test_bench-output 2.1.1.2 → 3.0.0.0.pre.1
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/output/comment_style.rb +61 -0
- data/lib/test_bench/output/controls/comment_style.rb +21 -0
- data/lib/test_bench/output/controls/event.rb +2 -2
- data/lib/test_bench/output/controls/events/aborted.rb +9 -0
- data/lib/test_bench/output/controls/events/commented.rb +21 -0
- data/lib/test_bench/output/controls/events/context_finished.rb +9 -0
- data/lib/test_bench/output/controls/events/context_started.rb +9 -0
- data/lib/test_bench/output/controls/events/detailed.rb +21 -0
- data/lib/test_bench/output/controls/events/failed.rb +9 -0
- data/lib/test_bench/output/controls/events/file_executed.rb +9 -0
- data/lib/test_bench/output/controls/events/file_not_found.rb +9 -0
- data/lib/test_bench/output/controls/events/file_queued.rb +9 -0
- data/lib/test_bench/output/controls/events/skipped.rb +9 -0
- data/lib/test_bench/output/controls/events/test_finished.rb +9 -0
- data/lib/test_bench/output/controls/events/test_started.rb +9 -0
- data/lib/test_bench/output/controls/random.rb +2 -2
- data/lib/test_bench/output/controls/session.rb +17 -0
- data/lib/test_bench/output/controls/status.rb +7 -0
- data/lib/test_bench/output/controls/style.rb +14 -6
- data/lib/test_bench/output/controls/text.rb +16 -4
- data/lib/test_bench/output/controls.rb +21 -5
- data/lib/test_bench/output/detail_policy.rb +44 -0
- data/lib/test_bench/output/device/null.rb +3 -3
- data/lib/test_bench/output/device/substitute.rb +19 -33
- data/lib/test_bench/output/device.rb +73 -0
- data/lib/test_bench/output/get.rb +30 -0
- data/lib/test_bench/output/level.rb +51 -0
- data/lib/test_bench/output/output.rb +540 -36
- data/lib/test_bench/output/writer/style.rb +5 -3
- data/lib/test_bench/output/writer/substitute.rb +10 -23
- data/lib/test_bench/output/writer.rb +54 -147
- data/lib/test_bench/output.rb +10 -4
- metadata +49 -21
- data/lib/test_bench/output/controls/data.rb +0 -49
- data/lib/test_bench/output/controls/device.rb +0 -27
- data/lib/test_bench/output/controls/output.rb +0 -34
- data/lib/test_bench/output/controls/styling.rb +0 -27
- data/lib/test_bench/output/digest.rb +0 -113
- data/lib/test_bench/output/writer/buffer.rb +0 -57
- data/lib/test_bench/output/writer/defaults.rb +0 -11
@@ -0,0 +1,51 @@
|
|
1
|
+
module TestBench
|
2
|
+
class Output
|
3
|
+
module Level
|
4
|
+
Error = Class.new(RuntimeError)
|
5
|
+
|
6
|
+
def self.abort
|
7
|
+
:abort
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.failure
|
11
|
+
:failure
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.not_passing
|
15
|
+
:not_passing
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.all
|
19
|
+
:all
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.output?(output_level, result=nil)
|
23
|
+
result ||= Session::Result.none
|
24
|
+
|
25
|
+
case output_level
|
26
|
+
when abort
|
27
|
+
result == Session::Result.aborted
|
28
|
+
|
29
|
+
when failure
|
30
|
+
[
|
31
|
+
Session::Result.aborted,
|
32
|
+
Session::Result.failed
|
33
|
+
].include?(result)
|
34
|
+
|
35
|
+
when not_passing
|
36
|
+
result != Session::Result.passed
|
37
|
+
|
38
|
+
when all
|
39
|
+
true
|
40
|
+
|
41
|
+
else
|
42
|
+
raise Error, "Incorrect output level: #{output_level.inspect}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.assure_output_level(output_level)
|
47
|
+
output?(output_level)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,66 +1,570 @@
|
|
1
1
|
module TestBench
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
include Telemetry::Sink::Handler
|
2
|
+
class Output
|
3
|
+
include Telemetry::Sink::Handler
|
4
|
+
include ImportConstants
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
end
|
6
|
+
import_constants Session::Events
|
7
|
+
|
8
|
+
Result = Session::Result
|
12
9
|
|
13
10
|
def writer
|
14
11
|
@writer ||= Writer::Substitute.build
|
15
12
|
end
|
16
13
|
attr_writer :writer
|
17
14
|
|
18
|
-
def
|
19
|
-
|
15
|
+
def detail_policy
|
16
|
+
@detail_policy ||= DetailPolicy.on
|
17
|
+
end
|
18
|
+
attr_writer :detail_policy
|
19
|
+
|
20
|
+
def output_level
|
21
|
+
@output_level ||= Level.all
|
22
|
+
end
|
23
|
+
attr_writer :output_level
|
24
|
+
|
25
|
+
def branches
|
26
|
+
@branches ||= []
|
27
|
+
end
|
28
|
+
attr_writer :branches
|
29
|
+
|
30
|
+
def status
|
31
|
+
@status ||= Session::Status.initial
|
32
|
+
end
|
33
|
+
attr_writer :status
|
34
|
+
|
35
|
+
def self.build(styling: nil, device: nil)
|
36
|
+
instance = new
|
37
|
+
|
38
|
+
instance.detail_policy = Defaults.detail_policy
|
39
|
+
instance.output_level = Defaults.output_level
|
40
|
+
|
41
|
+
Writer.configure(instance, styling:, device:)
|
42
|
+
|
43
|
+
instance
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.register_telemetry_sink(session=nil, styling: nil, device: nil)
|
47
|
+
session ||= Session.instance
|
48
|
+
|
49
|
+
output = build(styling:, device:)
|
50
|
+
|
51
|
+
session.register_telemetry_sink(output)
|
52
|
+
|
53
|
+
output
|
54
|
+
end
|
55
|
+
|
56
|
+
handle Failed do |failed|
|
57
|
+
pend(failed)
|
58
|
+
end
|
59
|
+
|
60
|
+
handle Aborted do |aborted|
|
61
|
+
pend(aborted)
|
62
|
+
end
|
63
|
+
|
64
|
+
handle Skipped do |skipped|
|
65
|
+
pend(skipped)
|
66
|
+
end
|
67
|
+
|
68
|
+
handle Commented do |commented|
|
69
|
+
pend(commented)
|
70
|
+
end
|
71
|
+
|
72
|
+
handle Detailed do |detailed|
|
73
|
+
pend(detailed)
|
74
|
+
end
|
75
|
+
|
76
|
+
handle TestStarted do |test_started|
|
77
|
+
branch(test_started)
|
78
|
+
end
|
79
|
+
|
80
|
+
handle TestFinished do |test_finished|
|
81
|
+
merge(test_finished)
|
82
|
+
end
|
83
|
+
|
84
|
+
handle ContextStarted do |context_started|
|
85
|
+
branch(context_started)
|
86
|
+
end
|
87
|
+
|
88
|
+
handle ContextFinished do |context_finished|
|
89
|
+
merge(context_finished)
|
90
|
+
end
|
91
|
+
|
92
|
+
handle FileQueued do |file_queued|
|
93
|
+
branch(file_queued)
|
94
|
+
end
|
95
|
+
|
96
|
+
handle FileExecuted do |file_executed|
|
97
|
+
merge(file_executed)
|
98
|
+
end
|
99
|
+
|
100
|
+
handle FileNotFound do |file_not_found|
|
101
|
+
pend(file_not_found)
|
102
|
+
end
|
103
|
+
|
104
|
+
def merge(event)
|
105
|
+
pend(event)
|
106
|
+
|
107
|
+
merge_branch = branches.pop
|
108
|
+
|
109
|
+
if root?
|
110
|
+
if not Level.output?(output_level, merge_branch.status.result)
|
111
|
+
return
|
112
|
+
end
|
113
|
+
|
114
|
+
merge_branch.each do |event, status|
|
115
|
+
resolve(event, status)
|
116
|
+
end
|
117
|
+
else
|
118
|
+
current_branch.merge(merge_branch)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def branch(event)
|
123
|
+
branch = Branch.new
|
124
|
+
|
125
|
+
branches << branch
|
126
|
+
|
127
|
+
pend(event)
|
128
|
+
|
129
|
+
branch
|
20
130
|
end
|
21
131
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
132
|
+
def pend(event)
|
133
|
+
status.update(event)
|
134
|
+
|
135
|
+
if root?
|
136
|
+
resolve(event, status)
|
137
|
+
else
|
138
|
+
current_branch.pend(event)
|
27
139
|
end
|
28
140
|
end
|
29
141
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
142
|
+
def current_branch
|
143
|
+
branches.last
|
144
|
+
end
|
145
|
+
|
146
|
+
def root?
|
147
|
+
current_branch.nil?
|
148
|
+
end
|
149
|
+
|
150
|
+
def resolve(event, status)
|
151
|
+
case event
|
152
|
+
in Failed => failed
|
153
|
+
resolve_failed(failed)
|
154
|
+
in Aborted => aborted
|
155
|
+
resolve_aborted(aborted)
|
156
|
+
in Skipped => skipped
|
157
|
+
resolve_skipped(skipped)
|
158
|
+
in Commented => commented
|
159
|
+
resolve_commented(commented)
|
160
|
+
in Detailed => detailed
|
161
|
+
resolve_detailed(detailed, status)
|
162
|
+
in TestStarted => test_started
|
163
|
+
resolve_test_started(test_started, status)
|
164
|
+
in TestFinished => test_finished
|
165
|
+
resolve_test_finished(test_finished)
|
166
|
+
in ContextStarted => context_started
|
167
|
+
resolve_context_started(context_started, status)
|
168
|
+
in ContextFinished => context_finished
|
169
|
+
resolve_context_finished(context_finished, status)
|
170
|
+
in FileQueued => file_queued
|
171
|
+
resolve_file_queued(file_queued, status)
|
172
|
+
in FileExecuted => file_executed
|
173
|
+
resolve_file_executed(file_executed)
|
174
|
+
in FileNotFound => file_not_found
|
175
|
+
resolve_file_not_found(file_not_found)
|
176
|
+
else
|
35
177
|
end
|
36
|
-
alias :register :register_telemetry
|
37
178
|
end
|
38
179
|
|
39
|
-
|
40
|
-
|
41
|
-
attr_name ||= :output
|
180
|
+
def resolve_failed(failed)
|
181
|
+
message = failed.message
|
42
182
|
|
43
|
-
|
44
|
-
|
183
|
+
writer.
|
184
|
+
indent.
|
185
|
+
style(:red).
|
186
|
+
puts(message)
|
187
|
+
end
|
188
|
+
|
189
|
+
def resolve_aborted(aborted)
|
190
|
+
message = aborted.message
|
191
|
+
|
192
|
+
writer.
|
193
|
+
indent.
|
194
|
+
style(:bold, :red).
|
195
|
+
print("Aborted: ").
|
196
|
+
style(:reset_intensity).
|
197
|
+
puts(message)
|
198
|
+
end
|
199
|
+
|
200
|
+
def resolve_skipped(skipped)
|
201
|
+
message = skipped.message
|
202
|
+
|
203
|
+
writer.
|
204
|
+
indent.
|
205
|
+
style(:yellow)
|
206
|
+
|
207
|
+
if not message.nil?
|
208
|
+
writer.print(message)
|
209
|
+
|
210
|
+
if not writer.styling?
|
211
|
+
writer.print(" (skipped)")
|
212
|
+
end
|
213
|
+
else
|
214
|
+
writer.print("Skipped")
|
45
215
|
end
|
216
|
+
|
217
|
+
writer.puts
|
46
218
|
end
|
47
219
|
|
48
|
-
|
49
|
-
|
50
|
-
|
220
|
+
def resolve_commented(commented)
|
221
|
+
text = commented.text
|
222
|
+
|
223
|
+
disposition = commented.disposition
|
224
|
+
style = CommentStyle.fetch(disposition)
|
225
|
+
|
226
|
+
case style
|
227
|
+
when CommentStyle.detect
|
228
|
+
if text.end_with?("\n")
|
229
|
+
style = CommentStyle.block
|
230
|
+
else
|
231
|
+
style = CommentStyle.normal
|
232
|
+
end
|
233
|
+
|
234
|
+
when CommentStyle.raw
|
235
|
+
writer.
|
236
|
+
print(text).
|
237
|
+
print("\n")
|
238
|
+
|
239
|
+
return
|
240
|
+
end
|
241
|
+
|
242
|
+
if text.empty?
|
243
|
+
writer.
|
244
|
+
indent.
|
245
|
+
style(:faint, :italic)
|
246
|
+
|
247
|
+
if style == CommentStyle.heading
|
248
|
+
writer.puts('(no heading)')
|
249
|
+
|
250
|
+
if not writer.styling?
|
251
|
+
writer.
|
252
|
+
indent.
|
253
|
+
puts("- - -")
|
254
|
+
end
|
255
|
+
else
|
256
|
+
writer.puts('(empty)')
|
257
|
+
end
|
258
|
+
|
259
|
+
return
|
51
260
|
end
|
52
261
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
262
|
+
case style
|
263
|
+
when CommentStyle.normal
|
264
|
+
writer.
|
265
|
+
indent.
|
266
|
+
puts(text)
|
267
|
+
|
268
|
+
when CommentStyle.heading
|
269
|
+
writer.
|
270
|
+
indent.
|
271
|
+
style(:bold).
|
272
|
+
puts(text)
|
273
|
+
|
274
|
+
if not writer.styling?
|
275
|
+
writer.
|
276
|
+
indent.
|
277
|
+
puts("- - -")
|
278
|
+
end
|
279
|
+
|
280
|
+
when CommentStyle.block
|
281
|
+
text.each_line do |line|
|
282
|
+
writer.
|
283
|
+
indent.
|
284
|
+
style(:reverse_video)
|
285
|
+
|
286
|
+
if writer.styling?
|
287
|
+
writer.print(' ')
|
57
288
|
else
|
58
|
-
|
289
|
+
writer.print('>')
|
59
290
|
end
|
60
291
|
|
61
|
-
|
292
|
+
writer.
|
293
|
+
style(:reset_reverse_video).
|
294
|
+
print(' ').
|
295
|
+
puts(line)
|
296
|
+
end
|
297
|
+
|
298
|
+
when CommentStyle.line_number
|
299
|
+
lines = text.each_line
|
300
|
+
|
301
|
+
final_line_number_width = lines.count.to_s.length
|
302
|
+
marker_width = final_line_number_width + 2
|
303
|
+
|
304
|
+
lines.with_index(1) do |line, line_number|
|
305
|
+
line_marker = "#{line_number}.".ljust(marker_width)
|
306
|
+
|
307
|
+
writer.
|
308
|
+
indent.
|
309
|
+
style(:faint).
|
310
|
+
print(line_marker).
|
311
|
+
style(:reset_intensity).
|
312
|
+
puts(line)
|
62
313
|
end
|
63
314
|
end
|
64
315
|
end
|
316
|
+
|
317
|
+
def resolve_detailed(detailed, status)
|
318
|
+
result = status.result
|
319
|
+
|
320
|
+
print_detail = DetailPolicy.detail?(detail_policy, result)
|
321
|
+
|
322
|
+
if print_detail
|
323
|
+
resolve_commented(detailed)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
def resolve_test_started(test_started, status)
|
328
|
+
title = test_started.title
|
329
|
+
|
330
|
+
if title.nil?
|
331
|
+
return
|
332
|
+
end
|
333
|
+
|
334
|
+
writer.indent
|
335
|
+
|
336
|
+
result = status.result
|
337
|
+
|
338
|
+
case result
|
339
|
+
when Result.passed
|
340
|
+
writer.style(:green)
|
341
|
+
when Result.failed, Result.aborted, Result.incomplete, Result.none
|
342
|
+
writer.style(:bold, :red)
|
343
|
+
end
|
344
|
+
|
345
|
+
writer.print(title)
|
346
|
+
|
347
|
+
if not writer.styling?
|
348
|
+
case result
|
349
|
+
when Result.aborted
|
350
|
+
writer.print(" (aborted)")
|
351
|
+
when Result.failed
|
352
|
+
writer.print(" (failed)")
|
353
|
+
when Result.incomplete, Result.none
|
354
|
+
writer.print(" (inconclusive)")
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
writer.puts
|
359
|
+
|
360
|
+
writer.increase_indentation
|
361
|
+
end
|
362
|
+
|
363
|
+
def resolve_test_finished(test_finished)
|
364
|
+
title = test_finished.title
|
365
|
+
|
366
|
+
if not title.nil?
|
367
|
+
writer.decrease_indentation
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
def resolve_context_started(context_started, status)
|
372
|
+
title = context_started.title
|
373
|
+
|
374
|
+
if title.nil?
|
375
|
+
return
|
376
|
+
end
|
377
|
+
|
378
|
+
writer.indent
|
379
|
+
|
380
|
+
result = status.result
|
381
|
+
|
382
|
+
case result
|
383
|
+
when Result.aborted
|
384
|
+
writer.style(:red)
|
385
|
+
when Result.passed, Result.failed, Result.incomplete
|
386
|
+
writer.style(:green)
|
387
|
+
end
|
388
|
+
|
389
|
+
writer.print(title)
|
390
|
+
|
391
|
+
if not writer.styling?
|
392
|
+
if result == Result.aborted
|
393
|
+
writer.print(" (aborted)")
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
writer.puts
|
398
|
+
|
399
|
+
writer.increase_indentation
|
400
|
+
end
|
401
|
+
|
402
|
+
def resolve_context_finished(context_finished, status)
|
403
|
+
title = context_finished.title
|
404
|
+
|
405
|
+
if title.nil?
|
406
|
+
return
|
407
|
+
end
|
408
|
+
|
409
|
+
writer.decrease_indentation
|
410
|
+
|
411
|
+
if not writer.indentation_depth.zero?
|
412
|
+
return
|
413
|
+
end
|
414
|
+
|
415
|
+
error_count = status.error_sequence
|
416
|
+
failure_count = status.failure_sequence
|
417
|
+
skip_count = status.skip_sequence
|
418
|
+
|
419
|
+
if error_count > 0 || failure_count > 0 || skip_count > 0
|
420
|
+
writer.puts
|
421
|
+
end
|
422
|
+
|
423
|
+
if not error_count.zero?
|
424
|
+
writer.
|
425
|
+
style(:red).
|
426
|
+
print("Errors: ").
|
427
|
+
style(:bold).
|
428
|
+
puts("#{status.error_sequence}")
|
429
|
+
end
|
430
|
+
|
431
|
+
if not failure_count.zero?
|
432
|
+
writer.
|
433
|
+
style(:red).
|
434
|
+
print("Failures: ").
|
435
|
+
style(:bold).
|
436
|
+
puts("#{status.failure_sequence}")
|
437
|
+
end
|
438
|
+
|
439
|
+
if not skip_count.zero?
|
440
|
+
writer.
|
441
|
+
style(:yellow).
|
442
|
+
print("Skipped: ").
|
443
|
+
style(:bold).
|
444
|
+
puts("#{status.skip_sequence}")
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
def resolve_file_queued(file_queued, status)
|
449
|
+
writer.indent
|
450
|
+
|
451
|
+
if status.result == Session::Result.aborted
|
452
|
+
writer.style(:bold, :red)
|
453
|
+
end
|
454
|
+
|
455
|
+
file = file_queued.file
|
456
|
+
writer.print("Running #{file}")
|
457
|
+
|
458
|
+
if !writer.styling? && status.result == Session::Result.aborted
|
459
|
+
writer.print(" (aborted)")
|
460
|
+
end
|
461
|
+
|
462
|
+
writer.puts
|
463
|
+
end
|
464
|
+
|
465
|
+
def resolve_file_executed(file_executed)
|
466
|
+
indented = writer.indentation_depth > 0
|
467
|
+
|
468
|
+
result = file_executed.result
|
469
|
+
|
470
|
+
if indented
|
471
|
+
file = file_executed.file
|
472
|
+
|
473
|
+
writer.
|
474
|
+
indent.
|
475
|
+
style(:italic).
|
476
|
+
print("Ran #{file}")
|
477
|
+
|
478
|
+
if result == Result.none
|
479
|
+
writer.
|
480
|
+
print(' ').
|
481
|
+
style(:faint).
|
482
|
+
print("(no tests)")
|
483
|
+
end
|
484
|
+
|
485
|
+
writer.puts
|
486
|
+
else
|
487
|
+
if result == Result.none
|
488
|
+
writer.
|
489
|
+
style(:faint, :italic).
|
490
|
+
puts("(no tests)")
|
491
|
+
end
|
492
|
+
|
493
|
+
writer.puts
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
497
|
+
def resolve_file_not_found(file_not_found)
|
498
|
+
file = file_not_found.file
|
499
|
+
|
500
|
+
writer.
|
501
|
+
style(:red).
|
502
|
+
print("File not found: ").
|
503
|
+
style(:bold).
|
504
|
+
puts(file).
|
505
|
+
puts
|
506
|
+
end
|
507
|
+
|
508
|
+
class Branch
|
509
|
+
def status
|
510
|
+
@status ||= Session::Status.initial
|
511
|
+
end
|
512
|
+
attr_writer :status
|
513
|
+
|
514
|
+
def entries
|
515
|
+
@entries ||= []
|
516
|
+
end
|
517
|
+
attr_writer :entries
|
518
|
+
|
519
|
+
def pend(event)
|
520
|
+
status.update(event)
|
521
|
+
|
522
|
+
entries << event
|
523
|
+
end
|
524
|
+
|
525
|
+
def merge(branch)
|
526
|
+
branch_status = branch.status
|
527
|
+
|
528
|
+
status.test_sequence += branch_status.test_sequence
|
529
|
+
status.failure_sequence += branch_status.failure_sequence
|
530
|
+
status.error_sequence += branch_status.error_sequence
|
531
|
+
status.skip_sequence += branch_status.skip_sequence
|
532
|
+
|
533
|
+
entries << branch
|
534
|
+
end
|
535
|
+
|
536
|
+
def each(&block)
|
537
|
+
entries.each do |entry|
|
538
|
+
case entry
|
539
|
+
in Telemetry::Event => event
|
540
|
+
block.(event, status)
|
541
|
+
in Branch => branch
|
542
|
+
branch.each(&block)
|
543
|
+
end
|
544
|
+
end
|
545
|
+
end
|
546
|
+
end
|
547
|
+
|
548
|
+
module Defaults
|
549
|
+
def self.detail_policy
|
550
|
+
env_var_value = ENV.fetch('TEST_BENCH_OUTPUT_DETAIL', 'failure')
|
551
|
+
|
552
|
+
detail_policy = env_var_value.to_sym
|
553
|
+
|
554
|
+
DetailPolicy.assure_policy(detail_policy)
|
555
|
+
|
556
|
+
detail_policy
|
557
|
+
end
|
558
|
+
|
559
|
+
def self.output_level
|
560
|
+
env_var_value = ENV.fetch('TEST_BENCH_OUTPUT_LEVEL', 'all')
|
561
|
+
|
562
|
+
output_level = env_var_value.gsub('-', '_').to_sym
|
563
|
+
|
564
|
+
Level.assure_output_level(output_level)
|
565
|
+
|
566
|
+
output_level
|
567
|
+
end
|
568
|
+
end
|
65
569
|
end
|
66
570
|
end
|
@@ -1,27 +1,29 @@
|
|
1
1
|
module TestBench
|
2
|
-
|
2
|
+
class Output
|
3
3
|
class Writer
|
4
4
|
module Style
|
5
5
|
Error = Class.new(RuntimeError)
|
6
6
|
|
7
7
|
def self.control_code(style)
|
8
8
|
control_codes.fetch(style) do
|
9
|
-
raise Error, "
|
9
|
+
raise Error, "Incorrect style: #{style.inspect}"
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
13
|
def self.control_codes
|
14
14
|
@sgr_codes ||= {
|
15
|
-
:reset => '
|
15
|
+
:reset => '',
|
16
16
|
|
17
17
|
:bold => '1',
|
18
18
|
:faint => '2',
|
19
19
|
:italic => '3',
|
20
20
|
:underline => '4',
|
21
|
+
:reverse_video => '7',
|
21
22
|
|
22
23
|
:reset_intensity => '22',
|
23
24
|
:reset_italic => '23',
|
24
25
|
:reset_underline => '24',
|
26
|
+
:reset_reverse_video => '27',
|
25
27
|
|
26
28
|
:black => '30',
|
27
29
|
:red => '31',
|