minitest 5.11.3 → 5.27.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/History.rdoc +426 -4
- data/Manifest.txt +6 -0
- data/README.rdoc +119 -20
- data/Rakefile +28 -17
- data/design_rationale.rb +21 -19
- data/lib/hoe/minitest.rb +4 -6
- data/lib/minitest/assertions.rb +257 -100
- data/lib/minitest/autorun.rb +4 -11
- data/lib/minitest/benchmark.rb +15 -18
- data/lib/minitest/compress.rb +94 -0
- data/lib/minitest/error_on_warning.rb +11 -0
- data/lib/minitest/expectations.rb +72 -35
- data/lib/minitest/hell.rb +1 -1
- data/lib/minitest/manual_plugins.rb +16 -0
- data/lib/minitest/mock.rb +131 -44
- data/lib/minitest/parallel.rb +7 -5
- data/lib/minitest/pride.rb +1 -1
- data/lib/minitest/pride_plugin.rb +18 -25
- data/lib/minitest/spec.rb +47 -25
- data/lib/minitest/test.rb +54 -36
- data/lib/minitest/test_task.rb +324 -0
- data/lib/minitest/unit.rb +6 -9
- data/lib/minitest.rb +443 -180
- data/test/minitest/metametameta.rb +65 -17
- data/test/minitest/test_minitest_assertions.rb +1677 -0
- data/test/minitest/test_minitest_benchmark.rb +3 -3
- data/test/minitest/test_minitest_mock.rb +405 -66
- data/test/minitest/test_minitest_reporter.rb +174 -36
- data/test/minitest/test_minitest_spec.rb +368 -196
- data/test/minitest/test_minitest_test.rb +476 -1244
- data/test/minitest/test_minitest_test_task.rb +57 -0
- data.tar.gz.sig +0 -0
- metadata +50 -23
- metadata.gz.sig +0 -0
data/lib/minitest/mock.rb
CHANGED
|
@@ -8,9 +8,9 @@ module Minitest # :nodoc:
|
|
|
8
8
|
# All mock objects are an instance of Mock
|
|
9
9
|
|
|
10
10
|
class Mock
|
|
11
|
-
alias
|
|
11
|
+
alias __respond_to? respond_to?
|
|
12
12
|
|
|
13
|
-
overridden_methods = %
|
|
13
|
+
overridden_methods = %i[
|
|
14
14
|
===
|
|
15
15
|
class
|
|
16
16
|
inspect
|
|
@@ -23,18 +23,23 @@ module Minitest # :nodoc:
|
|
|
23
23
|
to_s
|
|
24
24
|
]
|
|
25
25
|
|
|
26
|
+
overridden_methods << :singleton_method_added if defined?(::DEBUGGER__)
|
|
27
|
+
|
|
26
28
|
instance_methods.each do |m|
|
|
27
|
-
undef_method m unless overridden_methods.include?(m
|
|
29
|
+
undef_method m unless overridden_methods.include?(m) || m =~ /^__/
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
overridden_methods.map(&:to_sym).each do |method_id|
|
|
31
|
-
|
|
33
|
+
old_w, $-w = $-w, nil
|
|
34
|
+
define_method method_id do |*args, **kwargs, &b|
|
|
32
35
|
if @expected_calls.key? method_id then
|
|
33
|
-
method_missing(method_id, *args, &b)
|
|
36
|
+
method_missing(method_id, *args, **kwargs, &b)
|
|
34
37
|
else
|
|
35
|
-
super(*args, &b)
|
|
38
|
+
super(*args, **kwargs, &b)
|
|
36
39
|
end
|
|
37
40
|
end
|
|
41
|
+
ensure
|
|
42
|
+
$-w = old_w
|
|
38
43
|
end
|
|
39
44
|
|
|
40
45
|
def initialize delegator = nil # :nodoc:
|
|
@@ -43,9 +48,11 @@ module Minitest # :nodoc:
|
|
|
43
48
|
@actual_calls = Hash.new { |calls, name| calls[name] = [] }
|
|
44
49
|
end
|
|
45
50
|
|
|
51
|
+
@@KW_WARNED = false # :nodoc:
|
|
52
|
+
|
|
46
53
|
##
|
|
47
|
-
# Expect that method +name+ is called, optionally with +args+
|
|
48
|
-
# +blk
|
|
54
|
+
# Expect that method +name+ is called, optionally with +args+ (and
|
|
55
|
+
# +kwargs+ or a +blk+), and returns +retval+.
|
|
49
56
|
#
|
|
50
57
|
# @mock.expect(:meaning_of_life, 42)
|
|
51
58
|
# @mock.meaning_of_life # => 42
|
|
@@ -78,15 +85,31 @@ module Minitest # :nodoc:
|
|
|
78
85
|
# @mock.ordinal_increment # => raises MockExpectationError "No more expects available for :ordinal_increment"
|
|
79
86
|
#
|
|
80
87
|
|
|
81
|
-
def expect name, retval, args = [], &blk
|
|
88
|
+
def expect name, retval, args = [], **kwargs, &blk
|
|
82
89
|
name = name.to_sym
|
|
83
90
|
|
|
84
|
-
if
|
|
91
|
+
if blk then
|
|
85
92
|
raise ArgumentError, "args ignored when block given" unless args.empty?
|
|
93
|
+
raise ArgumentError, "kwargs ignored when block given" unless kwargs.empty?
|
|
86
94
|
@expected_calls[name] << { :retval => retval, :block => blk }
|
|
87
95
|
else
|
|
88
96
|
raise ArgumentError, "args must be an array" unless Array === args
|
|
89
|
-
|
|
97
|
+
|
|
98
|
+
if ENV["MT_KWARGS_HAC\K"] && (Hash === args.last ||
|
|
99
|
+
Hash == args.last) then
|
|
100
|
+
if kwargs.empty? then
|
|
101
|
+
kwargs = args.pop
|
|
102
|
+
else
|
|
103
|
+
unless @@KW_WARNED then
|
|
104
|
+
from = caller(1..1).first
|
|
105
|
+
warn "Using MT_KWARGS_HAC\K yet passing kwargs. From #{from}"
|
|
106
|
+
@@KW_WARNED = true
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
@expected_calls[name] <<
|
|
112
|
+
{ :retval => retval, :args => args, :kwargs => kwargs }
|
|
90
113
|
end
|
|
91
114
|
self
|
|
92
115
|
end
|
|
@@ -94,7 +117,13 @@ module Minitest # :nodoc:
|
|
|
94
117
|
def __call name, data # :nodoc:
|
|
95
118
|
case data
|
|
96
119
|
when Hash then
|
|
97
|
-
|
|
120
|
+
args = data[:args].inspect[1..-2]
|
|
121
|
+
kwargs = data[:kwargs]
|
|
122
|
+
if kwargs && !kwargs.empty? then
|
|
123
|
+
args << ", " unless args.empty?
|
|
124
|
+
args << kwargs.inspect[1..-2]
|
|
125
|
+
end
|
|
126
|
+
"#{name}(#{args}) => #{data[:retval].inspect}"
|
|
98
127
|
else
|
|
99
128
|
data.map { |d| __call name, d }.join ", "
|
|
100
129
|
end
|
|
@@ -107,18 +136,18 @@ module Minitest # :nodoc:
|
|
|
107
136
|
|
|
108
137
|
def verify
|
|
109
138
|
@expected_calls.each do |name, expected|
|
|
110
|
-
actual = @actual_calls.fetch
|
|
111
|
-
raise MockExpectationError, "
|
|
112
|
-
raise MockExpectationError, "
|
|
139
|
+
actual = @actual_calls.fetch name, nil # defaults to []
|
|
140
|
+
raise MockExpectationError, "Expected #{__call name, expected[0]}" unless actual
|
|
141
|
+
raise MockExpectationError, "Expected #{__call name, expected[actual.size]}, got [#{__call name, actual}]" if
|
|
113
142
|
actual.size < expected.size
|
|
114
143
|
end
|
|
115
144
|
true
|
|
116
145
|
end
|
|
117
146
|
|
|
118
|
-
def method_missing sym, *args, &block # :nodoc:
|
|
119
|
-
unless @expected_calls.key?
|
|
147
|
+
def method_missing sym, *args, **kwargs, &block # :nodoc:
|
|
148
|
+
unless @expected_calls.key? sym then
|
|
120
149
|
if @delegator && @delegator.respond_to?(sym)
|
|
121
|
-
return @delegator.public_send(sym, *args, &block)
|
|
150
|
+
return @delegator.public_send(sym, *args, **kwargs, &block)
|
|
122
151
|
else
|
|
123
152
|
raise NoMethodError, "unmocked method %p, expected one of %p" %
|
|
124
153
|
[sym, @expected_calls.keys.sort_by(&:to_s)]
|
|
@@ -129,41 +158,69 @@ module Minitest # :nodoc:
|
|
|
129
158
|
expected_call = @expected_calls[sym][index]
|
|
130
159
|
|
|
131
160
|
unless expected_call then
|
|
132
|
-
raise MockExpectationError, "No more expects available for %p: %p" %
|
|
133
|
-
[sym, args]
|
|
161
|
+
raise MockExpectationError, "No more expects available for %p: %p %p" %
|
|
162
|
+
[sym, args, kwargs]
|
|
134
163
|
end
|
|
135
164
|
|
|
136
|
-
expected_args, retval, val_block =
|
|
137
|
-
expected_call.values_at
|
|
165
|
+
expected_args, expected_kwargs, retval, val_block =
|
|
166
|
+
expected_call.values_at :args, :kwargs, :retval, :block
|
|
167
|
+
|
|
168
|
+
expected_kwargs = kwargs.to_h { |ak, av| [ak, Object] } if
|
|
169
|
+
Hash == expected_kwargs
|
|
138
170
|
|
|
139
171
|
if val_block then
|
|
140
172
|
# keep "verify" happy
|
|
141
173
|
@actual_calls[sym] << expected_call
|
|
142
174
|
|
|
143
|
-
raise MockExpectationError, "mocked method %p failed block w/ %p" %
|
|
144
|
-
[sym, args] unless val_block.call(*args, &block)
|
|
175
|
+
raise MockExpectationError, "mocked method %p failed block w/ %p %p" %
|
|
176
|
+
[sym, args, kwargs] unless val_block.call(*args, **kwargs, &block)
|
|
145
177
|
|
|
146
178
|
return retval
|
|
147
179
|
end
|
|
148
180
|
|
|
149
181
|
if expected_args.size != args.size then
|
|
150
|
-
raise ArgumentError, "mocked method %p expects %d arguments, got %
|
|
151
|
-
[sym, expected_args.size, args
|
|
182
|
+
raise ArgumentError, "mocked method %p expects %d arguments, got %p" %
|
|
183
|
+
[sym, expected_args.size, args]
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
if expected_kwargs.size != kwargs.size then
|
|
187
|
+
raise ArgumentError, "mocked method %p expects %d keyword arguments, got %p" %
|
|
188
|
+
[sym, expected_kwargs.size, kwargs]
|
|
152
189
|
end
|
|
153
190
|
|
|
154
|
-
zipped_args = expected_args.zip
|
|
191
|
+
zipped_args = expected_args.zip args
|
|
155
192
|
fully_matched = zipped_args.all? { |mod, a|
|
|
156
193
|
mod === a or mod == a
|
|
157
194
|
}
|
|
158
195
|
|
|
159
196
|
unless fully_matched then
|
|
160
|
-
|
|
161
|
-
|
|
197
|
+
fmt = "mocked method %p called with unexpected arguments %p"
|
|
198
|
+
raise MockExpectationError, fmt % [sym, args]
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
unless expected_kwargs.keys.sort == kwargs.keys.sort then
|
|
202
|
+
fmt = "mocked method %p called with unexpected keywords %p vs %p"
|
|
203
|
+
raise MockExpectationError, fmt % [sym, expected_kwargs.keys, kwargs.keys]
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
zipped_kwargs = expected_kwargs.to_h { |ek, ev|
|
|
207
|
+
av = kwargs[ek]
|
|
208
|
+
[ek, [ev, av]]
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
fully_matched = zipped_kwargs.all? { |ek, (ev, av)|
|
|
212
|
+
ev === av or ev == av
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
unless fully_matched then
|
|
216
|
+
fmt = "mocked method %p called with unexpected keyword arguments %p vs %p"
|
|
217
|
+
raise MockExpectationError, fmt % [sym, expected_kwargs, kwargs]
|
|
162
218
|
end
|
|
163
219
|
|
|
164
220
|
@actual_calls[sym] << {
|
|
165
221
|
:retval => retval,
|
|
166
|
-
:args
|
|
222
|
+
:args => zipped_args.map { |e, a| e === a ? e : a },
|
|
223
|
+
:kwargs => zipped_kwargs.to_h { |k, (e, a)| [k, e === a ? e : a] },
|
|
167
224
|
}
|
|
168
225
|
|
|
169
226
|
retval
|
|
@@ -172,20 +229,35 @@ module Minitest # :nodoc:
|
|
|
172
229
|
def respond_to? sym, include_private = false # :nodoc:
|
|
173
230
|
return true if @expected_calls.key? sym.to_sym
|
|
174
231
|
return true if @delegator && @delegator.respond_to?(sym, include_private)
|
|
175
|
-
__respond_to?
|
|
232
|
+
__respond_to? sym, include_private
|
|
176
233
|
end
|
|
177
234
|
end
|
|
178
235
|
end
|
|
179
236
|
|
|
180
237
|
module Minitest::Assertions
|
|
181
238
|
##
|
|
182
|
-
# Assert that the mock verifies correctly.
|
|
239
|
+
# Assert that the mock verifies correctly and fail if not.
|
|
183
240
|
|
|
184
|
-
def assert_mock mock
|
|
241
|
+
def assert_mock mock, msg = nil
|
|
185
242
|
assert mock.verify
|
|
243
|
+
rescue MockExpectationError => e
|
|
244
|
+
msg = message(msg) { e.message }
|
|
245
|
+
flunk msg
|
|
186
246
|
end
|
|
187
247
|
end
|
|
188
248
|
|
|
249
|
+
module Minitest::Expectations
|
|
250
|
+
##
|
|
251
|
+
# See Minitest::Assertions#assert_mock.
|
|
252
|
+
#
|
|
253
|
+
# _(collection).must_verify
|
|
254
|
+
#
|
|
255
|
+
# :method: must_verify
|
|
256
|
+
|
|
257
|
+
infect_an_assertion :assert_mock, :must_verify, :unary if
|
|
258
|
+
defined?(infect_an_assertion)
|
|
259
|
+
end
|
|
260
|
+
|
|
189
261
|
##
|
|
190
262
|
# Object extensions for Minitest::Mock.
|
|
191
263
|
|
|
@@ -207,31 +279,46 @@ class Object
|
|
|
207
279
|
# assert obj_under_test.stale?
|
|
208
280
|
# end
|
|
209
281
|
# end
|
|
210
|
-
|
|
282
|
+
#--
|
|
283
|
+
# NOTE: keyword args in callables are NOT checked for correctness
|
|
284
|
+
# against the existing method. Too many edge cases to be worth it.
|
|
211
285
|
|
|
212
|
-
def stub name, val_or_callable, *block_args
|
|
286
|
+
def stub name, val_or_callable, *block_args, **block_kwargs, &block
|
|
213
287
|
new_name = "__minitest_stub__#{name}"
|
|
214
288
|
|
|
215
289
|
metaclass = class << self; self; end
|
|
216
290
|
|
|
217
291
|
if respond_to? name and not methods.map(&:to_s).include? name.to_s then
|
|
218
|
-
metaclass.send :define_method, name do |*args|
|
|
219
|
-
super(*args)
|
|
292
|
+
metaclass.send :define_method, name do |*args, **kwargs|
|
|
293
|
+
super(*args, **kwargs)
|
|
220
294
|
end
|
|
221
295
|
end
|
|
222
296
|
|
|
223
297
|
metaclass.send :alias_method, new_name, name
|
|
224
298
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
val_or_callable.call
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
299
|
+
if ENV["MT_KWARGS_HAC\K"] then
|
|
300
|
+
metaclass.send :define_method, name do |*args, &blk|
|
|
301
|
+
if val_or_callable.respond_to? :call then
|
|
302
|
+
val_or_callable.call(*args, &blk)
|
|
303
|
+
else
|
|
304
|
+
blk.call(*block_args, **block_kwargs) if blk
|
|
305
|
+
val_or_callable
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
else
|
|
309
|
+
metaclass.send :define_method, name do |*args, **kwargs, &blk|
|
|
310
|
+
if val_or_callable.respond_to? :call then
|
|
311
|
+
val_or_callable.call(*args, **kwargs, &blk)
|
|
312
|
+
else
|
|
313
|
+
if blk then
|
|
314
|
+
blk.call(*block_args, **block_kwargs)
|
|
315
|
+
end
|
|
316
|
+
val_or_callable
|
|
317
|
+
end
|
|
231
318
|
end
|
|
232
319
|
end
|
|
233
320
|
|
|
234
|
-
|
|
321
|
+
block[self]
|
|
235
322
|
ensure
|
|
236
323
|
metaclass.send :undef_method, name
|
|
237
324
|
metaclass.send :alias_method, name, new_name
|
data/lib/minitest/parallel.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
require "thread"
|
|
2
|
+
|
|
1
3
|
module Minitest
|
|
2
|
-
module Parallel
|
|
4
|
+
module Parallel # :nodoc:
|
|
3
5
|
|
|
4
6
|
##
|
|
5
7
|
# The engine used to run multiple tests in parallel.
|
|
@@ -16,7 +18,7 @@ module Minitest
|
|
|
16
18
|
|
|
17
19
|
def initialize size
|
|
18
20
|
@size = size
|
|
19
|
-
@queue = Queue.new
|
|
21
|
+
@queue = Thread::Queue.new
|
|
20
22
|
@pool = nil
|
|
21
23
|
end
|
|
22
24
|
|
|
@@ -24,10 +26,10 @@ module Minitest
|
|
|
24
26
|
# Start the executor
|
|
25
27
|
|
|
26
28
|
def start
|
|
27
|
-
@pool = size
|
|
28
|
-
Thread.new
|
|
29
|
+
@pool = Array.new(size) {
|
|
30
|
+
Thread.new @queue do |queue|
|
|
29
31
|
Thread.current.abort_on_exception = true
|
|
30
|
-
while
|
|
32
|
+
while job = queue.pop do
|
|
31
33
|
klass, method, reporter = job
|
|
32
34
|
reporter.synchronize { reporter.prerecord klass, method }
|
|
33
35
|
result = Minitest.run_one_method klass, method
|
data/lib/minitest/pride.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative "../minitest"
|
|
2
2
|
|
|
3
3
|
module Minitest
|
|
4
4
|
def self.plugin_pride_options opts, _options # :nodoc:
|
|
@@ -8,13 +8,13 @@ module Minitest
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def self.plugin_pride_init options # :nodoc:
|
|
11
|
-
|
|
12
|
-
klass = ENV["TERM"] =~ /^xterm|-256color$/ ? PrideLOL : PrideIO
|
|
13
|
-
io = klass.new options[:io]
|
|
11
|
+
return unless PrideIO.pride?
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
klass = ENV["TERM"] =~ /^xterm|-(?:256color|direct)$/ ? PrideLOL : PrideIO
|
|
14
|
+
io = klass.new options[:io]
|
|
15
|
+
|
|
16
|
+
self.reporter.reporters.grep(Minitest::Reporter).each do |rep|
|
|
17
|
+
rep.io = io if rep.io.tty?
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
@@ -48,7 +48,7 @@ module Minitest
|
|
|
48
48
|
def initialize io # :nodoc:
|
|
49
49
|
@io = io
|
|
50
50
|
# stolen from /System/Library/Perl/5.10.0/Term/ANSIColor.pm
|
|
51
|
-
# also reference
|
|
51
|
+
# also reference https://en.wikipedia.org/wiki/ANSI_escape_code
|
|
52
52
|
@colors ||= (31..36).to_a
|
|
53
53
|
@size = @colors.size
|
|
54
54
|
@index = 0
|
|
@@ -59,12 +59,10 @@ module Minitest
|
|
|
59
59
|
|
|
60
60
|
def print o
|
|
61
61
|
case o
|
|
62
|
-
when "." then
|
|
62
|
+
when ".", "S" then
|
|
63
63
|
io.print pride o
|
|
64
64
|
when "E", "F" then
|
|
65
65
|
io.print "#{ESC}41m#{ESC}37m#{o}#{NND}"
|
|
66
|
-
when "S" then
|
|
67
|
-
io.print pride o
|
|
68
66
|
else
|
|
69
67
|
io.print o
|
|
70
68
|
end
|
|
@@ -72,11 +70,9 @@ module Minitest
|
|
|
72
70
|
|
|
73
71
|
def puts *o # :nodoc:
|
|
74
72
|
o.map! { |s|
|
|
75
|
-
s.to_s.sub(
|
|
73
|
+
s.to_s.sub("Finished") {
|
|
76
74
|
@index = 0
|
|
77
|
-
"Fabulous run".
|
|
78
|
-
pride(c)
|
|
79
|
-
}.join
|
|
75
|
+
"Fabulous run".chars.map { |c| pride(c) }.join
|
|
80
76
|
}
|
|
81
77
|
}
|
|
82
78
|
|
|
@@ -113,19 +109,16 @@ module Minitest
|
|
|
113
109
|
#
|
|
114
110
|
# plot (3*sin(x)+3), (3*sin(x+2*pi/3)+3), (3*sin(x+4*pi/3)+3)
|
|
115
111
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
n *= 1.0 / 6
|
|
112
|
+
@colors = Array.new(6 * 7) { |n|
|
|
113
|
+
n *= 1.0 / 3
|
|
119
114
|
r = (3 * Math.sin(n ) + 3).to_i
|
|
120
|
-
g = (3 * Math.sin(n +
|
|
121
|
-
b = (3 * Math.sin(n +
|
|
122
|
-
|
|
123
|
-
# Then we take rgb and encode them in a single number using base 6.
|
|
124
|
-
# For some mysterious reason, we add 16... to clear the bottom 4 bits?
|
|
125
|
-
# Yes... they're ugly.
|
|
115
|
+
g = (3 * Math.sin(n + 4 * PI_3) + 3).to_i
|
|
116
|
+
b = (3 * Math.sin(n + 2 * PI_3) + 3).to_i
|
|
126
117
|
|
|
118
|
+
# Then we take rgb and encode them in a single number using
|
|
119
|
+
# base 6, shifted by 16 for the base 16 ansi colors.
|
|
127
120
|
36 * r + 6 * g + b + 16
|
|
128
|
-
}
|
|
121
|
+
}.rotate(4) # puts "red" first
|
|
129
122
|
|
|
130
123
|
super
|
|
131
124
|
end
|
data/lib/minitest/spec.rb
CHANGED
|
@@ -1,19 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative "test"
|
|
2
2
|
|
|
3
3
|
class Module # :nodoc:
|
|
4
4
|
def infect_an_assertion meth, new_name, dont_flip = false # :nodoc:
|
|
5
5
|
block = dont_flip == :block
|
|
6
6
|
dont_flip = false if block
|
|
7
|
+
target_obj = block ? "_{obj.method}" : "_(obj)"
|
|
8
|
+
|
|
9
|
+
# https://eregon.me/blog/2021/02/13/correct-delegation-in-ruby-2-27-3.html
|
|
10
|
+
# Drop this when we can drop ruby 2.6 (aka after rails 6.1 EOL, ~2024-06)
|
|
11
|
+
kw_extra = "ruby2_keywords %p" % [new_name] if respond_to? :ruby2_keywords, true
|
|
7
12
|
|
|
8
13
|
# warn "%-22p -> %p %p" % [meth, new_name, dont_flip]
|
|
9
14
|
self.class_eval <<-EOM, __FILE__, __LINE__ + 1
|
|
10
15
|
def #{new_name} *args
|
|
16
|
+
where = Minitest.filter_backtrace(caller).first
|
|
17
|
+
where = where.split(/:in /, 2).first # clean up noise
|
|
18
|
+
Kernel.warn "DEPRECATED: global use of #{new_name} from #\{where}. Use #{target_obj}.#{new_name} instead. This will fail in Minitest 6."
|
|
11
19
|
Minitest::Expectation.new(self, Minitest::Spec.current).#{new_name}(*args)
|
|
12
20
|
end
|
|
21
|
+
#{kw_extra}
|
|
13
22
|
EOM
|
|
14
23
|
|
|
15
24
|
Minitest::Expectation.class_eval <<-EOM, __FILE__, __LINE__ + 1
|
|
16
25
|
def #{new_name} *args
|
|
26
|
+
raise "Calling ##{new_name} outside of test." unless ctx
|
|
17
27
|
case
|
|
18
28
|
when #{!!dont_flip} then
|
|
19
29
|
ctx.#{meth}(target, *args)
|
|
@@ -23,11 +33,16 @@ class Module # :nodoc:
|
|
|
23
33
|
ctx.#{meth}(args.first, target, *args[1..-1])
|
|
24
34
|
end
|
|
25
35
|
end
|
|
36
|
+
#{kw_extra}
|
|
26
37
|
EOM
|
|
27
38
|
end
|
|
28
39
|
end
|
|
29
40
|
|
|
30
|
-
|
|
41
|
+
# :stopdoc:
|
|
42
|
+
module Minitest # fucking hell rdoc...
|
|
43
|
+
Expectation = Struct.new :target, :ctx
|
|
44
|
+
end
|
|
45
|
+
# :startdoc:
|
|
31
46
|
|
|
32
47
|
##
|
|
33
48
|
# Kernel extensions for minitest
|
|
@@ -61,7 +76,7 @@ module Kernel
|
|
|
61
76
|
#
|
|
62
77
|
# For some suggestions on how to improve your specs, try:
|
|
63
78
|
#
|
|
64
|
-
#
|
|
79
|
+
# https://betterspecs.org
|
|
65
80
|
#
|
|
66
81
|
# but do note that several items there are debatable or specific to
|
|
67
82
|
# rspec.
|
|
@@ -70,14 +85,15 @@ module Kernel
|
|
|
70
85
|
|
|
71
86
|
def describe desc, *additional_desc, &block # :doc:
|
|
72
87
|
stack = Minitest::Spec.describe_stack
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
88
|
+
is_spec_class = Class === self && kind_of?(Minitest::Spec::DSL)
|
|
89
|
+
name = [stack.last, desc, *additional_desc]
|
|
90
|
+
name.prepend self if stack.empty? && is_spec_class
|
|
91
|
+
sclas =
|
|
92
|
+
stack.last \
|
|
93
|
+
|| (is_spec_class && self) \
|
|
94
|
+
|| Minitest::Spec.spec_type(desc, *additional_desc)
|
|
79
95
|
|
|
80
|
-
cls = sclas.create name, desc
|
|
96
|
+
cls = sclas.create name.compact.join("::"), desc
|
|
81
97
|
|
|
82
98
|
stack.push cls
|
|
83
99
|
cls.class_eval(&block)
|
|
@@ -238,7 +254,7 @@ class Minitest::Spec < Minitest::Test
|
|
|
238
254
|
pre, post = "let '#{name}' cannot ", ". Please use another name."
|
|
239
255
|
methods = Minitest::Spec.instance_methods.map(&:to_s) - %w[subject]
|
|
240
256
|
raise ArgumentError, "#{pre}begin with 'test'#{post}" if
|
|
241
|
-
name
|
|
257
|
+
name.start_with? "test"
|
|
242
258
|
raise ArgumentError, "#{pre}override a method in Minitest::Spec#{post}" if
|
|
243
259
|
methods.include? name
|
|
244
260
|
|
|
@@ -257,7 +273,7 @@ class Minitest::Spec < Minitest::Test
|
|
|
257
273
|
end
|
|
258
274
|
|
|
259
275
|
def create name, desc # :nodoc:
|
|
260
|
-
cls = Class.new
|
|
276
|
+
cls = Class.new self do
|
|
261
277
|
@name = name
|
|
262
278
|
@desc = desc
|
|
263
279
|
|
|
@@ -273,33 +289,39 @@ class Minitest::Spec < Minitest::Test
|
|
|
273
289
|
defined?(@name) ? @name : super
|
|
274
290
|
end
|
|
275
291
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
end
|
|
292
|
+
alias to_s name
|
|
293
|
+
alias inspect name
|
|
279
294
|
|
|
280
295
|
attr_reader :desc # :nodoc:
|
|
281
|
-
alias
|
|
296
|
+
alias specify it
|
|
282
297
|
|
|
283
298
|
##
|
|
284
299
|
# Rdoc... why are you so dumb?
|
|
285
300
|
|
|
286
301
|
module InstanceMethods
|
|
287
302
|
##
|
|
288
|
-
#
|
|
289
|
-
# available to it.
|
|
303
|
+
# Takes a value or a block and returns a value monad that has
|
|
304
|
+
# all of Expectations methods available to it.
|
|
290
305
|
#
|
|
291
|
-
#
|
|
306
|
+
# _(1 + 1).must_equal 2
|
|
292
307
|
#
|
|
293
|
-
#
|
|
294
|
-
#
|
|
295
|
-
#
|
|
308
|
+
# And for blocks:
|
|
309
|
+
#
|
|
310
|
+
# _ { 1 + "1" }.must_raise TypeError
|
|
296
311
|
#
|
|
297
312
|
# This method of expectation-based testing is preferable to
|
|
298
313
|
# straight-expectation methods (on Object) because it stores its
|
|
299
314
|
# test context, bypassing our hacky use of thread-local variables.
|
|
300
315
|
#
|
|
301
|
-
# At some point, the methods on Object will be deprecated
|
|
302
|
-
# removed.
|
|
316
|
+
# NOTE: At some point, the methods on Object will be deprecated
|
|
317
|
+
# and then removed.
|
|
318
|
+
#
|
|
319
|
+
# It is also aliased to #value and #expect for your aesthetic
|
|
320
|
+
# pleasure:
|
|
321
|
+
#
|
|
322
|
+
# _(1 + 1).must_equal 2
|
|
323
|
+
# value(1 + 1).must_equal 2
|
|
324
|
+
# expect(1 + 1).must_equal 2
|
|
303
325
|
|
|
304
326
|
def _ value = nil, &block
|
|
305
327
|
Minitest::Expectation.new block || value, self
|
|
@@ -324,7 +346,7 @@ class Minitest::Spec < Minitest::Test
|
|
|
324
346
|
TYPES = DSL::TYPES # :nodoc:
|
|
325
347
|
end
|
|
326
348
|
|
|
327
|
-
|
|
349
|
+
require_relative "expectations"
|
|
328
350
|
|
|
329
351
|
class Object # :nodoc:
|
|
330
352
|
include Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
|