minitest 5.14.3 → 5.16.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f47836e4dcf290018441ccd338ab779507b9ad318c5815f7c6df427d5d519fd4
4
- data.tar.gz: 29aeac653e8eb3e2d0962e6bfd29794ae88290e63820e827a8f92bb395a778b7
3
+ metadata.gz: 9253f08ed8cc9ec5b362ff80aee1be1b0b0d7873fea50c97893d2e62ef013fd2
4
+ data.tar.gz: e674a1a6f27a4bb130b735585f31658efdec0bb4eae4140e63f1bc30a5d59779
5
5
  SHA512:
6
- metadata.gz: b2f2c7e8f0a5b3c3ea3f8e87b68f69ff5294dc1e40c453308660a97ae8e072cd2426e853a5c84638b5d2f3d57bc744d6df98f9a659adad9ca13b233d401565b0
7
- data.tar.gz: 13a28eebea4de744d08bb6ac3538cde8fe1817167cf48e2a5cfc5bc76d0a4584953f6e5b98d4bb15285630d92aae000093368ab309a3e5a80a8cb02117c6ba15
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.after_tests
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 :: http://docs.seattlerb.org/minitest
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
- http://www.martinfowler.com/bliki/TestDouble.html:
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
- http://www.martinfowler.com/bliki/TestDouble.html:
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 piecemeal or
268
- all at once. Both rake and rails ship with rake tasks for running your
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 "rake/testtask"
301
+ require "minitest/test_task"
302
+
303
+ Minitest::TestTask.create # named test, sensible defaults
304
+
305
+ # or more explicitly:
300
306
 
301
- Rake::TestTask.new(:test) do |t|
307
+ Minitest::TestTask.create(:test) do |t|
302
308
  t.libs << "test"
303
309
  t.libs << "lib"
304
- t.test_files = FileList["test/**/test_*.rb"]
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: http://www.spoonflower.com/fabric/3928730-again-by-katie_allen
784
+ * minitest/pride fabric: https://www.spoonflower.com/fabric/3928730-again-by-katie_allen
716
785
 
717
786
  == REQUIREMENTS:
718
787
 
data/Rakefile CHANGED
@@ -11,7 +11,7 @@ Hoe.spec "minitest" do
11
11
 
12
12
  license "MIT"
13
13
 
14
- require_ruby_version [">= 2.2", "< 4.0"]
14
+ require_ruby_version [">= 2.6", "< 4.0"]
15
15
  end
16
16
 
17
17
  desc "Find missing expectations"
data/lib/hoe/minitest.rb CHANGED
@@ -24,9 +24,5 @@ module Hoe::Minitest
24
24
 
25
25
  def define_minitest_tasks
26
26
  self.testlib = :minitest
27
-
28
- # make sure we use the gemmed minitest on 1.9
29
- self.test_prelude = 'gem "minitest"' unless
30
- minitest? or ENV["MT_NO_ISOLATE"]
31
27
  end
32
28
  end
@@ -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.split(/:/, 3).first(2).join ":"
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
 
@@ -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: http://en.wikipedia.org/wiki/Coefficient_of_determination
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: http://mathworld.wolfram.com/LeastSquaresFittingExponential.html
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: http://mathworld.wolfram.com/LeastSquaresFittingLogarithmic.html
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: http://mathworld.wolfram.com/LeastSquaresFitting.html
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: http://mathworld.wolfram.com/LeastSquaresFittingPowerLaw.html
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
- method_missing(method_id, *args, &b)
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
- super(*args, &b)
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+ or a
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
- "#{name}(#{data[:args].inspect[1..-2]}) => #{data[:retval].inspect}"
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 %d" %
151
- [sym, expected_args.size, args.size]
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
- raise MockExpectationError, "mocked method %p called with unexpected arguments %p" %
161
- [sym, args]
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! { |mod, a| mod === a ? mod : a },
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
- val_or_callable.call(*args, &blk)
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
- blk.call(*block_args) if blk
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 http://en.wikipedia.org/wiki/ANSI_escape_code
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 _(obj).#{new_name} instead. This will fail in Minitest 6."
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
- # http://betterspecs.org
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
- max = methods.size
71
- methods.sort.sort_by { rand max }
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: