test_bench 1.0.1.1 → 1.1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/lib/test_bench.rb +9 -9
  3. data/lib/test_bench/cli.rb +2 -2
  4. data/lib/test_bench/cli/parse_arguments.rb +31 -18
  5. data/lib/test_bench/controls.rb +5 -1
  6. data/lib/test_bench/controls/output/batch_data.rb +52 -0
  7. data/lib/test_bench/controls/output/detail_setting.rb +29 -0
  8. data/lib/test_bench/controls/output/exercise.rb +7 -0
  9. data/lib/test_bench/controls/output/log_level.rb +7 -0
  10. data/lib/test_bench/controls/output/summary/error.rb +0 -16
  11. data/lib/test_bench/controls/output/summary/session.rb +20 -0
  12. data/lib/test_bench/controls/pattern.rb +6 -2
  13. data/lib/test_bench/controls/time.rb +18 -0
  14. data/lib/test_bench/fixture +1 -0
  15. data/lib/test_bench/fixture.rb +1 -0
  16. data/lib/test_bench/output.rb +14 -2
  17. data/lib/test_bench/output/batch_data.rb +17 -0
  18. data/lib/test_bench/output/buffer.rb +112 -0
  19. data/lib/test_bench/output/log.rb +27 -0
  20. data/lib/test_bench/output/raw.rb +353 -0
  21. data/lib/test_bench/output/summary.rb +146 -0
  22. data/lib/test_bench/output/summary/session.rb +94 -0
  23. data/lib/test_bench/output/writer.rb +2 -2
  24. data/lib/test_bench/run.rb +7 -7
  25. metadata +15 -12
  26. data/lib/test_bench/controls/output/summary/run.rb +0 -59
  27. data/lib/test_bench/output/build.rb +0 -51
  28. data/lib/test_bench/output/levels/debug.rb +0 -229
  29. data/lib/test_bench/output/levels/failure.rb +0 -31
  30. data/lib/test_bench/output/levels/none.rb +0 -13
  31. data/lib/test_bench/output/levels/pass.rb +0 -286
  32. data/lib/test_bench/output/levels/summary.rb +0 -21
  33. data/lib/test_bench/output/summary/error.rb +0 -77
  34. data/lib/test_bench/output/summary/run.rb +0 -102
  35. data/lib/test_bench/output/summary/run/print.rb +0 -98
@@ -0,0 +1,27 @@
1
+ module TestBench
2
+ module Output
3
+ module Log
4
+ def self.build(device=nil, level: nil)
5
+ level ||= Defaults.level
6
+
7
+ Fixture::Output::Log.build(device, level: level)
8
+ end
9
+
10
+ def self.default_level
11
+ :fatal
12
+ end
13
+
14
+ module Defaults
15
+ def self.level
16
+ level_text = ::ENV['TEST_BENCH_LOG_LEVEL']
17
+
18
+ if level_text.nil?
19
+ Log.default_level
20
+ else
21
+ level_text.to_sym
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,353 @@
1
+ module TestBench
2
+ module Output
3
+ class Raw
4
+ Error = Class.new(RuntimeError)
5
+
6
+ include Fixture::Output
7
+ include Writer::Dependency
8
+
9
+ include PrintError
10
+
11
+ def verbose
12
+ instance_variable_defined?(:@verbose) ?
13
+ @verbose :
14
+ @verbose = Defaults.verbose
15
+ end
16
+ attr_writer :verbose
17
+ alias_method :verbose?, :verbose
18
+
19
+ def detail_setting
20
+ @detail_setting ||= Defaults.detail
21
+ end
22
+ attr_writer :detail_setting
23
+
24
+ attr_accessor :current_batch
25
+
26
+ def batch_starting(batch_data)
27
+ if batch_data.depth.zero?
28
+ self.current_batch = batch_data
29
+ end
30
+ end
31
+
32
+ def batch_finished(batch_data)
33
+ if batch_data.depth.zero?
34
+ self.current_batch = nil
35
+ end
36
+ end
37
+
38
+ def previous_byte_offset
39
+ @previous_byte_offset ||= 0
40
+ end
41
+ attr_writer :previous_byte_offset
42
+
43
+ def configure(verbose: nil, detail: nil, omit_backtrace_pattern: nil, reverse_backtraces: nil, writer: nil, device: nil, styling: nil)
44
+ unless detail.nil?
45
+ self.class.assure_detail_setting(detail)
46
+ end
47
+
48
+ self.detail_setting = detail unless detail.nil?
49
+ self.verbose = verbose unless verbose.nil?
50
+
51
+ self.omit_backtrace_pattern = omit_backtrace_pattern unless omit_backtrace_pattern.nil?
52
+ self.reverse_backtraces = reverse_backtraces unless reverse_backtraces.nil?
53
+
54
+ Writer.configure(self, writer: writer, styling: styling, device: device)
55
+ end
56
+
57
+ def self.build(verbose: nil, detail: nil, omit_backtrace_pattern: nil, reverse_backtraces: nil, writer: nil, device: nil, styling: nil)
58
+ instance = new
59
+ instance.configure(verbose: verbose, detail: detail, omit_backtrace_pattern: omit_backtrace_pattern, reverse_backtraces: reverse_backtraces, writer: writer, device: device, styling: styling)
60
+ instance
61
+ end
62
+
63
+ def self.configure(receiver, attr_name: nil, **args)
64
+ attr_name ||= :raw_output
65
+
66
+ instance = build(**args)
67
+ receiver.public_send(:"#{attr_name}=", instance)
68
+ instance
69
+ end
70
+
71
+ def detail?(result=nil)
72
+ result ||= current_batch&.result
73
+
74
+ case detail_setting
75
+ when :failure
76
+ result != true
77
+ when :on
78
+ true
79
+ when :off
80
+ false
81
+ end
82
+ end
83
+
84
+ def enter_context(title, batch_data: nil)
85
+ batch_starting(batch_data) unless batch_data.nil?
86
+
87
+ return if title.nil?
88
+
89
+ writer
90
+ .indent
91
+ .escape_code(:green)
92
+ .text(title)
93
+ .escape_code(:reset_fg)
94
+ .newline
95
+
96
+ writer.increase_indentation
97
+ end
98
+
99
+ def exit_context(title, result, batch_data: nil)
100
+ return if title.nil?
101
+
102
+ writer.decrease_indentation
103
+
104
+ if verbose?
105
+ text = "Finished context #{title.inspect} (Result: #{result_text(result)})"
106
+
107
+ color = result ? :green : :red
108
+
109
+ writer
110
+ .indent
111
+ .escape_code(:faint).escape_code(:italic).escape_code(color)
112
+ .text(text)
113
+ .escape_code(:reset_fg).escape_code(:reset_italic).escape_code(:reset_intensity)
114
+ .newline
115
+ end
116
+
117
+ if writer.indentation_depth.zero?
118
+ writer.newline
119
+ end
120
+
121
+ ensure
122
+ batch_finished(batch_data) unless batch_data.nil?
123
+ end
124
+
125
+ def skip_context(title)
126
+ return if title.nil?
127
+
128
+ writer
129
+ .indent
130
+ .escape_code(:yellow)
131
+ .text(title)
132
+ .escape_code(:reset_fg)
133
+ .newline
134
+ end
135
+
136
+ def start_test(title, batch_data: nil)
137
+ batch_starting(batch_data) unless batch_data.nil?
138
+
139
+ batch_data = nil if verbose
140
+
141
+ if batch_data&.passed? && title.nil?
142
+ return
143
+ end
144
+
145
+ if batch_data.nil?
146
+ if title.nil?
147
+ text = "Starting test"
148
+ else
149
+ text = "Starting test #{title.inspect}"
150
+ end
151
+
152
+ writer
153
+ .indent
154
+ .escape_code(:faint)
155
+ .escape_code(:italic)
156
+ .escape_code(:blue)
157
+ .text(text)
158
+ .escape_code(:reset_fg)
159
+ .escape_code(:reset_italic)
160
+ .escape_code(:reset_intensity)
161
+ .newline
162
+
163
+ else
164
+ result = batch_data.result
165
+
166
+ print_test_result(title, result)
167
+ end
168
+
169
+ writer.increase_indentation
170
+ end
171
+
172
+ def finish_test(title, result, batch_data: nil)
173
+ batch_data = nil if verbose?
174
+
175
+ if batch_data&.passed? && title.nil?
176
+ return
177
+ end
178
+
179
+ writer.decrease_indentation
180
+
181
+ if batch_data.nil?
182
+ print_test_result(title, result)
183
+ end
184
+
185
+ ensure
186
+ batch_finished(batch_data) unless batch_data.nil?
187
+ end
188
+
189
+ def print_test_result(title, result)
190
+ title ||= default_test_title
191
+
192
+ if writer.styling?
193
+ text = title
194
+ elsif result
195
+ text = title
196
+ else
197
+ text = "#{title} (failed)"
198
+ end
199
+
200
+ color = result ? :green : :red
201
+
202
+ writer
203
+ .indent
204
+ .escape_code(color)
205
+ .text(text)
206
+ .escape_code(:reset_fg)
207
+ .newline
208
+ end
209
+
210
+ def skip_test(title)
211
+ title ||= default_test_title
212
+
213
+ if writer.styling?
214
+ text = title
215
+ else
216
+ text = "#{title} (skipped)"
217
+ end
218
+
219
+ writer
220
+ .indent
221
+ .escape_code(:yellow)
222
+ .text(text)
223
+ .escape_code(:reset_fg)
224
+ .newline
225
+ end
226
+
227
+ def start_fixture(fixture, batch_data: nil)
228
+ batch_starting(batch_data) unless batch_data.nil?
229
+
230
+ return unless verbose?
231
+
232
+ fixture_class = fixture.class.inspect
233
+
234
+ text = "Starting fixture (Fixture: #{fixture_class})"
235
+
236
+ writer
237
+ .indent
238
+ .escape_code(:blue)
239
+ .text(text)
240
+ .escape_code(:reset_fg)
241
+ .newline
242
+
243
+ writer.increase_indentation
244
+ end
245
+
246
+ def finish_fixture(fixture, result, batch_data: nil)
247
+ return unless verbose?
248
+
249
+ fixture_class = fixture.class.inspect
250
+
251
+ text = "Finished fixture (Fixture: #{fixture_class}, Result: #{result_text(result)})"
252
+
253
+ writer.decrease_indentation
254
+
255
+ writer
256
+ .indent
257
+ .escape_code(:magenta)
258
+ .text(text)
259
+ .escape_code(:reset_fg)
260
+ .newline
261
+
262
+ ensure
263
+ batch_finished(batch_data) unless batch_data.nil?
264
+ end
265
+
266
+ def error(error)
267
+ print_error(error)
268
+ end
269
+
270
+ def comment(text)
271
+ writer
272
+ .indent
273
+ .text(text)
274
+ .newline
275
+ end
276
+
277
+ def detail(text)
278
+ return unless verbose? || detail?
279
+
280
+ if verbose? && !detail?
281
+ text = "(detail omitted: #{text})"
282
+ end
283
+
284
+ writer
285
+ .indent
286
+ .text(text)
287
+ .newline
288
+ end
289
+
290
+ def enter_file(path)
291
+ text = "Running #{path}"
292
+
293
+ writer.text(text).newline
294
+
295
+ self.previous_byte_offset = writer.byte_offset
296
+ end
297
+
298
+ def exit_file(path, result)
299
+ unless writer.byte_offset > previous_byte_offset
300
+ writer
301
+ .escape_code(:faint)
302
+ .text("(Nothing written)")
303
+ .escape_code(:reset_intensity)
304
+ .newline
305
+
306
+ writer.newline
307
+ end
308
+ end
309
+
310
+ def result_text(result)
311
+ result ? 'pass' : 'failure'
312
+ end
313
+
314
+ def default_test_title
315
+ 'Test'
316
+ end
317
+
318
+ def self.assure_detail_setting(detail_setting)
319
+ unless detail_settings.include?(detail_setting)
320
+ raise Error, "Invalid detail setting #{detail_setting.inspect} (Valid values: #{detail_settings.map(&:inspect).join(', ')})"
321
+ end
322
+ end
323
+
324
+ def self.detail_settings
325
+ [
326
+ :failure,
327
+ :on,
328
+ :off
329
+ ]
330
+ end
331
+
332
+ def self.default_detail_setting
333
+ detail_settings.fetch(0)
334
+ end
335
+
336
+ module Defaults
337
+ def self.verbose
338
+ Environment::Boolean.fetch('TEST_BENCH_VERBOSE', false)
339
+ end
340
+
341
+ def self.detail
342
+ detail = ::ENV['TEST_BENCH_DETAIL']
343
+
344
+ if detail.nil?
345
+ Raw.default_detail_setting
346
+ else
347
+ detail.to_sym
348
+ end
349
+ end
350
+ end
351
+ end
352
+ end
353
+ end
@@ -0,0 +1,146 @@
1
+ module TestBench
2
+ module Output
3
+ class Summary
4
+ include Fixture::Output
5
+
6
+ include Writer::Dependency
7
+
8
+ def file_count
9
+ @file_count ||= 0
10
+ end
11
+ attr_writer :file_count
12
+
13
+ def test_count
14
+ @test_count ||= 0
15
+ end
16
+ attr_writer :test_count
17
+
18
+ def pass_count
19
+ @pass_count ||= 0
20
+ end
21
+ attr_writer :pass_count
22
+
23
+ def skip_count
24
+ @skip_count ||= 0
25
+ end
26
+ attr_writer :skip_count
27
+
28
+ def failure_count
29
+ @failure_count ||= 0
30
+ end
31
+ attr_writer :failure_count
32
+
33
+ def error_count
34
+ @error_count ||= 0
35
+ end
36
+ attr_writer :error_count
37
+
38
+ def elapsed_time
39
+ @elapsed_time ||= 0
40
+ end
41
+ attr_writer :elapsed_time
42
+
43
+ def timer
44
+ @timer ||= Timer::Substitute.build
45
+ end
46
+ attr_writer :timer
47
+
48
+ def errors_by_file
49
+ @errors_by_file ||= Hash.new do |hash, key|
50
+ hash[key] = []
51
+ end
52
+ end
53
+ attr_writer :errors_by_file
54
+
55
+ attr_accessor :current_file
56
+
57
+ def configure(writer: nil, device: nil, styling: nil)
58
+ Writer.configure(self, writer: writer, device: device, styling: styling)
59
+ Timer.configure(self)
60
+ end
61
+
62
+ def self.build(writer: nil, device: nil, styling: nil)
63
+ instance = new
64
+ instance.configure(writer: writer, device: device, styling: styling)
65
+ instance
66
+ end
67
+
68
+ def enter_file(file)
69
+ timer.start
70
+
71
+ self.current_file = file
72
+ end
73
+
74
+ def exit_file(_, _)
75
+ elapsed_time = timer.stop
76
+
77
+ self.elapsed_time += elapsed_time
78
+
79
+ self.file_count += 1
80
+ end
81
+
82
+ def finish_test(_, result)
83
+ self.test_count += 1
84
+
85
+ if result
86
+ self.pass_count += 1
87
+ else
88
+ self.failure_count += 1
89
+ end
90
+ end
91
+
92
+ def skip_test(_)
93
+ self.skip_count += 1
94
+ end
95
+
96
+ def error(error)
97
+ errors_by_file[current_file] << error
98
+
99
+ self.error_count += 1
100
+ end
101
+
102
+ def finish(_)
103
+ error_summary
104
+
105
+ session_summary
106
+ end
107
+
108
+ def session_summary
109
+ Session.(file_count: file_count, test_count: test_count, pass_count: pass_count, skip_count: skip_count, failure_count: failure_count, error_count: error_count, elapsed_time: elapsed_time, writer: writer)
110
+ end
111
+
112
+ def error_summary
113
+ return if errors_by_file.empty?
114
+
115
+ writer
116
+ .escape_code(:bold)
117
+ .escape_code(:red)
118
+ .text('Error Summary:')
119
+ .escape_code(:reset_intensity)
120
+ .escape_code(:reset_fg)
121
+ .newline
122
+
123
+ errors_by_file.each do |file, errors|
124
+ error_count = errors.count
125
+
126
+ writer
127
+ .text(error_count.to_s.rjust(4, ' '))
128
+ .text(": #{file}")
129
+ .newline
130
+
131
+ errors.each do |error|
132
+ writer
133
+ .text(' ')
134
+ .escape_code(:red)
135
+
136
+ PrintError.error_message(error, writer: writer)
137
+
138
+ writer.escape_code(:reset_fg)
139
+ end
140
+ end
141
+
142
+ writer.newline
143
+ end
144
+ end
145
+ end
146
+ end