test_bench 1.0.1.0 → 1.2.0.2
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.
- checksums.yaml +4 -4
- data/lib/test_bench.rb +12 -10
- data/lib/test_bench/cli.rb +2 -2
- data/lib/test_bench/cli/parse_arguments.rb +50 -37
- data/lib/test_bench/controls.rb +8 -2
- data/lib/test_bench/controls/error.rb +8 -8
- data/lib/test_bench/controls/output/batch_data.rb +52 -0
- data/lib/test_bench/controls/output/detail_setting.rb +29 -0
- data/lib/test_bench/controls/output/exercise.rb +7 -0
- data/lib/test_bench/controls/output/log_level.rb +7 -0
- data/lib/test_bench/controls/output/newline_character.rb +6 -1
- data/lib/test_bench/controls/output/summary/error.rb +5 -21
- data/lib/test_bench/controls/output/summary/session.rb +20 -0
- data/lib/test_bench/controls/pattern.rb +6 -2
- data/lib/test_bench/controls/time.rb +30 -2
- data/lib/test_bench/deactivation_variants.rb +0 -10
- data/lib/test_bench/fixtures.rb +3 -1
- data/lib/test_bench/output.rb +14 -2
- data/lib/test_bench/output/batch_data.rb +17 -0
- data/lib/test_bench/output/buffer.rb +114 -0
- data/lib/test_bench/output/log.rb +27 -0
- data/lib/test_bench/output/raw.rb +353 -0
- data/lib/test_bench/output/summary.rb +146 -0
- data/lib/test_bench/output/summary/session.rb +94 -0
- data/lib/test_bench/output/timer/substitute.rb +1 -1
- data/lib/test_bench/output/writer.rb +3 -3
- data/lib/test_bench/run.rb +9 -9
- data/lib/test_bench/test_bench.rb +23 -3
- metadata +18 -17
- data/lib/test_bench/controls/output/summary/run.rb +0 -59
- data/lib/test_bench/output/build.rb +0 -57
- data/lib/test_bench/output/levels/debug.rb +0 -229
- data/lib/test_bench/output/levels/failure.rb +0 -31
- data/lib/test_bench/output/levels/none.rb +0 -13
- data/lib/test_bench/output/levels/pass.rb +0 -286
- data/lib/test_bench/output/levels/summary.rb +0 -21
- data/lib/test_bench/output/summary/error.rb +0 -77
- data/lib/test_bench/output/summary/run.rb +0 -102
- data/lib/test_bench/output/summary/run/print.rb +0 -98
@@ -12,9 +12,19 @@ module TestBench
|
|
12
12
|
minutes = self.minutes
|
13
13
|
seconds = self.seconds + seconds_offset
|
14
14
|
|
15
|
-
|
15
|
+
if not RUBY_ENGINE == 'mruby'
|
16
|
+
tz_offset = self.tz_offset
|
16
17
|
|
17
|
-
|
18
|
+
final_argument = tz_offset
|
19
|
+
else
|
20
|
+
seconds, subseconds = seconds.divmod(1)
|
21
|
+
|
22
|
+
microseconds = subseconds * 1_000_000
|
23
|
+
|
24
|
+
final_argument = microseconds
|
25
|
+
end
|
26
|
+
|
27
|
+
::Time.new(year, month, day, hours, minutes, seconds, final_argument)
|
18
28
|
end
|
19
29
|
|
20
30
|
def self.year
|
@@ -55,6 +65,24 @@ module TestBench
|
|
55
65
|
"1.111s"
|
56
66
|
end
|
57
67
|
end
|
68
|
+
|
69
|
+
module PerSecond
|
70
|
+
def self.example
|
71
|
+
elapsed_time = Elapsed.example
|
72
|
+
|
73
|
+
Rational(ocurrences, elapsed_time)
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.ocurrences
|
77
|
+
1
|
78
|
+
end
|
79
|
+
|
80
|
+
module Text
|
81
|
+
def self.example
|
82
|
+
"0.9"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
58
86
|
end
|
59
87
|
end
|
60
88
|
end
|
@@ -1,21 +1,11 @@
|
|
1
1
|
module TestBench
|
2
2
|
module DeactivationVariants
|
3
3
|
def _context(title=nil, &block)
|
4
|
-
test_session.fail! if Defaults.fail_session
|
5
|
-
|
6
4
|
context(title)
|
7
5
|
end
|
8
6
|
|
9
7
|
def _test(title=nil, &block)
|
10
|
-
test_session.fail! if Defaults.fail_session
|
11
|
-
|
12
8
|
test(title)
|
13
9
|
end
|
14
|
-
|
15
|
-
module Defaults
|
16
|
-
def self.fail_session
|
17
|
-
Environment::Boolean.fetch('TEST_BENCH_FAIL_DEACTIVATED_TESTS', true)
|
18
|
-
end
|
19
|
-
end
|
20
10
|
end
|
21
11
|
end
|
data/lib/test_bench/fixtures.rb
CHANGED
data/lib/test_bench/output.rb
CHANGED
@@ -1,7 +1,19 @@
|
|
1
1
|
module TestBench
|
2
2
|
module Output
|
3
|
-
def self.build(**
|
4
|
-
|
3
|
+
def self.build(log_level: nil, writer: nil, device: nil, styling: nil, **buffer_output_args)
|
4
|
+
summary = Summary.build(writer: writer, device: device, styling: styling)
|
5
|
+
|
6
|
+
log_output = Log.build(level: log_level)
|
7
|
+
|
8
|
+
writer = summary.writer
|
9
|
+
|
10
|
+
buffer_output = Buffer.build(writer: writer, **buffer_output_args)
|
11
|
+
|
12
|
+
Fixture::Output::Multiple.build(
|
13
|
+
log_output,
|
14
|
+
buffer_output,
|
15
|
+
summary
|
16
|
+
)
|
5
17
|
end
|
6
18
|
|
7
19
|
Substitute = Fixture::Output::Substitute
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module TestBench
|
2
|
+
module Output
|
3
|
+
class Buffer < Fixture::Output::Capture
|
4
|
+
attr_accessor :writer
|
5
|
+
|
6
|
+
def raw_output
|
7
|
+
@raw_output ||= Raw.new
|
8
|
+
end
|
9
|
+
attr_writer :raw_output
|
10
|
+
|
11
|
+
def stack
|
12
|
+
@stack ||= []
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.build(verbose: nil, detail: nil, omit_backtrace_pattern: nil, reverse_backtraces: nil, writer: nil, device: nil, styling: nil)
|
16
|
+
instance = new
|
17
|
+
|
18
|
+
raw_output = Raw.configure(instance, verbose: verbose, detail: detail, omit_backtrace_pattern: omit_backtrace_pattern, reverse_backtraces: reverse_backtraces, writer: writer, device: device, styling: styling)
|
19
|
+
|
20
|
+
instance.writer = raw_output.writer
|
21
|
+
|
22
|
+
instance
|
23
|
+
end
|
24
|
+
|
25
|
+
def exit_context(*)
|
26
|
+
super
|
27
|
+
|
28
|
+
flush unless buffering?
|
29
|
+
end
|
30
|
+
|
31
|
+
def finish_test(*)
|
32
|
+
super
|
33
|
+
|
34
|
+
flush unless buffering?
|
35
|
+
end
|
36
|
+
|
37
|
+
def finish_fixture(*)
|
38
|
+
super
|
39
|
+
|
40
|
+
flush unless buffering?
|
41
|
+
end
|
42
|
+
|
43
|
+
def new_record(signal, data)
|
44
|
+
record = super
|
45
|
+
|
46
|
+
record.extend(Record)
|
47
|
+
|
48
|
+
case signal
|
49
|
+
when :enter_context, :start_test, :start_fixture
|
50
|
+
start_batch(record)
|
51
|
+
|
52
|
+
when :exit_context, :finish_test, :finish_fixture
|
53
|
+
result = record.data.last
|
54
|
+
|
55
|
+
finish_batch(record, result)
|
56
|
+
end
|
57
|
+
|
58
|
+
record
|
59
|
+
end
|
60
|
+
|
61
|
+
def start_batch(record)
|
62
|
+
record.start_batch(stack_depth)
|
63
|
+
|
64
|
+
stack.push(record)
|
65
|
+
end
|
66
|
+
|
67
|
+
def finish_batch(final_record, result)
|
68
|
+
first_record = stack.pop
|
69
|
+
|
70
|
+
batch_data = first_record.batch_data
|
71
|
+
batch_data.result = result
|
72
|
+
|
73
|
+
final_record.batch_data = first_record.batch_data
|
74
|
+
end
|
75
|
+
|
76
|
+
def flush
|
77
|
+
records.each do |record|
|
78
|
+
record.forward(raw_output)
|
79
|
+
end
|
80
|
+
|
81
|
+
records.clear
|
82
|
+
end
|
83
|
+
|
84
|
+
def buffering?
|
85
|
+
stack_depth.nonzero?
|
86
|
+
end
|
87
|
+
|
88
|
+
def stack_depth
|
89
|
+
stack.length
|
90
|
+
end
|
91
|
+
|
92
|
+
module Record
|
93
|
+
attr_accessor :batch_data
|
94
|
+
|
95
|
+
def forward(raw_output)
|
96
|
+
return super if batch_data.nil?
|
97
|
+
|
98
|
+
raw_output.public_send(signal, *data, batch_data: batch_data)
|
99
|
+
end
|
100
|
+
|
101
|
+
def start_batch(depth)
|
102
|
+
batch_data = Output::BatchData.new
|
103
|
+
batch_data.depth = depth
|
104
|
+
|
105
|
+
self.batch_data = batch_data
|
106
|
+
end
|
107
|
+
|
108
|
+
def finish_batch(result)
|
109
|
+
batch_data.result = result
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -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
|