test_bench 1.0.0.0 → 1.2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +33 -20
  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/deactivation_variants.rb +0 -10
  15. data/lib/test_bench/output.rb +14 -2
  16. data/lib/test_bench/output/batch_data.rb +17 -0
  17. data/lib/test_bench/output/buffer.rb +112 -0
  18. data/lib/test_bench/output/log.rb +27 -0
  19. data/lib/test_bench/output/raw.rb +353 -0
  20. data/lib/test_bench/output/summary.rb +146 -0
  21. data/lib/test_bench/output/summary/session.rb +94 -0
  22. data/lib/test_bench/output/writer.rb +2 -2
  23. data/lib/test_bench/run.rb +9 -9
  24. data/lib/test_bench/test_bench.rb +31 -3
  25. metadata +18 -17
  26. data/lib/test_bench/controls/output/summary/run.rb +0 -59
  27. data/lib/test_bench/output/build.rb +0 -57
  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 -274
  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