minitest 5.14.3 → 5.16.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 +55 -1
- data/Manifest.txt +2 -0
- data/README.rdoc +79 -10
- data/Rakefile +1 -1
- data/lib/hoe/minitest.rb +0 -4
- data/lib/minitest/assertions.rb +7 -6
- data/lib/minitest/benchmark.rb +5 -5
- data/lib/minitest/mock.rb +79 -28
- data/lib/minitest/pride_plugin.rb +1 -1
- data/lib/minitest/spec.rb +3 -2
- data/lib/minitest/test.rb +28 -3
- data/lib/minitest/test_task.rb +305 -0
- data/lib/minitest/unit.rb +5 -8
- data/lib/minitest.rb +44 -14
- data/test/minitest/metametameta.rb +1 -1
- data/test/minitest/test_minitest_assertions.rb +32 -16
- data/test/minitest/test_minitest_benchmark.rb +2 -2
- data/test/minitest/test_minitest_mock.rb +179 -9
- data/test/minitest/test_minitest_reporter.rb +30 -17
- data/test/minitest/test_minitest_spec.rb +25 -16
- data/test/minitest/test_minitest_test.rb +128 -30
- data/test/minitest/test_minitest_test_task.rb +46 -0
- data.tar.gz.sig +1 -2
- 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: 9253f08ed8cc9ec5b362ff80aee1be1b0b0d7873fea50c97893d2e62ef013fd2
|
4
|
+
data.tar.gz: e674a1a6f27a4bb130b735585f31658efdec0bb4eae4140e63f1bc30a5d59779
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 925355cd00438e04a789b67a4c79796c590d4d18a2e0bedf33592d471a6c3586a77aec61fec8882099ab3980ccb4e9be87de7dd31c6ae9d938f39a13188788f7
|
7
|
+
data.tar.gz: 48e0507f508e989bf2a6dbe137114377b4cb552041d52a1cf232feb062ab6bcfb43097e551f061c23a35fce074093ddbe5259c9a51dbee7e88d10843c15db2f8
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/History.rdoc
CHANGED
@@ -1,3 +1,57 @@
|
|
1
|
+
=== 5.16.0 / 2022-06-14
|
2
|
+
|
3
|
+
* 2 major enhancements:
|
4
|
+
|
5
|
+
* Added Minitest::TestTask.
|
6
|
+
* Dropping ruby 2.2 - 2.5. 2.6 is DTM soon too.
|
7
|
+
|
8
|
+
* 11 minor enhancements:
|
9
|
+
|
10
|
+
* Added --show-skips option to show skips at end of run but not require --verbose. (MSP-Greg)
|
11
|
+
* Added Minitest.seed, the random seed used by the run.
|
12
|
+
* Calling `srand Minitest.seed` before all shuffles to ensure determinism.
|
13
|
+
* Extended #stub to handle kwargs for both block and call args. (SampsonCrowley)
|
14
|
+
* Extended Mock#__call to display kwargs.
|
15
|
+
* Extended Mock#expect to record kwargs.
|
16
|
+
* Extended Mock#method_missing to take kwargs & compare them against expected.
|
17
|
+
* Mock#method_missing displays better errors on arity mismatch.
|
18
|
+
* Removed minor optimization removing empty suites before run.
|
19
|
+
* Simplified test randomization (test order will change even with fixed seed).
|
20
|
+
* assert_match now returns the MatchData on success. (Nakilon)
|
21
|
+
|
22
|
+
* 3 bug fixes:
|
23
|
+
|
24
|
+
* (Re)Fixed marshalling of exceptions, neutering them in 2 passes.
|
25
|
+
* Fixed more problems with rdoc.
|
26
|
+
* Had to patch up mock and stub to deal with <=2.7 kwargs oddities
|
27
|
+
|
28
|
+
=== 5.15.0 / 2021-12-14
|
29
|
+
|
30
|
+
* 1 major enhancement:
|
31
|
+
|
32
|
+
* assert_throws returns the value returned, if any. (volmer)
|
33
|
+
|
34
|
+
* 3 minor enhancements:
|
35
|
+
|
36
|
+
* Added -S <CODES> option to skip reporting of certain types of output
|
37
|
+
* Enable Ruby deprecation warnings by default. (casperisfine)
|
38
|
+
* Use Etc.nprocessors by default in order to maximize cpu usage. (tonytonyjan)
|
39
|
+
|
40
|
+
* 6 bug fixes:
|
41
|
+
|
42
|
+
* Close then unlink tempfiles on Windows. (nobu)
|
43
|
+
* Fixed #skip_until for windows paths. (MSP-Greg)
|
44
|
+
* Fixed a bunch of tests for jruby and windows. (MSP-Greg)
|
45
|
+
* Fixed marshalling of specs if they error. (tenderlove, jeremyevans, et al)
|
46
|
+
* Updated deprecation message for block expectations. (blowmage)
|
47
|
+
* Use Kernel.warn directly in expectations in case CUT defines their own warn. (firien)
|
48
|
+
|
49
|
+
=== 5.14.4 / 2021-02-23
|
50
|
+
|
51
|
+
* 1 bug fix:
|
52
|
+
|
53
|
+
* Fixed deprecation warning using stub with methods using keyword arguments. (Nakilon)
|
54
|
+
|
1
55
|
=== 5.14.3 / 2021-01-05
|
2
56
|
|
3
57
|
* 1 bug fix:
|
@@ -555,7 +609,7 @@ Minitest 5:
|
|
555
609
|
* Added Minitest::Benchmark.
|
556
610
|
* Your benchmarks need to move to their own subclass.
|
557
611
|
* Benchmarks using the spec DSL have to have "Bench" somewhere in their describe.
|
558
|
-
* MiniTest::Unit.after_tests moved to Minitest.
|
612
|
+
* MiniTest::Unit.after_tests moved to Minitest.after_run
|
559
613
|
* MiniTest::Unit.autorun is now Minitest.autorun. Just require minitest/autorun pls.
|
560
614
|
* Removed ParallelEach#grep since it isn't used anywhere.
|
561
615
|
* Renamed Runnable#__name__ to Runnable#name (but uses @NAME internally).
|
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
|
304
|
+
|
305
|
+
# or more explicitly:
|
300
306
|
|
301
|
-
|
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
|
@@ -376,6 +403,42 @@ Using our example above, here is how we might implement MyCI:
|
|
376
403
|
|
377
404
|
== FAQ
|
378
405
|
|
406
|
+
=== What versions are compatible with what? Or what versions are supported?
|
407
|
+
|
408
|
+
Minitest is a dependency of rails, which until fairly recently had an
|
409
|
+
overzealous backwards compatibility policy. As such, I'm stuck
|
410
|
+
supporting versions of ruby that are long past EOL. Once rails 5.2 is
|
411
|
+
dropped (hopefully April 2021), I get to drop a bunch of versions of
|
412
|
+
ruby that I have to currently test against.
|
413
|
+
|
414
|
+
(As of 2021-01-31)
|
415
|
+
|
416
|
+
Current versions of rails: (https://endoflife.date/rails)
|
417
|
+
|
418
|
+
| rails | min ruby | rec ruby | minitest | status |
|
419
|
+
|-------+----------+----------+----------+----------|
|
420
|
+
| 7.0 | >= 2.7 | 3.0 | >= 5.1 | Future |
|
421
|
+
| 6.1 | >= 2.5 | 3.0 | >= 5.1 | Current |
|
422
|
+
| 6.0 | >= 2.5 | 2.6 | >= 5.1 | Security |
|
423
|
+
| 5.2 | >= 2.2.2 | 2.5 | ~> 5.1 | Security | EOL @railsconf 2021?
|
424
|
+
|
425
|
+
Current versions of ruby: (https://endoflife.date/ruby)
|
426
|
+
|
427
|
+
| ruby | Status | EOL Date |
|
428
|
+
|------+---------+------------|
|
429
|
+
| 3.0 | Current | 2024-03-31 |
|
430
|
+
| 2.7 | Maint | 2023-03-31 |
|
431
|
+
| 2.6 | Maint* | 2022-03-31 |
|
432
|
+
| 2.5 | EOL | 2021-03-31 |
|
433
|
+
| 2.4 | EOL | 2020-03-31 |
|
434
|
+
| 2.3 | EOL | 2019-03-31 |
|
435
|
+
| 2.2 | EOL | 2018-03-31 |
|
436
|
+
|
437
|
+
See also:
|
438
|
+
|
439
|
+
* https://www.fastruby.io/blog/ruby/rails/versions/compatibility-table.html
|
440
|
+
* https://jamesjeffersconsulting.com/ruby-rails-version-matrix/
|
441
|
+
|
379
442
|
=== How to test SimpleDelegates?
|
380
443
|
|
381
444
|
The following implementation and test:
|
@@ -611,6 +674,7 @@ minitest-growl :: Test notifier for minitest via growl.
|
|
611
674
|
minitest-happy :: GLOBALLY ACTIVATE MINITEST PRIDE! RAWR!
|
612
675
|
minitest-have_tag :: Adds Minitest assertions to test for the existence of
|
613
676
|
HTML tags, including contents, within a provided string.
|
677
|
+
minitest-heat :: Reporting that builds a heat map of failure locations
|
614
678
|
minitest-hooks :: Around and before_all/after_all/around_all hooks
|
615
679
|
minitest-hyper :: Pretty, single-page HTML reports for your Minitest runs
|
616
680
|
minitest-implicit-subject :: Implicit declaration of the test subject.
|
@@ -685,8 +749,13 @@ mongoid-minitest :: Minitest matchers for Mongoid.
|
|
685
749
|
mutant-minitest :: Minitest integration for mutant.
|
686
750
|
pry-rescue :: A pry plugin w/ minitest support. See
|
687
751
|
pry-rescue/minitest.rb.
|
752
|
+
rematch :: Declutter your test files from large hardcoded data
|
753
|
+
and update them automatically when your code changes.
|
688
754
|
rspec2minitest :: Easily translate any RSpec matchers to Minitest
|
689
755
|
assertions and expectations.
|
756
|
+
stubberry :: Multiple stubbing 'berries', sweet and useful
|
757
|
+
stub helpers and assertions. ( stub_must,
|
758
|
+
assert_method_called, stubbing ORM objects by id )
|
690
759
|
|
691
760
|
== Unknown Extensions:
|
692
761
|
|
@@ -712,7 +781,7 @@ Authors... Please send me a pull request with a description of your minitest ext
|
|
712
781
|
|
713
782
|
== Minitest related goods
|
714
783
|
|
715
|
-
* minitest/pride fabric:
|
784
|
+
* minitest/pride fabric: https://www.spoonflower.com/fabric/3928730-again-by-katie_allen
|
716
785
|
|
717
786
|
== REQUIREMENTS:
|
718
787
|
|
data/Rakefile
CHANGED
data/lib/hoe/minitest.rb
CHANGED
data/lib/minitest/assertions.rb
CHANGED
@@ -293,6 +293,8 @@ module Minitest
|
|
293
293
|
assert_respond_to matcher, :"=~"
|
294
294
|
matcher = Regexp.new Regexp.escape matcher if String === matcher
|
295
295
|
assert matcher =~ obj, msg
|
296
|
+
|
297
|
+
Regexp.last_match
|
296
298
|
end
|
297
299
|
|
298
300
|
##
|
@@ -473,7 +475,7 @@ module Minitest
|
|
473
475
|
def assert_throws sym, msg = nil
|
474
476
|
default = "Expected #{mu_pp(sym)} to have been thrown"
|
475
477
|
caught = true
|
476
|
-
catch(sym) do
|
478
|
+
value = catch(sym) do
|
477
479
|
begin
|
478
480
|
yield
|
479
481
|
rescue ThreadError => e # wtf?!? 1.8 + threads == suck
|
@@ -489,6 +491,7 @@ module Minitest
|
|
489
491
|
end
|
490
492
|
|
491
493
|
assert caught, message(msg) { default }
|
494
|
+
value
|
492
495
|
rescue Assertion
|
493
496
|
raise
|
494
497
|
rescue => e
|
@@ -561,15 +564,13 @@ module Minitest
|
|
561
564
|
|
562
565
|
return captured_stdout.read, captured_stderr.read
|
563
566
|
ensure
|
564
|
-
captured_stdout.unlink
|
565
|
-
captured_stderr.unlink
|
566
567
|
$stdout.reopen orig_stdout
|
567
568
|
$stderr.reopen orig_stderr
|
568
569
|
|
569
570
|
orig_stdout.close
|
570
571
|
orig_stderr.close
|
571
|
-
captured_stdout.close
|
572
|
-
captured_stderr.close
|
572
|
+
captured_stdout.close!
|
573
|
+
captured_stderr.close!
|
573
574
|
end
|
574
575
|
end
|
575
576
|
end
|
@@ -793,7 +794,7 @@ module Minitest
|
|
793
794
|
|
794
795
|
def skip_until y,m,d,msg
|
795
796
|
skip msg if Time.now < Time.local(y, m, d)
|
796
|
-
where = caller.first.
|
797
|
+
where = caller.first.rpartition(':in').reject(&:empty?).first
|
797
798
|
warn "Stale skip_until %p at %s" % [msg, where]
|
798
799
|
end
|
799
800
|
|
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
|
@@ -44,8 +52,8 @@ module Minitest # :nodoc:
|
|
44
52
|
end
|
45
53
|
|
46
54
|
##
|
47
|
-
# Expect that method +name+ is called, optionally with +args+
|
48
|
-
# +blk+, and returns +retval+.
|
55
|
+
# Expect that method +name+ is called, optionally with +args+ (and
|
56
|
+
# +kwargs+ or a +blk+, and returns +retval+.
|
49
57
|
#
|
50
58
|
# @mock.expect(:meaning_of_life, 42)
|
51
59
|
# @mock.meaning_of_life # => 42
|
@@ -78,7 +86,7 @@ module Minitest # :nodoc:
|
|
78
86
|
# @mock.ordinal_increment # => raises MockExpectationError "No more expects available for :ordinal_increment"
|
79
87
|
#
|
80
88
|
|
81
|
-
def expect name, retval, args = [], &blk
|
89
|
+
def expect name, retval, args = [], **kwargs, &blk
|
82
90
|
name = name.to_sym
|
83
91
|
|
84
92
|
if block_given?
|
@@ -86,7 +94,7 @@ module Minitest # :nodoc:
|
|
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
|
-
@expected_calls[name] << { :retval => retval, :args => args }
|
97
|
+
@expected_calls[name] << { :retval => retval, :args => args, :kwargs => kwargs }
|
90
98
|
end
|
91
99
|
self
|
92
100
|
end
|
@@ -94,7 +102,13 @@ module Minitest # :nodoc:
|
|
94
102
|
def __call name, data # :nodoc:
|
95
103
|
case data
|
96
104
|
when Hash then
|
97
|
-
|
105
|
+
args = data[:args].inspect[1..-2]
|
106
|
+
kwargs = data[:kwargs]
|
107
|
+
if kwargs && !kwargs.empty? then
|
108
|
+
args << ", " unless args.empty?
|
109
|
+
args << kwargs.inspect[1..-2]
|
110
|
+
end
|
111
|
+
"#{name}(#{args}) => #{data[:retval].inspect}"
|
98
112
|
else
|
99
113
|
data.map { |d| __call name, d }.join ", "
|
100
114
|
end
|
@@ -115,10 +129,10 @@ module Minitest # :nodoc:
|
|
115
129
|
true
|
116
130
|
end
|
117
131
|
|
118
|
-
def method_missing sym, *args, &block # :nodoc:
|
132
|
+
def method_missing sym, *args, **kwargs, &block # :nodoc:
|
119
133
|
unless @expected_calls.key?(sym) then
|
120
134
|
if @delegator && @delegator.respond_to?(sym)
|
121
|
-
return @delegator.public_send(sym, *args, &block)
|
135
|
+
return @delegator.public_send(sym, *args, **kwargs, &block)
|
122
136
|
else
|
123
137
|
raise NoMethodError, "unmocked method %p, expected one of %p" %
|
124
138
|
[sym, @expected_calls.keys.sort_by(&:to_s)]
|
@@ -129,26 +143,31 @@ module Minitest # :nodoc:
|
|
129
143
|
expected_call = @expected_calls[sym][index]
|
130
144
|
|
131
145
|
unless expected_call then
|
132
|
-
raise MockExpectationError, "No more expects available for %p: %p" %
|
133
|
-
[sym, args]
|
146
|
+
raise MockExpectationError, "No more expects available for %p: %p %p" %
|
147
|
+
[sym, args, kwargs]
|
134
148
|
end
|
135
149
|
|
136
|
-
expected_args, retval, val_block =
|
137
|
-
expected_call.values_at(:args, :retval, :block)
|
150
|
+
expected_args, expected_kwargs, retval, val_block =
|
151
|
+
expected_call.values_at(:args, :kwargs, :retval, :block)
|
138
152
|
|
139
153
|
if val_block then
|
140
154
|
# keep "verify" happy
|
141
155
|
@actual_calls[sym] << expected_call
|
142
156
|
|
143
|
-
raise MockExpectationError, "mocked method %p failed block w/ %p" %
|
144
|
-
[sym, args] unless val_block.call(*args, &block)
|
157
|
+
raise MockExpectationError, "mocked method %p failed block w/ %p %p" %
|
158
|
+
[sym, args, kwargs] unless val_block.call(*args, **kwargs, &block)
|
145
159
|
|
146
160
|
return retval
|
147
161
|
end
|
148
162
|
|
149
163
|
if expected_args.size != args.size then
|
150
|
-
raise ArgumentError, "mocked method %p expects %d arguments, got %
|
151
|
-
[sym, expected_args.size, args
|
164
|
+
raise ArgumentError, "mocked method %p expects %d arguments, got %p" %
|
165
|
+
[sym, expected_args.size, args]
|
166
|
+
end
|
167
|
+
|
168
|
+
if expected_kwargs.size != kwargs.size then
|
169
|
+
raise ArgumentError, "mocked method %p expects %d keyword arguments, got %p" %
|
170
|
+
[sym, expected_kwargs.size, kwargs]
|
152
171
|
end
|
153
172
|
|
154
173
|
zipped_args = expected_args.zip(args)
|
@@ -157,13 +176,33 @@ module Minitest # :nodoc:
|
|
157
176
|
}
|
158
177
|
|
159
178
|
unless fully_matched then
|
160
|
-
|
161
|
-
|
179
|
+
fmt = "mocked method %p called with unexpected arguments %p"
|
180
|
+
raise MockExpectationError, fmt % [sym, args]
|
181
|
+
end
|
182
|
+
|
183
|
+
unless expected_kwargs.keys.sort == kwargs.keys.sort then
|
184
|
+
fmt = "mocked method %p called with unexpected keywords %p vs %p"
|
185
|
+
raise MockExpectationError, fmt % [sym, expected_kwargs.keys, kwargs.keys]
|
186
|
+
end
|
187
|
+
|
188
|
+
zipped_kwargs = expected_kwargs.map { |ek, ev|
|
189
|
+
av = kwargs[ek]
|
190
|
+
[ek, [ev, av]]
|
191
|
+
}.to_h
|
192
|
+
|
193
|
+
fully_matched = zipped_kwargs.all? { |ek, (ev, av)|
|
194
|
+
ev === av or ev == av
|
195
|
+
}
|
196
|
+
|
197
|
+
unless fully_matched then
|
198
|
+
fmt = "mocked method %p called with unexpected keyword arguments %p vs %p"
|
199
|
+
raise MockExpectationError, fmt % [sym, expected_kwargs, kwargs]
|
162
200
|
end
|
163
201
|
|
164
202
|
@actual_calls[sym] << {
|
165
203
|
:retval => retval,
|
166
|
-
:args => zipped_args.map
|
204
|
+
:args => zipped_args.map { |e, a| e === a ? e : a },
|
205
|
+
:kwargs => zipped_kwargs.map { |k, (e, a)| [k, e === a ? e : a] }.to_h,
|
167
206
|
}
|
168
207
|
|
169
208
|
retval
|
@@ -207,26 +246,38 @@ class Object
|
|
207
246
|
# assert obj_under_test.stale?
|
208
247
|
# end
|
209
248
|
# end
|
210
|
-
|
249
|
+
#--
|
250
|
+
# NOTE: keyword args in callables are NOT checked for correctness
|
251
|
+
# against the existing method. Too many edge cases to be worth it.
|
211
252
|
|
212
|
-
def stub name, val_or_callable, *block_args
|
253
|
+
def stub name, val_or_callable, *block_args, **block_kwargs
|
213
254
|
new_name = "__minitest_stub__#{name}"
|
214
255
|
|
215
256
|
metaclass = class << self; self; end
|
216
257
|
|
217
258
|
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)
|
259
|
+
metaclass.send :define_method, name do |*args, **kwargs|
|
260
|
+
super(*args, **kwargs)
|
220
261
|
end
|
221
262
|
end
|
222
263
|
|
223
264
|
metaclass.send :alias_method, new_name, name
|
224
265
|
|
225
|
-
metaclass.send :define_method, name do |*args, &blk|
|
266
|
+
metaclass.send :define_method, name do |*args, **kwargs, &blk|
|
226
267
|
if val_or_callable.respond_to? :call then
|
227
|
-
|
268
|
+
if kwargs.empty? then # FIX: drop this after 2.7 dead
|
269
|
+
val_or_callable.call(*args, &blk)
|
270
|
+
else
|
271
|
+
val_or_callable.call(*args, **kwargs, &blk)
|
272
|
+
end
|
228
273
|
else
|
229
|
-
|
274
|
+
if blk then
|
275
|
+
if block_kwargs.empty? then # FIX: drop this after 2.7 dead
|
276
|
+
blk.call(*block_args)
|
277
|
+
else
|
278
|
+
blk.call(*block_args, **block_kwargs)
|
279
|
+
end
|
280
|
+
end
|
230
281
|
val_or_callable
|
231
282
|
end
|
232
283
|
end
|
@@ -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
@@ -4,13 +4,14 @@ 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)'
|
7
8
|
|
8
9
|
# warn "%-22p -> %p %p" % [meth, new_name, dont_flip]
|
9
10
|
self.class_eval <<-EOM, __FILE__, __LINE__ + 1
|
10
11
|
def #{new_name} *args
|
11
12
|
where = Minitest.filter_backtrace(caller).first
|
12
13
|
where = where.split(/:in /, 2).first # clean up noise
|
13
|
-
warn "DEPRECATED: global use of #{new_name} from #\{where}. Use
|
14
|
+
Kernel.warn "DEPRECATED: global use of #{new_name} from #\{where}. Use #{target_obj}.#{new_name} instead. This will fail in Minitest 6."
|
14
15
|
Minitest::Expectation.new(self, Minitest::Spec.current).#{new_name}(*args)
|
15
16
|
end
|
16
17
|
EOM
|
@@ -65,7 +66,7 @@ module Kernel
|
|
65
66
|
#
|
66
67
|
# For some suggestions on how to improve your specs, try:
|
67
68
|
#
|
68
|
-
#
|
69
|
+
# https://betterspecs.org
|
69
70
|
#
|
70
71
|
# but do note that several items there are debatable or specific to
|
71
72
|
# rspec.
|
data/lib/minitest/test.rb
CHANGED
@@ -67,8 +67,8 @@ module Minitest
|
|
67
67
|
|
68
68
|
case self.test_order
|
69
69
|
when :random, :parallel then
|
70
|
-
|
71
|
-
methods.sort.
|
70
|
+
srand Minitest.seed
|
71
|
+
methods.sort.shuffle
|
72
72
|
when :alpha, :sorted then
|
73
73
|
methods.sort
|
74
74
|
else
|
@@ -198,7 +198,32 @@ module Minitest
|
|
198
198
|
rescue Assertion => e
|
199
199
|
self.failures << e
|
200
200
|
rescue Exception => e
|
201
|
-
self.failures << UnexpectedError.new(e)
|
201
|
+
self.failures << UnexpectedError.new(sanitize_exception e)
|
202
|
+
end
|
203
|
+
|
204
|
+
def sanitize_exception e # :nodoc:
|
205
|
+
Marshal.dump e
|
206
|
+
e # good: use as-is
|
207
|
+
rescue TypeError
|
208
|
+
neuter_exception e
|
209
|
+
end
|
210
|
+
|
211
|
+
def neuter_exception e
|
212
|
+
bt = e.backtrace
|
213
|
+
msg = e.message.dup
|
214
|
+
|
215
|
+
new_exception e.class, msg, bt # e.class can be a problem...
|
216
|
+
rescue TypeError
|
217
|
+
msg.prepend "Neutered Exception #{e.class}: "
|
218
|
+
|
219
|
+
new_exception RuntimeError, msg, bt # but if this raises, we die
|
220
|
+
end
|
221
|
+
|
222
|
+
def new_exception klass, msg, bt
|
223
|
+
ne = klass.new msg
|
224
|
+
ne.set_backtrace bt
|
225
|
+
Marshal.dump ne # can raise TypeError
|
226
|
+
ne
|
202
227
|
end
|
203
228
|
|
204
229
|
def with_info_handler &block # :nodoc:
|