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 +7 -0
- data/bin/ruptr +10 -0
- data/lib/ruptr/adapters/assertions.rb +43 -0
- data/lib/ruptr/adapters/rr.rb +23 -0
- data/lib/ruptr/adapters/rspec_expect.rb +32 -0
- data/lib/ruptr/adapters/rspec_mocks.rb +29 -0
- data/lib/ruptr/adapters.rb +7 -0
- data/lib/ruptr/assertions.rb +493 -0
- data/lib/ruptr/autorun.rb +38 -0
- data/lib/ruptr/capture_output.rb +106 -0
- data/lib/ruptr/compat.rb +27 -0
- data/lib/ruptr/exceptions.rb +47 -0
- data/lib/ruptr/formatter.rb +78 -0
- data/lib/ruptr/golden_master.rb +143 -0
- data/lib/ruptr/instance.rb +37 -0
- data/lib/ruptr/main.rb +439 -0
- data/lib/ruptr/minitest/override.rb +4 -0
- data/lib/ruptr/minitest.rb +134 -0
- data/lib/ruptr/plain.rb +425 -0
- data/lib/ruptr/progress.rb +98 -0
- data/lib/ruptr/rake_task.rb +18 -0
- data/lib/ruptr/report.rb +104 -0
- data/lib/ruptr/result.rb +38 -0
- data/lib/ruptr/rspec/configuration.rb +191 -0
- data/lib/ruptr/rspec/example_group.rb +498 -0
- data/lib/ruptr/rspec/override.rb +4 -0
- data/lib/ruptr/rspec.rb +211 -0
- data/lib/ruptr/runner.rb +433 -0
- data/lib/ruptr/sink.rb +58 -0
- data/lib/ruptr/stringified.rb +57 -0
- data/lib/ruptr/suite.rb +188 -0
- data/lib/ruptr/surrogate_exception.rb +71 -0
- data/lib/ruptr/tabular.rb +21 -0
- data/lib/ruptr/tap.rb +51 -0
- data/lib/ruptr/testunit/override.rb +4 -0
- data/lib/ruptr/testunit.rb +117 -0
- data/lib/ruptr/timing_cache.rb +100 -0
- data/lib/ruptr/tty_colors.rb +60 -0
- data/lib/ruptr/utils.rb +57 -0
- metadata +77 -0
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,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,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
|