ruptr 0.1.3

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2bb54a65cd25733932795a5d3e7b3f414f74c1601bd4dbbb24bf3d39543112ec
4
+ data.tar.gz: 81459ecd24738d49985cd8557893ef01760483bf5f0a626932e0e5cc1dcaaa99
5
+ SHA512:
6
+ metadata.gz: d15c2d9e871e62c547def98b0f7adcccd56f53159523f438b2b2e07f7de7e515364e5954845ed50fd6fb2edc1724d74e5a2360e4c47b8634f3037e466b258593
7
+ data.tar.gz: db349382ea275b3c2793dc1630dced2bf56f05abc5a467e110c66bbe10cb6b9ea72f4bb9812580079306da3a9527273a5faf054d54b5424e8b273e430a8cf468
data/bin/ruptr ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'ruptr/main'
5
+
6
+ main = Ruptr::Main.new
7
+ argv = ARGV.dup
8
+ ARGV.clear # some test scripts take actions based on ARGV
9
+ main.parse_options(argv)
10
+ exit main.run
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../assertions'
4
+ require_relative '../exceptions'
5
+ require_relative '../adapters'
6
+ require_relative '../stringified'
7
+
8
+ module Ruptr
9
+ class Assertions::AssertionError
10
+ include AssertionErrorMixin
11
+ end
12
+
13
+ class Assertions::SkippedException
14
+ include SkippedExceptionMixin
15
+ end
16
+
17
+ module Adapters::RuptrAssertions
18
+ include TestInstance
19
+ include Ruptr::Assertions
20
+
21
+ def bump_assertions_count = self.ruptr_assertions_count += 1
22
+ def passthrough_exception?(ex) = ex.is_a?(SkippedExceptionMixin) || super
23
+ def assertion_exception?(ex) = ex.is_a?(AssertionErrorMixin) || super
24
+
25
+ def assertion_capture_value(v) = Stringified.from(v)
26
+
27
+ def assertions_golden_store = ruptr_context.runner.golden_store
28
+
29
+ def assertion_golden_key(k) = [ruptr_context.test_element.path_identifiers, k]
30
+
31
+ def assertion_set_golden_trial_value(k, v)
32
+ assertions_golden_store.set_trial(assertion_golden_key(k), v)
33
+ end
34
+
35
+ def assertion_golden_value_missing(k)
36
+ warn "golden value missing for key #{k.inspect}"
37
+ end
38
+
39
+ def assertion_yield_golden_value(k)
40
+ yield assertions_golden_store.get_golden(assertion_golden_key(k)) { return assertion_golden_value_missing(k) }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rr'
4
+
5
+ require_relative '../adapters'
6
+
7
+ module Ruptr
8
+ module Adapters::RR
9
+ include TestInstance
10
+
11
+ def ruptr_wrap_test_instance
12
+ super do
13
+ ::RR.reset
14
+ begin
15
+ yield
16
+ ::RR.verify
17
+ ensure
18
+ ::RR.reset
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspec/expectations'
4
+
5
+ require_relative '../adapters'
6
+
7
+ module Ruptr
8
+ module Adapters::RSpecExpect
9
+ include TestInstance
10
+ include ::RSpec::Matchers
11
+
12
+ def expect(...)
13
+ self.ruptr_assertions_count += 1
14
+ super
15
+ end
16
+
17
+ module Helpers
18
+ def should(matcher, message = nil)
19
+ self.ruptr_assertions_count += 1
20
+ ::RSpec::Expectations::PositiveExpectationHandler.handle_matcher(subject, matcher, message)
21
+ end
22
+
23
+ def should_not(matcher, message = nil)
24
+ self.ruptr_assertions_count += 1
25
+ ::RSpec::Expectations::NegativeExpectationHandler.handle_matcher(subject, matcher, message)
26
+ end
27
+
28
+ def subject = nil
29
+ def is_expected = expect(subject)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspec/mocks'
4
+
5
+ require_relative '../adapters'
6
+ require_relative 'rspec_expect'
7
+
8
+ module Ruptr
9
+ module Adapters::RSpecMocks
10
+ include TestInstance
11
+ # NOTE: On inclusion, RSpec::Mocks::ExampleMethods will define its own restricted variant of the
12
+ # #expect method if it is not already defined in the including module. Thus, always include
13
+ # RSpec::Matchers (via Adapters::RSpecExpect) first to get the real #expect method.
14
+ include Adapters::RSpecExpect
15
+ include ::RSpec::Mocks::ExampleMethods
16
+
17
+ def ruptr_wrap_test_instance
18
+ super do
19
+ ::RSpec::Mocks.setup
20
+ begin
21
+ yield
22
+ ::RSpec::Mocks.verify
23
+ ensure
24
+ ::RSpec::Mocks.teardown
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'instance'
4
+
5
+ module Ruptr
6
+ module Adapters; end
7
+ end
@@ -0,0 +1,493 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'capture_output'
4
+
5
+ module Ruptr
6
+ module Assertions
7
+ class AssertionError < StandardError; end
8
+
9
+ class UnexpectedExceptionError < AssertionError; end
10
+
11
+ class UnexpectedValueError < AssertionError
12
+ def initialize(message = nil, actual:)
13
+ super(message)
14
+ @actual = actual
15
+ end
16
+
17
+ attr_reader :actual
18
+ end
19
+
20
+ class EquivalenceAssertionError < UnexpectedValueError
21
+ def initialize(message = nil, actual:, expected:)
22
+ super(message, actual:)
23
+ @expected = expected
24
+ end
25
+
26
+ attr_reader :expected
27
+ end
28
+
29
+ class EquivalenceRefutationError < UnexpectedValueError
30
+ def initialize(message = nil, actual:, unexpected:)
31
+ super(message, actual:)
32
+ @unexpected = unexpected
33
+ end
34
+
35
+ attr_reader :unexpected
36
+ end
37
+
38
+ class SkippedException < Exception; end
39
+
40
+ private
41
+
42
+ def bump_assertions_count = nil
43
+ def bump_skipped_blocks_count = nil
44
+
45
+ def assertion_inspect_complete(val) = val.inspect
46
+ def assertion_inspect_truncate = 256
47
+
48
+ def assertion_inspect(val)
49
+ str = assertion_inspect_complete(val)
50
+ if (n = assertion_inspect_truncate) && str.length > n
51
+ str = "#{str[0, n]}... (truncated)"
52
+ end
53
+ str
54
+ end
55
+
56
+ def assertion_capture_value(v) = v
57
+
58
+ def get_assertion_message(msg)
59
+ msg.is_a?(Proc) ? msg.call : msg
60
+ end
61
+
62
+ public
63
+
64
+ def assertion_raise(klass, msg, ...)
65
+ raise klass.new(get_assertion_message(msg), ...)
66
+ end
67
+
68
+ def assertion_failed(msg)
69
+ assertion_raise(AssertionError, msg)
70
+ end
71
+
72
+ def assertion_unexpected_exception(exc, msg = nil)
73
+ assertion_raise(UnexpectedExceptionError, msg || "unexpected exception: #{assertion_inspect(exc)}")
74
+ end
75
+
76
+ def assertion_unexpected_value(val, msg = nil)
77
+ assertion_raise(UnexpectedValueError, msg || "unexpected value: #{assertion_inspect(val)}",
78
+ actual: assertion_capture_value(val))
79
+ end
80
+
81
+ def pass(_msg = nil)
82
+ bump_assertions_count
83
+ end
84
+
85
+ def flunk(msg = nil)
86
+ bump_assertions_count
87
+ assertion_failed(msg || "Flunked")
88
+ end
89
+
90
+ def assert(val, msg = nil)
91
+ bump_assertions_count
92
+ return if val
93
+ assertion_unexpected_value(val, msg || "expected #{assertion_inspect(val)} to be truthy")
94
+ end
95
+
96
+ def refute(val, msg = nil)
97
+ bump_assertions_count
98
+ return unless val
99
+ assertion_unexpected_value(val, msg || "expected #{assertion_inspect(val)} to be falsey")
100
+ end
101
+
102
+ alias assert_not refute
103
+
104
+ def assert_block(msg = nil) = assert(yield, msg)
105
+ def refute_block(msg = nil) = refute(yield, msg)
106
+ alias assert_not_block refute_block
107
+
108
+ def assert_equal(exp, act, msg = nil)
109
+ bump_assertions_count
110
+ return if exp == act
111
+ assertion_raise(EquivalenceAssertionError,
112
+ msg || "expected #{assertion_inspect(act)} to be #{assertion_inspect(exp)}",
113
+ actual: assertion_capture_value(act),
114
+ expected: assertion_capture_value(exp))
115
+ end
116
+
117
+ def refute_equal(exp, act, msg = nil)
118
+ bump_assertions_count
119
+ return unless exp == act
120
+ assertion_raise(EquivalenceRefutationError,
121
+ msg || "expected #{assertion_inspect(act)} to be something else",
122
+ actual: assertion_capture_value(act),
123
+ unexpected: assertion_capture_value(exp))
124
+ end
125
+
126
+ alias assert_not_equal refute_equal
127
+
128
+ def assert_match(pat, act, msg = nil)
129
+ bump_assertions_count
130
+ pat = Regexp.new(Regexp.quote(pat)) if pat.is_a?(String)
131
+ return $~ if pat =~ act
132
+ assertion_unexpected_value(act, msg || "expected #{assertion_inspect(pat)} " \
133
+ "to match #{assertion_inspect(act)}")
134
+ end
135
+
136
+ def refute_match(pat, act, msg = nil)
137
+ bump_assertions_count
138
+ pat = Regexp.new(Regexp.quote(pat)) if pat.is_a?(String)
139
+ return unless pat =~ act
140
+ assertion_unexpected_value(act, msg || "expected #{assertion_inspect(pat)} " \
141
+ "not to match #{assertion_inspect(act)}")
142
+ end
143
+
144
+ alias assert_not_match refute_match
145
+ alias assert_no_match refute_match
146
+
147
+ def assert_pattern(msg = nil)
148
+ yield
149
+ rescue NoMatchingPatternError
150
+ bump_assertions_count
151
+ assertion_failed(msg || $!.message)
152
+ else
153
+ bump_assertions_count
154
+ end
155
+
156
+ def refute_pattern(msg = nil)
157
+ yield
158
+ rescue NoMatchingPatternError
159
+ bump_assertions_count
160
+ else
161
+ bump_assertions_count
162
+ assertion_failed(msg || "expected pattern not to match")
163
+ end
164
+
165
+ def assert_true(val, msg = nil) = assert_equal(true, val, msg)
166
+ def assert_false(val, msg = nil) = assert_equal(false, val, msg)
167
+ def assert_boolean(val, msg = nil) = assert_includes([true, false], val, msg)
168
+
169
+ def assert_predicate(target, pred, msg = nil)
170
+ bump_assertions_count
171
+ return if target.public_send(pred)
172
+ assertion_unexpected_value(target, msg || "expected #{assertion_inspect(target)} to be #{pred}")
173
+ end
174
+
175
+ def refute_predicate(target, pred, msg = nil)
176
+ bump_assertions_count
177
+ return unless target.public_send(pred)
178
+ assertion_unexpected_value(target, msg || "expected #{assertion_inspect(target)} not to be #{pred}")
179
+ end
180
+
181
+ alias assert_not_predicate refute_predicate
182
+
183
+ def assert_operator(arg1, oper, arg2 = (no_arg2 = true; nil), msg = nil)
184
+ return assert_predicate(arg1, oper, msg) if no_arg2
185
+ bump_assertions_count
186
+ return if arg1.public_send(oper, arg2)
187
+ assertion_unexpected_value(arg1, msg || "expected #{assertion_inspect(arg1)} " \
188
+ "to be #{oper} #{assertion_inspect(arg2)}")
189
+ end
190
+
191
+ alias assert_compare assert_operator
192
+
193
+ def refute_operator(arg1, oper, arg2 = (no_arg2 = true; nil), msg = nil)
194
+ return refute_predicate(arg1, oper, msg) if no_arg2
195
+ bump_assertions_count
196
+ return unless arg1.public_send(oper, arg2)
197
+ assertion_unexpected_value(arg1, msg || "expected #{assertion_inspect(arg1)} " \
198
+ "not to be #{oper} #{assertion_inspect(arg2)}")
199
+ end
200
+
201
+ alias assert_not_operator refute_operator
202
+
203
+ def assert_all(enum, msg = nil, &)
204
+ bump_assertions_count
205
+ return if enum.all?(&)
206
+ assertion_unexpected_value(enum, msg || "expected truthy block for all elements of #{assertion_inspect(enum)}")
207
+ end
208
+
209
+ def assert_send(array, msg = nil)
210
+ target, method_name, *args = array
211
+ bump_assertions_count
212
+ return if target.__send__(method_name, *args)
213
+ assertion_unexpected_value(target,
214
+ msg || "expected #{assertion_inspect(target)}.#{method_name}" \
215
+ "(#{args.map { |arg| assertion_inspect(arg) }.join(', ')}) to be truthy")
216
+ end
217
+
218
+ def refute_send(array, msg = nil)
219
+ target, method_name, *args = array
220
+ bump_assertions_count
221
+ return unless target.__send__(method_name, *args)
222
+ assertion_unexpected_value(target,
223
+ msg || "expected #{assertion_inspect(target)}.#{method_name}" \
224
+ "(#{args.map { |arg| assertion_inspect(arg) }.join(', ')}) not to be truthy")
225
+ end
226
+
227
+ alias assert_not_send refute_send
228
+
229
+ def assert_in_delta(exp, act, delta = 0.001, msg = nil)
230
+ raise ArgumentError if delta.negative?
231
+ bump_assertions_count
232
+ return if (exp - act).abs <= delta
233
+ assertion_unexpected_value(act, msg || "expected #{assertion_inspect(act)} to be within " \
234
+ "#{assertion_inspect(delta)} of #{assertion_inspect(exp)}")
235
+ end
236
+
237
+ def refute_in_delta(exp, act, delta = 0.001, msg = nil)
238
+ raise ArgumentError if delta.negative?
239
+ bump_assertions_count
240
+ return if (exp - act).abs > delta
241
+ assertion_unexpected_value(act, msg || "expected #{assertion_inspect(act)} not to be within " \
242
+ "#{assertion_inspect(delta)} of #{assertion_inspect(exp)}")
243
+ end
244
+
245
+ alias assert_not_in_delta refute_in_delta
246
+
247
+ def assert_in_epsilon(exp, act, epsilon = 0.001, msg = nil)
248
+ assert_in_delta(exp, act, exp.zero? ? epsilon : exp.abs * epsilon, msg)
249
+ end
250
+
251
+ def refute_in_epsilon(exp, act, epsilon = 0.001, msg = nil)
252
+ refute_in_delta(exp, act, exp.zero? ? epsilon : exp.abs * epsilon, msg)
253
+ end
254
+
255
+ alias assert_not_in_epsilon refute_in_epsilon
256
+
257
+ def assert_path_exists(path, msg = nil)
258
+ assert File.exist?(path), msg || "expected path #{assertion_inspect(path)} to exist"
259
+ end
260
+
261
+ def refute_path_exists(path, msg = nil)
262
+ refute File.exist?(path), msg || "expected path #{assertion_inspect(path)} not to exist"
263
+ end
264
+
265
+ alias assert_path_exist assert_path_exists
266
+ alias assert_path_not_exist refute_path_exists
267
+
268
+ def assert_alias_method(obj, name1, name2, msg = nil)
269
+ bump_assertions_count
270
+ return if obj.method(name1) == obj.method(name2)
271
+ assertion_unexpected_value(obj, msg || "expected #{assertion_inspect(obj)} " \
272
+ "to have methods #{name1} and #{name2} be aliased")
273
+ end
274
+
275
+ def refute_alias_method(obj, name1, name2, msg = nil)
276
+ bump_assertions_count
277
+ return unless obj.method(name1) == obj.method(name2)
278
+ assertion_unexpected_value(obj, msg || "expected #{assertion_inspect(obj)} " \
279
+ "to not have methods #{name1} and #{name2} be aliased")
280
+ end
281
+
282
+ alias assert_not_alias_method refute_alias_method
283
+
284
+ def assert_golden(actual, msg = nil, key: nil)
285
+ assertion_set_golden_trial_value(key, actual)
286
+ # NOTE: does not yield if there are no golden value saved yet
287
+ assertion_yield_golden_value(key) do |golden|
288
+ if block_given?
289
+ yield golden, actual, msg
290
+ else
291
+ assert_equal golden, actual, msg
292
+ end
293
+ end
294
+ end
295
+
296
+ def self.def_predicate_shortcut(shortcut_name_suffix, predicate_name)
297
+ define_method(:"assert_#{shortcut_name_suffix}") do |target, msg = nil|
298
+ assert_predicate target, predicate_name, msg
299
+ end
300
+ define_method(:"refute_#{shortcut_name_suffix}") do |target, msg = nil|
301
+ refute_predicate target, predicate_name, msg
302
+ end
303
+ alias_method(:"assert_not_#{shortcut_name_suffix}", :"refute_#{shortcut_name_suffix}")
304
+ end
305
+
306
+ def self.def_operator_shortcut(shortcut_name_suffix, operator_name, swapped: false)
307
+ define_method(:"assert_#{shortcut_name_suffix}") do |arg1, arg2, msg = nil|
308
+ arg1, arg2 = arg2, arg1 if swapped
309
+ assert_operator arg1, operator_name, arg2, msg
310
+ end
311
+ define_method(:"refute_#{shortcut_name_suffix}") do |arg1, arg2, msg = nil|
312
+ arg1, arg2 = arg2, arg1 if swapped
313
+ refute_operator arg1, operator_name, arg2, msg
314
+ end
315
+ alias_method(:"assert_not_#{shortcut_name_suffix}", :"refute_#{shortcut_name_suffix}")
316
+ end
317
+
318
+ def_predicate_shortcut :nil, :nil?
319
+ def_predicate_shortcut :empty, :empty?
320
+ def_operator_shortcut :same, :equal?
321
+ def_operator_shortcut :case_equal, :===
322
+ def_operator_shortcut :respond_to, :respond_to?
323
+ def_operator_shortcut :includes, :include?
324
+ def_operator_shortcut :include, :include?
325
+ def_operator_shortcut :instance_of, :instance_of?, swapped: true
326
+ def_operator_shortcut :kind_of, :kind_of?, swapped: true
327
+ def_operator_shortcut :const_defined, :const_defined?
328
+
329
+ PASSTHROUGH_EXCEPTIONS = [
330
+ AssertionError,
331
+ SkippedException,
332
+ SignalException,
333
+ SystemExit,
334
+ ].freeze
335
+
336
+ def passthrough_exception?(ex) = case ex when *PASSTHROUGH_EXCEPTIONS then true else false end
337
+
338
+ def assertion_exception?(ex) = ex.is_a?(AssertionError)
339
+
340
+ def standard_exception?(ex) = ex.is_a?(StandardError)
341
+
342
+ # minitest's
343
+
344
+ def assert_raises(*expected)
345
+ msg = expected.pop if expected.last.is_a?(String)
346
+ expected = [StandardError] if expected.empty?
347
+ begin
348
+ yield
349
+ rescue *expected
350
+ bump_assertions_count
351
+ $!
352
+ rescue Exception
353
+ raise if passthrough_exception?($!)
354
+ bump_assertions_count
355
+ assertion_unexpected_exception($!, msg)
356
+ else
357
+ bump_assertions_count
358
+ assertion_failed(msg || "no exceptions raised")
359
+ end
360
+ end
361
+
362
+ alias assert_raise_kind_of assert_raises
363
+
364
+ # test/unit's
365
+
366
+ def assert_raise_exception_matches?(exception, *expected)
367
+ return true if expected.empty?
368
+ expected_modules, expected_instances = expected.partition { |v| v.is_a?(Module) }
369
+ expected_classes, expected_modules = expected_modules.partition { |v| v.is_a?(Class) }
370
+ expected_modules.any? { |m| exception.is_a?(m) } ||
371
+ expected_classes.any? { |c| exception.instance_of?(c) } ||
372
+ expected_instances.any? { |e| e.class == exception.class && e.message == exception.message }
373
+ end
374
+
375
+ def assert_raise_with_message(expected, expected_message, msg = nil)
376
+ yield
377
+ rescue Exception
378
+ if assert_raise_exception_matches?($!, *expected) &&
379
+ (expected_message.nil? || expected_message === $!.message)
380
+ bump_assertions_count
381
+ $!
382
+ else
383
+ raise if passthrough_exception?($!)
384
+ bump_assertions_count
385
+ assertion_unexpected_exception($!, msg)
386
+ end
387
+ else
388
+ bump_assertions_count
389
+ assertion_failed(msg || "no exceptions raised")
390
+ end
391
+
392
+ def assert_raise(*expected, &)
393
+ msg = expected.pop if expected.last.is_a?(String)
394
+ assert_raise_with_message(expected, nil, msg, &)
395
+ end
396
+
397
+ def assert_nothing_raised(*expected)
398
+ msg = expected.pop if expected.last.is_a?(String)
399
+ begin
400
+ r = yield
401
+ rescue Exception
402
+ raise unless assert_raise_exception_matches?($!, *expected)
403
+ bump_assertions_count
404
+ assertion_unexpected_exception($!, msg)
405
+ else
406
+ bump_assertions_count
407
+ end
408
+ r
409
+ end
410
+
411
+ def assert_raise_message(expected_message, msg = nil, &)
412
+ assert_raise_with_message([], expected_message, msg, &)
413
+ end
414
+
415
+ def assert_fail_assertion(msg = nil, &)
416
+ assert_raises(AssertionError, msg || "expected failed assertion", &)
417
+ end
418
+
419
+ def assert_throws(tag, msg = nil)
420
+ caught = true
421
+ r = catch(tag) do
422
+ yield tag
423
+ caught = false
424
+ rescue Exception
425
+ raise if assertion_exception?($!) || !standard_exception?($!)
426
+ bump_assertions_count
427
+ assertion_unexpected_exception($!)
428
+ end
429
+ bump_assertions_count
430
+ return r if caught
431
+ assertion_failed(msg || "expected block to throw #{assertion_inspect(tag)}")
432
+ end
433
+
434
+ alias assert_throw assert_throws
435
+
436
+ def assert_nothing_thrown(msg = nil)
437
+ begin
438
+ r = yield
439
+ rescue UncaughtThrowError
440
+ bump_assertions_count
441
+ assertion_failed(msg || "block threw #{assertion_inspect($!.tag)} unexpectedly")
442
+ else
443
+ bump_assertions_count
444
+ end
445
+ r
446
+ end
447
+
448
+ def capture_io(&) = Ruptr::CaptureOutput.capture_output(&)
449
+
450
+ alias capture_output capture_io
451
+
452
+ def assert_output(expected_stdout = nil, expected_stderr = nil, &)
453
+ begin
454
+ actual_stdout, actual_stderr = capture_io(&)
455
+ rescue Exception
456
+ raise if assertion_exception?($!) || !standard_exception?($!)
457
+ bump_assertions_count
458
+ assertion_unexpected_exception($!)
459
+ end
460
+ bump_assertions_count
461
+ unless expected_stderr.nil? || expected_stderr === actual_stderr
462
+ assertion_unexpected_value(actual_stderr,
463
+ "expected stderr to be #{assertion_inspect(expected_stderr)} " \
464
+ "instead of #{assertion_inspect(actual_stderr)}")
465
+ end
466
+ unless expected_stdout.nil? || expected_stdout === actual_stdout
467
+ assertion_unexpected_value(actual_stdout,
468
+ "expected stdout to be #{assertion_inspect(expected_stdout)} " \
469
+ "instead of #{assertion_inspect(actual_stdout)}")
470
+ end
471
+ end
472
+
473
+ def assert_silent(&)
474
+ assert_output('', '', &)
475
+ end
476
+
477
+ def skip(msg = nil)
478
+ raise ArgumentError if block_given?
479
+ assertion_raise(SkippedException, msg || "skipped")
480
+ end
481
+
482
+ def pend(msg = nil, &)
483
+ skip(msg) unless block_given?
484
+ assert_raises(StandardError, msg, &)
485
+ bump_skipped_blocks_count
486
+ end
487
+
488
+ def omit(msg = nil)
489
+ skip(msg) unless block_given?
490
+ bump_skipped_blocks_count
491
+ end
492
+ end
493
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'suite'
4
+ require_relative 'utils'
5
+
6
+ module Ruptr
7
+ class Compat
8
+ def prepare_autorun!(test_suite = Ruptr::TestSuite.global_autorun_test_suite)
9
+ @autorun_test_suite = test_suite
10
+ global_install!
11
+ end
12
+
13
+ def schedule_autorun!
14
+ return if @autorun_scheduled
15
+ return unless @autorun_test_suite
16
+ @autorun_test_suite.run_on_exit!
17
+ Ruptr.at_normal_exit do
18
+ finalize_configuration!
19
+ @autorun_test_suite.add_test_subgroup(adapted_test_group)
20
+ end
21
+ @autorun_scheduled = true
22
+ end
23
+ end
24
+
25
+ class TestSuite
26
+ def self.global_autorun_test_suite = @global_autorun_test_suite ||= TestSuite.new
27
+
28
+ def run_on_exit!
29
+ return if @run_on_exit
30
+ require_relative 'runner'
31
+ require_relative 'formatter'
32
+ Ruptr.at_normal_exit do
33
+ Runner.from_env.run_sink(self, Formatter.from_env($stdout))
34
+ end
35
+ @run_on_exit = true
36
+ end
37
+ end
38
+ end