test_bench-bootstrap 2.1.0 → 3.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 (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/test_bench/bootstrap.rb +187 -77
  3. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b400c74d1b0dfc2f2ce3332d525109cb9a1643ddeba0f65e440eba9acd6b84a
4
- data.tar.gz: 45ee30ba63adf373048a53d40d2e956fef6fc1bbaf3392cce964bcd7d3136325
3
+ metadata.gz: b4e2e358c29830ece30c5a9516c4cf96fe2d6748cb1a3c88e9d3d05727c66f9a
4
+ data.tar.gz: d07c4e27d9c6440427ff716ff8fe6cf405940287417c5f0f69e90560d6c140da
5
5
  SHA512:
6
- metadata.gz: be4671d8025e1be20ebe53d926d5e3e1919a00c54f23f2743ad00df0cc3dcb7422651bb499fc43a7c4bae2be8eb281d48a4d2d25568d0bd0c9f3ecc474951e56
7
- data.tar.gz: c6bfab181eabcc5d608f17f688f3d7150b0d6cbae5c2604a36e6636a7cdd576f0a381953634fa5a9b13d544da6c358e64863d89bc1f4a9134a0c6e7f26a799b3
6
+ metadata.gz: 787ba756e146d4b72a0a7dd265df1baa3c4ddab27bf78e3e0d271dd1b333a7006e1e486b0369c9727ffed7bf15adb9e150fe8a13b7f743b2833a0b78ee9cf881
7
+ data.tar.gz: faf41a1355cf5cc3a20cc46aa25cd1e1b62b4bb69da66ef25bc20b2efdacabdfe6d0f736908120f6ecab24f7b011d4ecee36bfa94ce78d0271da878260023681
@@ -1,20 +1,97 @@
1
1
  module TestBench
2
2
  module Bootstrap
3
- def self.activate(receiver=nil)
4
- receiver ||= TOPLEVEL_BINDING.receiver
3
+ def self.activate
4
+ Object.include(Fixture)
5
+ end
6
+
7
+ if RUBY_ENGINE != 'mruby'
8
+ class Abort < SystemExit
9
+ def self.build
10
+ new(1)
11
+ end
12
+ end
13
+ end
14
+
15
+ class Abort
16
+ def self.call
17
+ Output.raw_write("#{Bootstrap} is aborting\n")
18
+ instance = build
19
+ raise instance
20
+ end
21
+ end
22
+
23
+ module Backtrace
24
+ if RUBY_ENGINE != 'mruby'
25
+ def self.frame(frame_index)
26
+ frame_index += 1
27
+
28
+ caller[frame_index]
29
+ end
30
+ end
31
+ end
32
+
33
+ class AssertionFailure < RuntimeError
34
+ def self.build(frame_index=nil)
35
+ frame_index ||= 0
36
+
37
+ frame = Backtrace.frame(frame_index)
38
+
39
+ instance = new
40
+ instance.set_backtrace([frame])
41
+ instance
42
+ end
43
+
44
+ def message
45
+ "Assertion failed"
46
+ end
47
+ end
5
48
 
6
- receiver.extend(Fixture)
49
+ module Path
50
+ if RUBY_ENGINE != 'mruby'
51
+ def self.match?(pattern, string)
52
+ ::File.fnmatch?(pattern, string)
53
+ end
54
+
55
+ def self.search(path, include_pattern=nil, exclude_pattern=nil)
56
+ files = []
57
+
58
+ if ::File.directory?(path)
59
+ search_directory(path, files, include_pattern, exclude_pattern)
60
+ elsif ::File.exist?(path)
61
+ files << path
62
+ else
63
+ raise LoadError, "no such file or directory -- #{path}"
64
+ end
65
+
66
+ files
67
+ end
68
+
69
+ def self.search_directory(dir, files, include_pattern=nil, exclude_pattern=nil)
70
+ include_pattern ||= '*.rb'
71
+
72
+ ::Dir[::File.join(dir, '**', '*')].each do |path|
73
+ next if ::File.directory?(path)
74
+
75
+ if match?(include_pattern, path)
76
+ if exclude_pattern.nil? || !match?(exclude_pattern, path)
77
+ files << path
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
7
83
  end
8
84
 
9
85
  module Fixture
10
86
  def assert(value)
11
87
  unless value
12
- raise AssertionFailure.build(caller.first)
88
+ raise AssertionFailure.build(1)
13
89
  end
14
90
  end
15
91
 
16
92
  def assert_raises(error_class=nil, &block)
17
93
  begin
94
+ Output.raw_write("assert_raises\n")
18
95
  block.()
19
96
 
20
97
  rescue (error_class || StandardError) => error
@@ -27,12 +104,12 @@ module TestBench
27
104
  end
28
105
  end
29
106
 
30
- raise AssertionFailure.build(caller.first)
107
+ raise AssertionFailure.build(1)
31
108
  end
32
109
 
33
110
  def refute(value)
34
111
  if value
35
- raise AssertionFailure.build(caller.first)
112
+ raise AssertionFailure.build(1)
36
113
  end
37
114
  end
38
115
 
@@ -44,7 +121,7 @@ module TestBench
44
121
  raise error
45
122
  end
46
123
 
47
- raise AssertionFailure.build(caller.first)
124
+ raise AssertionFailure.build(1)
48
125
  end
49
126
 
50
127
  def context(prose=nil, &block)
@@ -64,9 +141,9 @@ module TestBench
64
141
  block.()
65
142
 
66
143
  rescue => error
67
- Fixture.print_error(error)
144
+ Output.error(error)
68
145
 
69
- raise Failure.build
146
+ Abort.()
70
147
  end
71
148
  end
72
149
 
@@ -87,10 +164,10 @@ module TestBench
87
164
 
88
165
  rescue => error
89
166
  Output.indent(prose, sgr_codes: [0x1, 0x31]) do
90
- Fixture.print_error(error)
167
+ Output.error(error)
91
168
  end
92
169
 
93
- raise Failure.build
170
+ Abort.()
94
171
  end
95
172
  end
96
173
 
@@ -102,6 +179,10 @@ module TestBench
102
179
  Output.write(text)
103
180
  end
104
181
 
182
+ def detail(text)
183
+ comment(text)
184
+ end
185
+
105
186
  def fixture(cls, *args, **kwargs, &block)
106
187
  fixture = TestBench::Fixture.(cls, *args, **kwargs, &block)
107
188
 
@@ -109,66 +190,79 @@ module TestBench
109
190
 
110
191
  assert(passed)
111
192
  end
193
+ end
194
+
195
+ module Output
196
+ extend self
197
+
198
+ def write(text, device: nil, sgr_code: nil, sgr_codes: nil, tab_indent: nil)
199
+ indent(text, device: device, sgr_code: sgr_code, sgr_codes: sgr_codes, tab_indent: tab_indent)
200
+ end
112
201
 
113
- def self.print_error(error)
114
- omit_backtrace_pattern = ENV['TEST_BENCH_OMIT_BACKTRACE_PATTERN']
115
- omit_backtrace_pattern ||= %r{test_bench/bootstrap\.rb}
202
+ def error(error)
203
+ omit_backtrace_pattern = Defaults.omit_backtrace_pattern
116
204
 
117
205
  omitting = false
118
206
 
119
- Output.write("\e[1mTraceback\e[22m (most recent call last):", sgr_code: 0x31)
207
+ write("\e[1mTraceback\e[22m (most recent call last):", sgr_code: 0x31)
120
208
 
121
209
  rjust_length = error.backtrace.length.to_s.length
122
210
 
123
- error.backtrace[1..-1].reverse_each.with_index do |line, index|
124
- line = line.dup
211
+ reverse_backtrace = error.backtrace[1..-1].reverse
212
+
213
+ reverse_backtrace.each_with_index do |frame, index|
214
+ frame = frame.dup
215
+ frame.chomp!
125
216
 
126
- line.chomp!
217
+ previous_frame = frame
127
218
 
128
- if omit_backtrace_pattern.match?(line)
219
+ file, _ = frame.split(':', 2)
220
+
221
+ line = ' ' * rjust_length
222
+
223
+ index_text = index.to_s
224
+ index_range = (-index_text.length..-1)
225
+
226
+ if Path.match?(omit_backtrace_pattern, file)
129
227
  if omitting
130
228
  next
131
229
  else
132
230
  omitting = true
133
231
 
134
- header = index.to_s.gsub(/./, '?').rjust(rjust_length, ' ')
232
+ line[index_range] = '?' * index_text.length
233
+ line += ": *omitted*"
135
234
 
136
- Output.write("#{header}: *omitted*", sgr_codes: [0x2, 0x3, 0x31], tab_indent: true)
235
+ write(line, sgr_codes: [0x2, 0x3, 0x31], tab_indent: true)
137
236
  end
138
237
  else
139
238
  omitting = false
140
239
 
141
- header = index.to_s.rjust(rjust_length, ' ')
240
+ line[index_range] = index_text
241
+ line += ": #{frame}"
142
242
 
143
- Output.write("#{header}: #{line}", sgr_code: 0x31, tab_indent: true)
243
+ write(line, sgr_code: 0x31, tab_indent: true)
144
244
  end
145
245
  end
146
246
 
147
247
  if error.message.empty?
148
248
  if error.instance_of?(RuntimeError)
149
- Output.write("#{error.backtrace[0]}: \e[1;4munhandled exception\e[24;22m", sgr_code: 0x31)
249
+ write("#{error.backtrace[0]}: \e[1;4munhandled exception\e[24;22m", sgr_code: 0x31)
150
250
  return
151
251
  end
152
252
 
153
253
  error.message = error.class
154
254
  end
155
255
 
156
- Output.write("#{error.backtrace[0]} \e[1m#{error} (\e[4m#{error.class}\e[24m)\e[22m", sgr_code: 0x31)
256
+ write("#{error.backtrace[0]}: \e[1m#{error} (\e[4m#{error.class}\e[24m)\e[22m", sgr_code: 0x31)
157
257
  end
158
- end
159
-
160
- module Output
161
- extend self
162
258
 
163
- def write(text, device: nil, sgr_code: nil, sgr_codes: nil, tab_indent: nil)
164
- indent(text, device: device, sgr_code: sgr_code, sgr_codes: sgr_codes, tab_indent: tab_indent)
259
+ def newline
260
+ write('')
165
261
  end
166
262
 
167
263
  def indent(text, device: nil, sgr_code: nil, sgr_codes: nil, tab_indent: nil, &block)
168
- device ||= $stdout
169
-
170
264
  unless text.nil?
171
- sgr_codes = Array(sgr_codes)
265
+ sgr_codes ||= []
172
266
  unless sgr_code.nil?
173
267
  sgr_codes << sgr_code
174
268
  end
@@ -181,9 +275,9 @@ module TestBench
181
275
  text = "\e[#{sgr_codes.join(';')}m#{text}\e[0m"
182
276
  end
183
277
 
184
- text = "#{"\t" if tab_indent}#{' ' * indentation}#{text}"
278
+ text = "#{"\t" if tab_indent}#{' ' * indentation}#{text}\n"
185
279
 
186
- device.puts(text)
280
+ raw_write(text, device)
187
281
  end
188
282
 
189
283
  return if block.nil?
@@ -197,67 +291,83 @@ module TestBench
197
291
  end
198
292
  end
199
293
 
200
- def indentation
201
- @indentation ||= 0
202
- end
203
- attr_writer :indentation
204
- end
205
-
206
- class AssertionFailure < RuntimeError
207
- def self.build(caller_location=nil)
208
- caller_location ||= caller(0)
294
+ def raw_write(text, device=nil)
295
+ device ||= self.device
209
296
 
210
- instance = new
211
- instance.set_backtrace([caller_location])
212
- instance
297
+ device.write(text)
213
298
  end
214
299
 
215
- def message
216
- "Assertion failed"
300
+ def indentation
301
+ @indentation ||= 0
217
302
  end
218
- end
303
+ attr_writer :indentation
219
304
 
220
- class Failure < SystemExit
221
- def self.build
222
- new(1, "TestBench::Bootstrap is aborting")
305
+ def device
306
+ @device ||= Defaults.output_device
223
307
  end
224
308
  end
225
309
 
226
310
  module Run
227
- def self.call(argv=nil, exclude_file_pattern: nil)
228
- argv ||= ::ARGV
311
+ def self.call(paths=nil, exclude_pattern: nil)
312
+ paths ||= []
313
+ exclude_pattern ||= Defaults.exclude_file_pattern
229
314
 
230
- exclude_file_pattern = ENV['TEST_BENCH_EXCLUDE_FILE_PATTERN']
231
- exclude_file_pattern ||= %r{automated_init\.rb}
232
-
233
- if argv.empty?
234
- tests_dir = ENV['TEST_BENCH_TESTS_DIR'] || 'test/automated'
235
-
236
- file_patterns = [File.join(tests_dir, '**', '*.rb')]
237
- else
238
- file_patterns = argv
315
+ if paths.is_a?(String)
316
+ paths = [paths]
239
317
  end
240
318
 
241
- file_patterns.each do |file_pattern|
242
- if File.directory?(file_pattern)
243
- file_pattern = File.join(file_pattern, '**/*.rb')
244
- end
245
-
246
- files = Dir[file_pattern].reject do |file|
247
- File.basename(file).match?(exclude_file_pattern)
248
- end
319
+ if paths.empty?
320
+ paths << Defaults.tests_dir
321
+ end
249
322
 
250
- files.sort.each do |file|
251
- puts "Running #{file}"
323
+ paths.each do |path|
324
+ Path.search(path, '*.rb', exclude_pattern).each do |file|
325
+ Output.write "Running #{file}"
252
326
 
253
327
  begin
254
- load file
328
+ load(file)
255
329
  ensure
256
- puts
330
+ Output.newline
257
331
  end
258
332
  end
259
333
  end
260
334
  end
261
335
  end
336
+
337
+ module Defaults
338
+ def self.get(env_var, default)
339
+ if env.key?(env_var)
340
+ env[env_var]
341
+ else
342
+ default
343
+ end
344
+ end
345
+
346
+ def self.exclude_file_pattern
347
+ get('TEST_BENCH_EXCLUDE_FILE_PATTERN', '*_init.rb')
348
+ end
349
+
350
+ def self.omit_backtrace_pattern
351
+ get('TEST_BENCH_OMIT_BACKTRACE_PATTERN', '*/test_bench/bootstrap.rb')
352
+ end
353
+
354
+ def self.tests_dir
355
+ get('TEST_BENCH_TESTS_DIRECTORY', 'test/automated')
356
+ end
357
+
358
+ if RUBY_ENGINE == 'mruby'
359
+ def self.env
360
+ {}
361
+ end
362
+ else
363
+ def self.output_device
364
+ $stdout
365
+ end
366
+
367
+ def self.env
368
+ ::ENV
369
+ end
370
+ end
371
+ end
262
372
  end
263
373
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: test_bench-bootstrap
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Ladd
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-08 00:00:00.000000000 Z
11
+ date: 2022-08-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: nathanladd+github@gmail.com
@@ -36,7 +36,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
36
36
  - !ruby/object:Gem::Version
37
37
  version: '0'
38
38
  requirements: []
39
- rubygems_version: 3.1.4
39
+ rubygems_version: 3.3.4
40
40
  signing_key:
41
41
  specification_version: 4
42
42
  summary: A minimal test framework for testing TestBench