Class: CC::CLI::Test
Constant Summary
collapse
- ARGUMENT_LIST =
"<engine_name>".freeze
- SHORT_HELP =
"Test an engine.".freeze
- HELP =
"Validate that an engine is behaving correctly.\n" \
"\n"\
" <engine_name> Engine to test".freeze
Constants inherited
from Command
Command::CODECLIMATE_YAML, Command::NAMESPACE
Instance Method Summary
collapse
Methods inherited from Command
[], abstract!, abstract?, all, command_name, #execute, help, inherited, #initialize, #require_codeclimate_yml, short_help, synopsis
Methods included from Output
#colorize, #fatal, #rainbow, #say, #success, #terminal, #warn
Instance Method Details
#announce_fail(marker, actual_issues) ⇒ Object
154
155
156
157
158
159
160
161
|
# File 'lib/cc/cli/test.rb', line 154
def announce_fail(marker, actual_issues)
say colorize(format("FAIL %3d: %s", marker.line, marker.line_text), :red)
say colorize("Expected:", :yellow)
say colorize(JSON.pretty_generate(marker.issue), :yellow)
say "\n"
say colorize("Actual:", :yellow)
say colorize(JSON.pretty_generate(actual_issues), :yellow)
end
|
#announce_pass(marker) ⇒ Object
150
151
152
|
# File 'lib/cc/cli/test.rb', line 150
def announce_pass(marker)
say format("PASS %3d: %s", marker.line, marker.line_text)
end
|
#capture_stdout ⇒ Object
Stolen from ActiveSupport (where it was deprecated)
248
249
250
251
252
253
254
255
256
257
258
259
260
261
|
# File 'lib/cc/cli/test.rb', line 248
def capture_stdout
captured_stream = Tempfile.new("stdout")
origin_stream = $stdout.dup
$stdout.reopen(captured_stream)
yield
$stdout.rewind
return captured_stream.read
ensure
captured_stream.close
captured_stream.unlink
$stdout.reopen(origin_stream)
end
|
#codeclimate_analyze(relative_path) ⇒ Object
187
188
189
190
191
192
193
194
195
196
|
# File 'lib/cc/cli/test.rb', line 187
def codeclimate_analyze(relative_path)
codeclimate_path = File.expand_path(File.join(File.dirname(__FILE__), "../../../bin/codeclimate"))
system(
codeclimate_path, "analyze",
"--engine", @engine_name,
"-f", "json",
relative_path
)
end
|
#compare_issues(actual_issues, markers) ⇒ Object
122
123
124
125
126
127
128
|
# File 'lib/cc/cli/test.rb', line 122
def compare_issues(actual_issues, markers)
markers.each do |marker|
validate_issue(marker, actual_issues)
end
validate_unexpected_issues(actual_issues)
end
|
#engine_image ⇒ Object
243
244
245
|
# File 'lib/cc/cli/test.rb', line 243
def engine_image
engine_registry[@engine_name]["channels"]["stable"]
end
|
#engine_spec ⇒ Object
239
240
241
|
# File 'lib/cc/cli/test.rb', line 239
def engine_spec
@engine_spec ||= JSON.parse(`docker run --rm #{engine_image} cat /engine.json`)
end
|
#fuzzy_match(expected, actual) ⇒ Object
173
174
175
176
177
|
# File 'lib/cc/cli/test.rb', line 173
def fuzzy_match(expected, actual)
expected.all? do |key, value|
actual[key] == value
end
end
|
#issues_in(test_directory) ⇒ Object
179
180
181
182
183
184
185
|
# File 'lib/cc/cli/test.rb', line 179
def issues_in(test_directory)
issue_docs = capture_stdout do
codeclimate_analyze(test_directory)
end
JSON.parse(issue_docs)
end
|
#locate_match(actual_issues, marker) ⇒ Object
140
141
142
143
144
145
146
147
148
|
# File 'lib/cc/cli/test.rb', line 140
def locate_match(actual_issues, marker)
actual_issues.each_with_index do |actual, index|
if fuzzy_match(marker.issue, actual)
return index
end
end
nil
end
|
#markers_in(test_directory) ⇒ Object
206
207
208
209
210
211
212
213
214
215
216
217
218
219
|
# File 'lib/cc/cli/test.rb', line 206
def markers_in(test_directory)
[].tap do |markers|
Dir[File.join(test_directory, "**/*")].each do |file|
next unless File.file?(file)
lines = File.readlines(file)
lines.each_with_index do |line, index|
if line =~ /\[issue\].*/
markers << Marker.from_text(@engine_name, file, index + 1, line)
end
end
end
end
end
|
#null_container_id ⇒ Object
225
226
227
228
229
|
# File 'lib/cc/cli/test.rb', line 225
def null_container_id
@null_container_id = `docker run -d #{engine_image} false`.chomp
end
|
#prepare_working_dir ⇒ Object
198
199
200
201
202
203
204
|
# File 'lib/cc/cli/test.rb', line 198
def prepare_working_dir
`git init`
File.open(".codeclimate.yml", "w") do |config|
config.write("engines:\n #{@engine_name}:\n enabled: true")
end
end
|
#process_directory(test_directory) ⇒ Object
115
116
117
118
119
120
|
# File 'lib/cc/cli/test.rb', line 115
def process_directory(test_directory)
markers = markers_in(test_directory)
actual_issues = issues_in(test_directory)
compare_issues(actual_issues, markers)
end
|
#remove_null_container ⇒ Object
231
232
233
|
# File 'lib/cc/cli/test.rb', line 231
def remove_null_container
`docker rm -f #{null_container_id}` if null_container_id
end
|
#run ⇒ Object
78
79
80
81
82
83
84
85
86
|
# File 'lib/cc/cli/test.rb', line 78
def run
@engine_name = @args.first
if @engine_name.blank?
fatal "Usage: codeclimate test #{rainbow.wrap("engine_name").underline}"
end
test_engine
end
|
#run_tests ⇒ Object
108
109
110
111
112
113
|
# File 'lib/cc/cli/test.rb', line 108
def run_tests
Dir["*"].each do |file|
next unless File.directory?(file)
process_directory(file)
end
end
|
#test_engine ⇒ Object
88
89
90
91
92
93
94
95
96
|
# File 'lib/cc/cli/test.rb', line 88
def test_engine
within_tempdir do
prepare_working_dir
unpack_tests
run_tests
end
ensure
remove_null_container
end
|
#test_paths ⇒ Object
235
236
237
|
# File 'lib/cc/cli/test.rb', line 235
def test_paths
Array.wrap(engine_spec["test_paths"])
end
|
#unpack(path) ⇒ Object
221
222
223
|
# File 'lib/cc/cli/test.rb', line 221
def unpack(path)
system("docker cp #{null_container_id}:#{path} .")
end
|
#unpack_tests ⇒ Object
102
103
104
105
106
|
# File 'lib/cc/cli/test.rb', line 102
def unpack_tests
test_paths.each do |test_path|
unpack(test_path)
end
end
|
#validate_issue(marker, actual_issues) ⇒ Object
130
131
132
133
134
135
136
137
138
|
# File 'lib/cc/cli/test.rb', line 130
def validate_issue(marker, actual_issues)
if (index = locate_match(actual_issues, marker))
announce_pass(marker)
actual_issues.delete_at(index)
else
announce_fail(marker, actual_issues)
fatal "Expected issue not found."
end
end
|
#validate_unexpected_issues(actual_issues) ⇒ Object
163
164
165
166
167
168
169
170
171
|
# File 'lib/cc/cli/test.rb', line 163
def validate_unexpected_issues(actual_issues)
if actual_issues.any?
say colorize("Actuals not empty after matching.", :red)
say "\n"
say colorize("#{actual_issues.size} remaining:", :yellow)
say colorize(JSON.pretty_generate(actual_issues), :yellow)
fatal "Unexpected issue found."
end
end
|
#within_tempdir(&block) ⇒ Object
98
99
100
|
# File 'lib/cc/cli/test.rb', line 98
def within_tempdir(&block)
Dir.mktmpdir { |tmp| Dir.chdir(tmp, &block) }
end
|