minitest 5.15.0 → 5.17.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 +63 -0
- data/Manifest.txt +2 -0
- data/README.rdoc +56 -28
- data/Rakefile +1 -1
- data/lib/minitest/assertions.rb +2 -0
- data/lib/minitest/benchmark.rb +5 -5
- data/lib/minitest/mock.rb +116 -33
- data/lib/minitest/pride_plugin.rb +1 -1
- data/lib/minitest/spec.rb +7 -1
- data/lib/minitest/test.rb +36 -10
- data/lib/minitest/test_task.rb +305 -0
- data/lib/minitest/unit.rb +5 -8
- data/lib/minitest.rb +31 -22
- data/test/minitest/metametameta.rb +1 -1
- data/test/minitest/test_minitest_assertions.rb +10 -7
- data/test/minitest/test_minitest_benchmark.rb +2 -2
- data/test/minitest/test_minitest_mock.rb +268 -7
- data/test/minitest/test_minitest_reporter.rb +1 -0
- data/test/minitest/test_minitest_spec.rb +57 -14
- data/test/minitest/test_minitest_test.rb +186 -23
- data/test/minitest/test_minitest_test_task.rb +46 -0
- data.tar.gz.sig +0 -0
- metadata +16 -14
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76379897c6c77174044638d17a95f50b1b2fddbfde053759d864d8b9b419984b
|
4
|
+
data.tar.gz: 7cdedb3e76825894a5577f2c639c541402e1955b1166221530e2937b6c605b81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5bc0b4b036c2e07d3db6ace79c1d0e51d2aa5cac74a26174ec822f1f987882bffc0165650c86f168ee38b31e9f07d825730b20a1f13b704fc395a9a88a4d9060
|
7
|
+
data.tar.gz: e9bdf26bc5a327b72b7a1dbdf701f6cef70561b634a258f932c511f26e7f2886597a05cc4a964749ef16e32529ab6a0cb6d11601f2954c3830444d34c3fcb23b
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/History.rdoc
CHANGED
@@ -1,3 +1,66 @@
|
|
1
|
+
=== 5.17.0 / 2022-12-31
|
2
|
+
|
3
|
+
* 1 minor enhancement:
|
4
|
+
|
5
|
+
* Refactor setup hooks into a SETUP_METHODS constant. (MSP-Greg)
|
6
|
+
|
7
|
+
* 3 bug fixes:
|
8
|
+
|
9
|
+
* Fix kwargs for Mock calls to delegator. (blowmage)
|
10
|
+
* Fix kwargs for expectations. (bobmazanec, blowmage)
|
11
|
+
* Remove check for .b method. (tenderlove)
|
12
|
+
|
13
|
+
=== 5.16.3 / 2022-08-17
|
14
|
+
|
15
|
+
* 2 bug fixes:
|
16
|
+
|
17
|
+
* Fixed exception sanitization by removing TypeError restriction on rescue.
|
18
|
+
* Use A instead of deprecated TESTOPTS in rake test:slow. (davidstosik)
|
19
|
+
|
20
|
+
=== 5.16.2 / 2022-07-03
|
21
|
+
|
22
|
+
* 4 bug fixes:
|
23
|
+
|
24
|
+
* Added MT_KWARGS_HACK kludge for stub to deal with ruby 2.7 kwargs nastiness. (tsugimoto)
|
25
|
+
* In #expect, pop Hash class from args if $MT_KWARGS_HACK. (casperisfine)
|
26
|
+
* In above scenario, set expected kwargs (as Objects) based on actual kwargs.
|
27
|
+
* Nuke ivars if exception fails to marshal twice (eg better_errors). (irphilli)
|
28
|
+
|
29
|
+
=== 5.16.1 / 2022-06-20
|
30
|
+
|
31
|
+
* 2 bug fixes:
|
32
|
+
|
33
|
+
* Apparently adding real kwarg support to mocks/stubs broke some code. Fixed.
|
34
|
+
* Use `MT_KWARGS_HACK=1` to activate the kludgy kwargs support w/ caveats.
|
35
|
+
* Clarified some doco wrt the block on #stub.
|
36
|
+
|
37
|
+
=== 5.16.0 / 2022-06-14
|
38
|
+
|
39
|
+
* 2 major enhancements:
|
40
|
+
|
41
|
+
* Added Minitest::TestTask.
|
42
|
+
* Dropping ruby 2.2 - 2.5. 2.6 is DTM soon too.
|
43
|
+
|
44
|
+
* 11 minor enhancements:
|
45
|
+
|
46
|
+
* Added --show-skips option to show skips at end of run but not require --verbose. (MSP-Greg)
|
47
|
+
* Added Minitest.seed, the random seed used by the run.
|
48
|
+
* Calling `srand Minitest.seed` before all shuffles to ensure determinism.
|
49
|
+
* Extended #stub to handle kwargs for both block and call args. (SampsonCrowley)
|
50
|
+
* Extended Mock#__call to display kwargs.
|
51
|
+
* Extended Mock#expect to record kwargs.
|
52
|
+
* Extended Mock#method_missing to take kwargs & compare them against expected.
|
53
|
+
* Mock#method_missing displays better errors on arity mismatch.
|
54
|
+
* Removed minor optimization removing empty suites before run.
|
55
|
+
* Simplified test randomization (test order will change even with fixed seed).
|
56
|
+
* assert_match now returns the MatchData on success. (Nakilon)
|
57
|
+
|
58
|
+
* 3 bug fixes:
|
59
|
+
|
60
|
+
* (Re)Fixed marshalling of exceptions, neutering them in 2 passes.
|
61
|
+
* Fixed more problems with rdoc.
|
62
|
+
* Had to patch up mock and stub to deal with <=2.7 kwargs oddities
|
63
|
+
|
1
64
|
=== 5.15.0 / 2021-12-14
|
2
65
|
|
3
66
|
* 1 major enhancement:
|
data/Manifest.txt
CHANGED
@@ -17,6 +17,7 @@ lib/minitest/pride.rb
|
|
17
17
|
lib/minitest/pride_plugin.rb
|
18
18
|
lib/minitest/spec.rb
|
19
19
|
lib/minitest/test.rb
|
20
|
+
lib/minitest/test_task.rb
|
20
21
|
lib/minitest/unit.rb
|
21
22
|
test/minitest/metametameta.rb
|
22
23
|
test/minitest/test_minitest_assertions.rb
|
@@ -25,3 +26,4 @@ test/minitest/test_minitest_mock.rb
|
|
25
26
|
test/minitest/test_minitest_reporter.rb
|
26
27
|
test/minitest/test_minitest_spec.rb
|
27
28
|
test/minitest/test_minitest_test.rb
|
29
|
+
test/minitest/test_minitest_test_task.rb
|
data/README.rdoc
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
home :: https://github.com/seattlerb/minitest
|
4
4
|
bugs :: https://github.com/seattlerb/minitest/issues
|
5
|
-
rdoc ::
|
5
|
+
rdoc :: https://docs.seattlerb.org/minitest
|
6
6
|
vim :: https://github.com/sunaku/vim-ruby-minitest
|
7
7
|
emacs:: https://github.com/arthurnn/minitest-emacs
|
8
8
|
|
@@ -70,6 +70,7 @@ extract-method refactorings still apply.
|
|
70
70
|
* minitest/mock - a simple and clean mock/stub system.
|
71
71
|
* minitest/benchmark - an awesome way to assert your algorithm's performance.
|
72
72
|
* minitest/pride - show your pride in testing!
|
73
|
+
* minitest/test_task - a full-featured and clean rake task generator.
|
73
74
|
* Incredibly small and fast runner, but no bells and whistles.
|
74
75
|
* Written by squishy human beings. Software can never be perfect. We will all eventually die.
|
75
76
|
|
@@ -186,7 +187,7 @@ Output is tab-delimited to make it easy to paste into a spreadsheet.
|
|
186
187
|
=== Mocks
|
187
188
|
|
188
189
|
Mocks and stubs defined using terminology by Fowler & Meszaros at
|
189
|
-
|
190
|
+
https://www.martinfowler.com/bliki/TestDouble.html:
|
190
191
|
|
191
192
|
"Mocks are pre-programmed with expectations which form a specification
|
192
193
|
of the calls they are expected to receive. They can throw an exception
|
@@ -237,7 +238,7 @@ an example of asserting that code inside a thread is run:
|
|
237
238
|
=== Stubs
|
238
239
|
|
239
240
|
Mocks and stubs are defined using terminology by Fowler & Meszaros at
|
240
|
-
|
241
|
+
https://www.martinfowler.com/bliki/TestDouble.html:
|
241
242
|
|
242
243
|
"Stubs provide canned answers to calls made during the test".
|
243
244
|
|
@@ -264,9 +265,8 @@ new non-existing method:
|
|
264
265
|
|
265
266
|
=== Running Your Tests
|
266
267
|
|
267
|
-
Ideally, you'll use a rake task to run your tests, either
|
268
|
-
all at once.
|
269
|
-
tests. BUT! You don't have to:
|
268
|
+
Ideally, you'll use a rake task to run your tests (see below), either
|
269
|
+
piecemeal or all at once. BUT! You don't have to:
|
270
270
|
|
271
271
|
% ruby -Ilib:test test/minitest/test_minitest_test.rb
|
272
272
|
Run options: --seed 37685
|
@@ -294,18 +294,45 @@ provided via plugins. To see them, simply run with +--help+:
|
|
294
294
|
-p, --pride Pride. Show your testing pride!
|
295
295
|
-a, --autotest Connect to autotest server.
|
296
296
|
|
297
|
+
=== Rake Tasks
|
298
|
+
|
297
299
|
You can set up a rake task to run all your tests by adding this to your Rakefile:
|
298
300
|
|
299
|
-
require "
|
301
|
+
require "minitest/test_task"
|
302
|
+
|
303
|
+
Minitest::TestTask.create # named test, sensible defaults
|
300
304
|
|
301
|
-
|
305
|
+
# or more explicitly:
|
306
|
+
|
307
|
+
Minitest::TestTask.create(:test) do |t|
|
302
308
|
t.libs << "test"
|
303
309
|
t.libs << "lib"
|
304
|
-
t.
|
310
|
+
t.warning = false
|
311
|
+
t.test_globs = ["test/**/*_test.rb"]
|
305
312
|
end
|
306
313
|
|
307
314
|
task :default => :test
|
308
315
|
|
316
|
+
Each of these will generate 4 tasks:
|
317
|
+
|
318
|
+
rake test :: Run the test suite.
|
319
|
+
rake test:cmd :: Print out the test command.
|
320
|
+
rake test:isolated :: Show which test files fail when run separately.
|
321
|
+
rake test:slow :: Show bottom 25 tests sorted by time.
|
322
|
+
|
323
|
+
=== Rake Task Variables
|
324
|
+
|
325
|
+
There are a bunch of variables you can supply to rake to modify the run.
|
326
|
+
|
327
|
+
MT_LIB_EXTRAS :: Extra libs to dynamically override/inject for custom runs.
|
328
|
+
N :: -n: Tests to run (string or /regexp/).
|
329
|
+
X :: -x: Tests to exclude (string or /regexp/).
|
330
|
+
A :: Any extra arguments. Honors shell quoting.
|
331
|
+
MT_CPU :: How many threads to use for parallel test runs
|
332
|
+
SEED :: -s --seed Sets random seed.
|
333
|
+
TESTOPTS :: Deprecated, same as A
|
334
|
+
FILTER :: Deprecated, same as A
|
335
|
+
|
309
336
|
== Writing Extensions
|
310
337
|
|
311
338
|
To define a plugin, add a file named minitest/XXX_plugin.rb to your
|
@@ -380,37 +407,34 @@ Using our example above, here is how we might implement MyCI:
|
|
380
407
|
|
381
408
|
Minitest is a dependency of rails, which until fairly recently had an
|
382
409
|
overzealous backwards compatibility policy. As such, I'm stuck
|
383
|
-
supporting versions of ruby that are long past EOL.
|
384
|
-
|
385
|
-
|
410
|
+
supporting versions of ruby that are long past EOL. Hopefully I'll be
|
411
|
+
able to support only current versions of ruby sometime in the near
|
412
|
+
future.
|
386
413
|
|
387
|
-
(As of
|
414
|
+
(As of 2022-11-29)
|
388
415
|
|
389
416
|
Current versions of rails: (https://endoflife.date/rails)
|
390
417
|
|
391
|
-
| rails | min ruby | rec ruby | minitest | status |
|
392
|
-
|
393
|
-
| 7.0 | >= 2.7 | 3.
|
394
|
-
| 6.1 | >= 2.5 | 3.0 | >= 5.1 |
|
395
|
-
| 6.0 | >= 2.5 | 2.6 | >= 5.1 | Security |
|
396
|
-
| 5.2 | >= 2.2.2 | 2.5 | ~> 5.1 |
|
418
|
+
| rails | min ruby | rec ruby | minitest | status | EOL Date |
|
419
|
+
|-------+----------+----------+----------+----------+------------|
|
420
|
+
| 7.0 | >= 2.7 | 3.1 | >= 5.1 | Current | 2025-06-01?|
|
421
|
+
| 6.1 | >= 2.5 | 3.0 | >= 5.1 | Maint | 2024-06-01?|
|
422
|
+
| 6.0 | >= 2.5 | 2.6 | >= 5.1 | Security | 2023-06-01 |
|
423
|
+
| 5.2 | >= 2.2.2 | 2.5 | ~> 5.1 | EOL | 2022-06-01 |
|
397
424
|
|
398
425
|
Current versions of ruby: (https://endoflife.date/ruby)
|
399
426
|
|
400
427
|
| ruby | Status | EOL Date |
|
401
428
|
|------+---------+------------|
|
402
|
-
| 3.
|
403
|
-
|
|
404
|
-
| 2.
|
429
|
+
| 3.1 | Current | 2025-12-25 |
|
430
|
+
| 3.0 | Maint | 2024-03-31 |
|
431
|
+
| 2.7 | Maint* | 2023-03-31 |
|
432
|
+
| 2.6 | EOL | 2022-03-31 |
|
405
433
|
| 2.5 | EOL | 2021-03-31 |
|
406
|
-
| 2.4 | EOL | 2020-03-31 |
|
407
|
-
| 2.3 | EOL | 2019-03-31 |
|
408
|
-
| 2.2 | EOL | 2018-03-31 |
|
409
434
|
|
410
435
|
See also:
|
411
436
|
|
412
437
|
* https://www.fastruby.io/blog/ruby/rails/versions/compatibility-table.html
|
413
|
-
* https://jamesjeffersconsulting.com/ruby-rails-version-matrix/
|
414
438
|
|
415
439
|
=== How to test SimpleDelegates?
|
416
440
|
|
@@ -614,6 +638,7 @@ minitest-capistrano :: Assertions and expectations for testing
|
|
614
638
|
Capistrano recipes.
|
615
639
|
minitest-capybara :: Capybara matchers support for minitest unit and
|
616
640
|
spec.
|
641
|
+
minitest-cc :: It provides minimal information about code coverage.
|
617
642
|
minitest-chef-handler :: Run Minitest suites as Chef report handlers
|
618
643
|
minitest-ci :: CI reporter plugin for Minitest.
|
619
644
|
minitest-context :: Defines contexts for code reuse in Minitest
|
@@ -712,7 +737,7 @@ minitest-stub-const :: Stub constants for the duration of a block.
|
|
712
737
|
minitest-tags :: Add tags for minitest.
|
713
738
|
minitest-unordered :: Adds a new assertion to minitest for checking the
|
714
739
|
contents of a collection, ignoring element order.
|
715
|
-
minitest-vcr :: Automatic cassette
|
740
|
+
minitest-vcr :: Automatic cassette management with Minitest::Spec
|
716
741
|
and VCR.
|
717
742
|
minitest_log :: Adds structured logging, data explication, and verdicts.
|
718
743
|
minitest_owrapper :: Get tests results as a TestResult object.
|
@@ -726,6 +751,9 @@ rematch :: Declutter your test files from large hardcoded da
|
|
726
751
|
and update them automatically when your code changes.
|
727
752
|
rspec2minitest :: Easily translate any RSpec matchers to Minitest
|
728
753
|
assertions and expectations.
|
754
|
+
stubberry :: Multiple stubbing 'berries', sweet and useful
|
755
|
+
stub helpers and assertions. ( stub_must,
|
756
|
+
assert_method_called, stubbing ORM objects by id )
|
729
757
|
|
730
758
|
== Unknown Extensions:
|
731
759
|
|
@@ -751,7 +779,7 @@ Authors... Please send me a pull request with a description of your minitest ext
|
|
751
779
|
|
752
780
|
== Minitest related goods
|
753
781
|
|
754
|
-
* minitest/pride fabric:
|
782
|
+
* minitest/pride fabric: https://www.spoonflower.com/fabric/3928730-again-by-katie_allen
|
755
783
|
|
756
784
|
== REQUIREMENTS:
|
757
785
|
|
data/Rakefile
CHANGED
data/lib/minitest/assertions.rb
CHANGED
data/lib/minitest/benchmark.rb
CHANGED
@@ -217,7 +217,7 @@ module Minitest
|
|
217
217
|
##
|
218
218
|
# Takes an array of x/y pairs and calculates the general R^2 value.
|
219
219
|
#
|
220
|
-
# See:
|
220
|
+
# See: https://en.wikipedia.org/wiki/Coefficient_of_determination
|
221
221
|
|
222
222
|
def fit_error xys
|
223
223
|
y_bar = sigma(xys) { |_, y| y } / xys.size.to_f
|
@@ -232,7 +232,7 @@ module Minitest
|
|
232
232
|
#
|
233
233
|
# Takes x and y values and returns [a, b, r^2].
|
234
234
|
#
|
235
|
-
# See:
|
235
|
+
# See: https://mathworld.wolfram.com/LeastSquaresFittingExponential.html
|
236
236
|
|
237
237
|
def fit_exponential xs, ys
|
238
238
|
n = xs.size
|
@@ -254,7 +254,7 @@ module Minitest
|
|
254
254
|
#
|
255
255
|
# Takes x and y values and returns [a, b, r^2].
|
256
256
|
#
|
257
|
-
# See:
|
257
|
+
# See: https://mathworld.wolfram.com/LeastSquaresFittingLogarithmic.html
|
258
258
|
|
259
259
|
def fit_logarithmic xs, ys
|
260
260
|
n = xs.size
|
@@ -276,7 +276,7 @@ module Minitest
|
|
276
276
|
#
|
277
277
|
# Takes x and y values and returns [a, b, r^2].
|
278
278
|
#
|
279
|
-
# See:
|
279
|
+
# See: https://mathworld.wolfram.com/LeastSquaresFitting.html
|
280
280
|
|
281
281
|
def fit_linear xs, ys
|
282
282
|
n = xs.size
|
@@ -298,7 +298,7 @@ module Minitest
|
|
298
298
|
#
|
299
299
|
# Takes x and y values and returns [a, b, r^2].
|
300
300
|
#
|
301
|
-
# See:
|
301
|
+
# See: https://mathworld.wolfram.com/LeastSquaresFittingPowerLaw.html
|
302
302
|
|
303
303
|
def fit_power xs, ys
|
304
304
|
n = xs.size
|
data/lib/minitest/mock.rb
CHANGED
@@ -28,11 +28,19 @@ module Minitest # :nodoc:
|
|
28
28
|
end
|
29
29
|
|
30
30
|
overridden_methods.map(&:to_sym).each do |method_id|
|
31
|
-
define_method method_id do |*args, &b|
|
31
|
+
define_method method_id do |*args, **kwargs, &b|
|
32
32
|
if @expected_calls.key? method_id then
|
33
|
-
|
33
|
+
if kwargs.empty? then # FIX: drop this after 2.7 dead
|
34
|
+
method_missing(method_id, *args, &b)
|
35
|
+
else
|
36
|
+
method_missing(method_id, *args, **kwargs, &b)
|
37
|
+
end
|
34
38
|
else
|
35
|
-
|
39
|
+
if kwargs.empty? then # FIX: drop this after 2.7 dead
|
40
|
+
super(*args, &b)
|
41
|
+
else
|
42
|
+
super(*args, **kwargs, &b)
|
43
|
+
end
|
36
44
|
end
|
37
45
|
end
|
38
46
|
end
|
@@ -43,9 +51,11 @@ module Minitest # :nodoc:
|
|
43
51
|
@actual_calls = Hash.new { |calls, name| calls[name] = [] }
|
44
52
|
end
|
45
53
|
|
54
|
+
@@KW_WARNED = false # :nodoc:
|
55
|
+
|
46
56
|
##
|
47
|
-
# Expect that method +name+ is called, optionally with +args+
|
48
|
-
# +blk+, and returns +retval+.
|
57
|
+
# Expect that method +name+ is called, optionally with +args+ (and
|
58
|
+
# +kwargs+ or a +blk+, and returns +retval+.
|
49
59
|
#
|
50
60
|
# @mock.expect(:meaning_of_life, 42)
|
51
61
|
# @mock.meaning_of_life # => 42
|
@@ -78,15 +88,31 @@ module Minitest # :nodoc:
|
|
78
88
|
# @mock.ordinal_increment # => raises MockExpectationError "No more expects available for :ordinal_increment"
|
79
89
|
#
|
80
90
|
|
81
|
-
def expect name, retval, args = [], &blk
|
91
|
+
def expect name, retval, args = [], **kwargs, &blk
|
82
92
|
name = name.to_sym
|
83
93
|
|
84
94
|
if block_given?
|
85
95
|
raise ArgumentError, "args ignored when block given" unless args.empty?
|
96
|
+
raise ArgumentError, "kwargs ignored when block given" unless kwargs.empty?
|
86
97
|
@expected_calls[name] << { :retval => retval, :block => blk }
|
87
98
|
else
|
88
99
|
raise ArgumentError, "args must be an array" unless Array === args
|
89
|
-
|
100
|
+
|
101
|
+
if ENV["MT_KWARGS_HAC\K"] && (Hash === args.last ||
|
102
|
+
Hash == args.last) then
|
103
|
+
if kwargs.empty? then
|
104
|
+
kwargs = args.pop
|
105
|
+
else
|
106
|
+
unless @@KW_WARNED then
|
107
|
+
from = caller.first
|
108
|
+
warn "Using MT_KWARGS_HAC\K yet passing kwargs. From #{from}"
|
109
|
+
@@KW_WARNED = true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
@expected_calls[name] <<
|
115
|
+
{ :retval => retval, :args => args, :kwargs => kwargs }
|
90
116
|
end
|
91
117
|
self
|
92
118
|
end
|
@@ -94,7 +120,13 @@ module Minitest # :nodoc:
|
|
94
120
|
def __call name, data # :nodoc:
|
95
121
|
case data
|
96
122
|
when Hash then
|
97
|
-
|
123
|
+
args = data[:args].inspect[1..-2]
|
124
|
+
kwargs = data[:kwargs]
|
125
|
+
if kwargs && !kwargs.empty? then
|
126
|
+
args << ", " unless args.empty?
|
127
|
+
args << kwargs.inspect[1..-2]
|
128
|
+
end
|
129
|
+
"#{name}(#{args}) => #{data[:retval].inspect}"
|
98
130
|
else
|
99
131
|
data.map { |d| __call name, d }.join ", "
|
100
132
|
end
|
@@ -115,10 +147,14 @@ module Minitest # :nodoc:
|
|
115
147
|
true
|
116
148
|
end
|
117
149
|
|
118
|
-
def method_missing sym, *args, &block # :nodoc:
|
150
|
+
def method_missing sym, *args, **kwargs, &block # :nodoc:
|
119
151
|
unless @expected_calls.key?(sym) then
|
120
152
|
if @delegator && @delegator.respond_to?(sym)
|
121
|
-
|
153
|
+
if kwargs.empty? then # FIX: drop this after 2.7 dead
|
154
|
+
return @delegator.public_send(sym, *args, &block)
|
155
|
+
else
|
156
|
+
return @delegator.public_send(sym, *args, **kwargs, &block)
|
157
|
+
end
|
122
158
|
else
|
123
159
|
raise NoMethodError, "unmocked method %p, expected one of %p" %
|
124
160
|
[sym, @expected_calls.keys.sort_by(&:to_s)]
|
@@ -129,26 +165,34 @@ module Minitest # :nodoc:
|
|
129
165
|
expected_call = @expected_calls[sym][index]
|
130
166
|
|
131
167
|
unless expected_call then
|
132
|
-
raise MockExpectationError, "No more expects available for %p: %p" %
|
133
|
-
[sym, args]
|
168
|
+
raise MockExpectationError, "No more expects available for %p: %p %p" %
|
169
|
+
[sym, args, kwargs]
|
134
170
|
end
|
135
171
|
|
136
|
-
expected_args, retval, val_block =
|
137
|
-
expected_call.values_at(:args, :retval, :block)
|
172
|
+
expected_args, expected_kwargs, retval, val_block =
|
173
|
+
expected_call.values_at(:args, :kwargs, :retval, :block)
|
174
|
+
|
175
|
+
expected_kwargs = kwargs.map { |ak, av| [ak, Object] }.to_h if
|
176
|
+
Hash == expected_kwargs
|
138
177
|
|
139
178
|
if val_block then
|
140
179
|
# keep "verify" happy
|
141
180
|
@actual_calls[sym] << expected_call
|
142
181
|
|
143
|
-
raise MockExpectationError, "mocked method %p failed block w/ %p" %
|
144
|
-
[sym, args] unless val_block.call(*args, &block)
|
182
|
+
raise MockExpectationError, "mocked method %p failed block w/ %p %p" %
|
183
|
+
[sym, args, kwargs] unless val_block.call(*args, **kwargs, &block)
|
145
184
|
|
146
185
|
return retval
|
147
186
|
end
|
148
187
|
|
149
188
|
if expected_args.size != args.size then
|
150
|
-
raise ArgumentError, "mocked method %p expects %d arguments, got %
|
151
|
-
[sym, expected_args.size, args
|
189
|
+
raise ArgumentError, "mocked method %p expects %d arguments, got %p" %
|
190
|
+
[sym, expected_args.size, args]
|
191
|
+
end
|
192
|
+
|
193
|
+
if expected_kwargs.size != kwargs.size then
|
194
|
+
raise ArgumentError, "mocked method %p expects %d keyword arguments, got %p" %
|
195
|
+
[sym, expected_kwargs.size, kwargs]
|
152
196
|
end
|
153
197
|
|
154
198
|
zipped_args = expected_args.zip(args)
|
@@ -157,13 +201,33 @@ module Minitest # :nodoc:
|
|
157
201
|
}
|
158
202
|
|
159
203
|
unless fully_matched then
|
160
|
-
|
161
|
-
|
204
|
+
fmt = "mocked method %p called with unexpected arguments %p"
|
205
|
+
raise MockExpectationError, fmt % [sym, args]
|
206
|
+
end
|
207
|
+
|
208
|
+
unless expected_kwargs.keys.sort == kwargs.keys.sort then
|
209
|
+
fmt = "mocked method %p called with unexpected keywords %p vs %p"
|
210
|
+
raise MockExpectationError, fmt % [sym, expected_kwargs.keys, kwargs.keys]
|
211
|
+
end
|
212
|
+
|
213
|
+
zipped_kwargs = expected_kwargs.map { |ek, ev|
|
214
|
+
av = kwargs[ek]
|
215
|
+
[ek, [ev, av]]
|
216
|
+
}.to_h
|
217
|
+
|
218
|
+
fully_matched = zipped_kwargs.all? { |ek, (ev, av)|
|
219
|
+
ev === av or ev == av
|
220
|
+
}
|
221
|
+
|
222
|
+
unless fully_matched then
|
223
|
+
fmt = "mocked method %p called with unexpected keyword arguments %p vs %p"
|
224
|
+
raise MockExpectationError, fmt % [sym, expected_kwargs, kwargs]
|
162
225
|
end
|
163
226
|
|
164
227
|
@actual_calls[sym] << {
|
165
228
|
:retval => retval,
|
166
|
-
:args => zipped_args.map
|
229
|
+
:args => zipped_args.map { |e, a| e === a ? e : a },
|
230
|
+
:kwargs => zipped_kwargs.map { |k, (e, a)| [k, e === a ? e : a] }.to_h,
|
167
231
|
}
|
168
232
|
|
169
233
|
retval
|
@@ -211,31 +275,50 @@ class Object
|
|
211
275
|
# NOTE: keyword args in callables are NOT checked for correctness
|
212
276
|
# against the existing method. Too many edge cases to be worth it.
|
213
277
|
|
214
|
-
def stub name, val_or_callable, *block_args
|
278
|
+
def stub name, val_or_callable, *block_args, **block_kwargs, &block
|
215
279
|
new_name = "__minitest_stub__#{name}"
|
216
280
|
|
217
281
|
metaclass = class << self; self; end
|
218
282
|
|
219
283
|
if respond_to? name and not methods.map(&:to_s).include? name.to_s then
|
220
|
-
metaclass.send :define_method, name do |*args|
|
221
|
-
super(*args)
|
284
|
+
metaclass.send :define_method, name do |*args, **kwargs|
|
285
|
+
super(*args, **kwargs)
|
222
286
|
end
|
223
287
|
end
|
224
288
|
|
225
289
|
metaclass.send :alias_method, new_name, name
|
226
290
|
|
227
|
-
|
228
|
-
|
229
|
-
val_or_callable.call
|
230
|
-
|
231
|
-
|
232
|
-
|
291
|
+
if ENV["MT_KWARGS_HAC\K"] then
|
292
|
+
metaclass.send :define_method, name do |*args, &blk|
|
293
|
+
if val_or_callable.respond_to? :call then
|
294
|
+
val_or_callable.call(*args, &blk)
|
295
|
+
else
|
296
|
+
blk.call(*block_args, **block_kwargs) if blk
|
297
|
+
val_or_callable
|
298
|
+
end
|
299
|
+
end
|
300
|
+
else
|
301
|
+
metaclass.send :define_method, name do |*args, **kwargs, &blk|
|
302
|
+
if val_or_callable.respond_to? :call then
|
303
|
+
if kwargs.empty? then # FIX: drop this after 2.7 dead
|
304
|
+
val_or_callable.call(*args, &blk)
|
305
|
+
else
|
306
|
+
val_or_callable.call(*args, **kwargs, &blk)
|
307
|
+
end
|
308
|
+
else
|
309
|
+
if blk then
|
310
|
+
if block_kwargs.empty? then # FIX: drop this after 2.7 dead
|
311
|
+
blk.call(*block_args)
|
312
|
+
else
|
313
|
+
blk.call(*block_args, **block_kwargs)
|
314
|
+
end
|
315
|
+
end
|
316
|
+
val_or_callable
|
317
|
+
end
|
233
318
|
end
|
234
319
|
end
|
235
320
|
|
236
|
-
|
237
|
-
|
238
|
-
yield self
|
321
|
+
block[self]
|
239
322
|
ensure
|
240
323
|
metaclass.send :undef_method, name
|
241
324
|
metaclass.send :alias_method, name, new_name
|
@@ -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
|
data/lib/minitest/spec.rb
CHANGED
@@ -6,6 +6,10 @@ class Module # :nodoc:
|
|
6
6
|
dont_flip = false if block
|
7
7
|
target_obj = block ? '_{obj.method}' : '_(obj)'
|
8
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)
|
12
|
+
|
9
13
|
# warn "%-22p -> %p %p" % [meth, new_name, dont_flip]
|
10
14
|
self.class_eval <<-EOM, __FILE__, __LINE__ + 1
|
11
15
|
def #{new_name} *args
|
@@ -14,6 +18,7 @@ class Module # :nodoc:
|
|
14
18
|
Kernel.warn "DEPRECATED: global use of #{new_name} from #\{where}. Use #{target_obj}.#{new_name} instead. This will fail in Minitest 6."
|
15
19
|
Minitest::Expectation.new(self, Minitest::Spec.current).#{new_name}(*args)
|
16
20
|
end
|
21
|
+
#{kw_extra}
|
17
22
|
EOM
|
18
23
|
|
19
24
|
Minitest::Expectation.class_eval <<-EOM, __FILE__, __LINE__ + 1
|
@@ -28,6 +33,7 @@ class Module # :nodoc:
|
|
28
33
|
ctx.#{meth}(args.first, target, *args[1..-1])
|
29
34
|
end
|
30
35
|
end
|
36
|
+
#{kw_extra}
|
31
37
|
EOM
|
32
38
|
end
|
33
39
|
end
|
@@ -66,7 +72,7 @@ module Kernel
|
|
66
72
|
#
|
67
73
|
# For some suggestions on how to improve your specs, try:
|
68
74
|
#
|
69
|
-
#
|
75
|
+
# https://betterspecs.org
|
70
76
|
#
|
71
77
|
# but do note that several items there are debatable or specific to
|
72
78
|
# rspec.
|