minitest 5.15.0 → 5.16.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d7d16c7decb91ba01a888704bd527d1e5569454b444fe1b4e41a8a3a7db7406
4
- data.tar.gz: 1ee0d2823a94b63b8cd019198fe2ca20a5c3d9d7bf4918148bdfa543fb65945d
3
+ metadata.gz: 852c6d118d767dd9a858cdb30033835fadb147806baf17b8212fd2adb73563f6
4
+ data.tar.gz: a6b8773230001afcd126bec405ffa06324a2cf3a5d52588ba44e8c0a0750aef2
5
5
  SHA512:
6
- metadata.gz: 933a300969aa30dc8f254952dd17f9975cb1f3aad9c10c96260394d088b76900273773374b5ed72731356f2b7f1cfeb131583ae943322250a60401e554e11f45
7
- data.tar.gz: 24a356e1d3c06e28d03860b4dca92d17b88979ebad6316fe97298207c58b29b0ae207657d0044a43ede1bf9a27ac43ca8c779e24fc9ca5ed4c920beca2eaf143
6
+ metadata.gz: e7059905b9c55d737ce9d92c066fcd38080deb7a60535a142b528d91d97fc1be87726261725cf14c8dd6540c1d274da8ebbc860f9bea957bbd2e7f6a078381f6
7
+ data.tar.gz: 8beb3623acb42c1a5fe640cbdbe99833181f90e4d9e52bcf297cfd471d86785c186291911e94e00d5b54cb56870ae1f1d97be16207c7c6381fc31bb56596e2aa
checksums.yaml.gz.sig CHANGED
Binary file
data/History.rdoc CHANGED
@@ -1,3 +1,38 @@
1
+ === 5.16.1 / 2022-06-20
2
+
3
+ * 2 bug fixes:
4
+
5
+ * Apparently adding real kwarg support to mocks/stubs broke some code. Fixed.
6
+ * Use `MT_KWARGS_HACK=1` to activate the kludgy kwargs support w/ caveats.
7
+ * Clarified some doco wrt the block on #stub.
8
+
9
+ === 5.16.0 / 2022-06-14
10
+
11
+ * 2 major enhancements:
12
+
13
+ * Added Minitest::TestTask.
14
+ * Dropping ruby 2.2 - 2.5. 2.6 is DTM soon too.
15
+
16
+ * 11 minor enhancements:
17
+
18
+ * Added --show-skips option to show skips at end of run but not require --verbose. (MSP-Greg)
19
+ * Added Minitest.seed, the random seed used by the run.
20
+ * Calling `srand Minitest.seed` before all shuffles to ensure determinism.
21
+ * Extended #stub to handle kwargs for both block and call args. (SampsonCrowley)
22
+ * Extended Mock#__call to display kwargs.
23
+ * Extended Mock#expect to record kwargs.
24
+ * Extended Mock#method_missing to take kwargs & compare them against expected.
25
+ * Mock#method_missing displays better errors on arity mismatch.
26
+ * Removed minor optimization removing empty suites before run.
27
+ * Simplified test randomization (test order will change even with fixed seed).
28
+ * assert_match now returns the MatchData on success. (Nakilon)
29
+
30
+ * 3 bug fixes:
31
+
32
+ * (Re)Fixed marshalling of exceptions, neutering them in 2 passes.
33
+ * Fixed more problems with rdoc.
34
+ * Had to patch up mock and stub to deal with <=2.7 kwargs oddities
35
+
1
36
  === 5.15.0 / 2021-12-14
2
37
 
3
38
  * 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 :: 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
300
304
 
301
- Rake::TestTask.new(:test) do |t|
305
+ # or more explicitly:
306
+
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
@@ -726,6 +753,9 @@ rematch :: Declutter your test files from large hardcoded da
726
753
  and update them automatically when your code changes.
727
754
  rspec2minitest :: Easily translate any RSpec matchers to Minitest
728
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 )
729
759
 
730
760
  == Unknown Extensions:
731
761
 
@@ -751,7 +781,7 @@ Authors... Please send me a pull request with a description of your minitest ext
751
781
 
752
782
  == Minitest related goods
753
783
 
754
- * 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
755
785
 
756
786
  == REQUIREMENTS:
757
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"
@@ -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
  ##
@@ -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
@@ -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+ or a
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,30 @@ 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
- @expected_calls[name] << { :retval => retval, :args => args }
100
+
101
+ if ENV["MT_KWARGS_HAC\K"] && Hash === args.last then
102
+ if kwargs.empty? then
103
+ kwargs = args.pop
104
+ else
105
+ unless @@KW_WARNED then
106
+ from = caller.first
107
+ warn "Using MT_KWARGS_HAC\K yet passing kwargs. From #{from}"
108
+ @@KW_WARNED = true
109
+ end
110
+ end
111
+ end
112
+
113
+ @expected_calls[name] <<
114
+ { :retval => retval, :args => args, :kwargs => kwargs }
90
115
  end
91
116
  self
92
117
  end
@@ -94,7 +119,13 @@ module Minitest # :nodoc:
94
119
  def __call name, data # :nodoc:
95
120
  case data
96
121
  when Hash then
97
- "#{name}(#{data[:args].inspect[1..-2]}) => #{data[:retval].inspect}"
122
+ args = data[:args].inspect[1..-2]
123
+ kwargs = data[:kwargs]
124
+ if kwargs && !kwargs.empty? then
125
+ args << ", " unless args.empty?
126
+ args << kwargs.inspect[1..-2]
127
+ end
128
+ "#{name}(#{args}) => #{data[:retval].inspect}"
98
129
  else
99
130
  data.map { |d| __call name, d }.join ", "
100
131
  end
@@ -115,10 +146,10 @@ module Minitest # :nodoc:
115
146
  true
116
147
  end
117
148
 
118
- def method_missing sym, *args, &block # :nodoc:
149
+ def method_missing sym, *args, **kwargs, &block # :nodoc:
119
150
  unless @expected_calls.key?(sym) then
120
151
  if @delegator && @delegator.respond_to?(sym)
121
- return @delegator.public_send(sym, *args, &block)
152
+ return @delegator.public_send(sym, *args, **kwargs, &block)
122
153
  else
123
154
  raise NoMethodError, "unmocked method %p, expected one of %p" %
124
155
  [sym, @expected_calls.keys.sort_by(&:to_s)]
@@ -129,26 +160,31 @@ module Minitest # :nodoc:
129
160
  expected_call = @expected_calls[sym][index]
130
161
 
131
162
  unless expected_call then
132
- raise MockExpectationError, "No more expects available for %p: %p" %
133
- [sym, args]
163
+ raise MockExpectationError, "No more expects available for %p: %p %p" %
164
+ [sym, args, kwargs]
134
165
  end
135
166
 
136
- expected_args, retval, val_block =
137
- expected_call.values_at(:args, :retval, :block)
167
+ expected_args, expected_kwargs, retval, val_block =
168
+ expected_call.values_at(:args, :kwargs, :retval, :block)
138
169
 
139
170
  if val_block then
140
171
  # keep "verify" happy
141
172
  @actual_calls[sym] << expected_call
142
173
 
143
- raise MockExpectationError, "mocked method %p failed block w/ %p" %
144
- [sym, args] unless val_block.call(*args, &block)
174
+ raise MockExpectationError, "mocked method %p failed block w/ %p %p" %
175
+ [sym, args, kwargs] unless val_block.call(*args, **kwargs, &block)
145
176
 
146
177
  return retval
147
178
  end
148
179
 
149
180
  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]
181
+ raise ArgumentError, "mocked method %p expects %d arguments, got %p" %
182
+ [sym, expected_args.size, args]
183
+ end
184
+
185
+ if expected_kwargs.size != kwargs.size then
186
+ raise ArgumentError, "mocked method %p expects %d keyword arguments, got %p" %
187
+ [sym, expected_kwargs.size, kwargs]
152
188
  end
153
189
 
154
190
  zipped_args = expected_args.zip(args)
@@ -157,13 +193,33 @@ module Minitest # :nodoc:
157
193
  }
158
194
 
159
195
  unless fully_matched then
160
- raise MockExpectationError, "mocked method %p called with unexpected arguments %p" %
161
- [sym, args]
196
+ fmt = "mocked method %p called with unexpected arguments %p"
197
+ raise MockExpectationError, fmt % [sym, args]
198
+ end
199
+
200
+ unless expected_kwargs.keys.sort == kwargs.keys.sort then
201
+ fmt = "mocked method %p called with unexpected keywords %p vs %p"
202
+ raise MockExpectationError, fmt % [sym, expected_kwargs.keys, kwargs.keys]
203
+ end
204
+
205
+ zipped_kwargs = expected_kwargs.map { |ek, ev|
206
+ av = kwargs[ek]
207
+ [ek, [ev, av]]
208
+ }.to_h
209
+
210
+ fully_matched = zipped_kwargs.all? { |ek, (ev, av)|
211
+ ev === av or ev == av
212
+ }
213
+
214
+ unless fully_matched then
215
+ fmt = "mocked method %p called with unexpected keyword arguments %p vs %p"
216
+ raise MockExpectationError, fmt % [sym, expected_kwargs, kwargs]
162
217
  end
163
218
 
164
219
  @actual_calls[sym] << {
165
220
  :retval => retval,
166
- :args => zipped_args.map! { |mod, a| mod === a ? mod : a },
221
+ :args => zipped_args.map { |e, a| e === a ? e : a },
222
+ :kwargs => zipped_kwargs.map { |k, (e, a)| [k, e === a ? e : a] }.to_h,
167
223
  }
168
224
 
169
225
  retval
@@ -211,31 +267,39 @@ class Object
211
267
  # NOTE: keyword args in callables are NOT checked for correctness
212
268
  # against the existing method. Too many edge cases to be worth it.
213
269
 
214
- def stub name, val_or_callable, *block_args
270
+ def stub name, val_or_callable, *block_args, **block_kwargs, &block
215
271
  new_name = "__minitest_stub__#{name}"
216
272
 
217
273
  metaclass = class << self; self; end
218
274
 
219
275
  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)
276
+ metaclass.send :define_method, name do |*args, **kwargs|
277
+ super(*args, **kwargs)
222
278
  end
223
279
  end
224
280
 
225
281
  metaclass.send :alias_method, new_name, name
226
282
 
227
- metaclass.send :define_method, name do |*args, &blk|
283
+ metaclass.send :define_method, name do |*args, **kwargs, &blk|
228
284
  if val_or_callable.respond_to? :call then
229
- val_or_callable.call(*args, &blk)
285
+ if kwargs.empty? then # FIX: drop this after 2.7 dead
286
+ val_or_callable.call(*args, &blk)
287
+ else
288
+ val_or_callable.call(*args, **kwargs, &blk)
289
+ end
230
290
  else
231
- blk.call(*block_args) if blk
291
+ if blk then
292
+ if block_kwargs.empty? then # FIX: drop this after 2.7 dead
293
+ blk.call(*block_args)
294
+ else
295
+ blk.call(*block_args, **block_kwargs)
296
+ end
297
+ end
232
298
  val_or_callable
233
299
  end
234
300
  end
235
301
 
236
- metaclass.send(:ruby2_keywords, name) if metaclass.respond_to?(:ruby2_keywords, true)
237
-
238
- yield self
302
+ block[self]
239
303
  ensure
240
304
  metaclass.send :undef_method, name
241
305
  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 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
@@ -66,7 +66,7 @@ module Kernel
66
66
  #
67
67
  # For some suggestions on how to improve your specs, try:
68
68
  #
69
- # http://betterspecs.org
69
+ # https://betterspecs.org
70
70
  #
71
71
  # but do note that several items there are debatable or specific to
72
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
@@ -203,12 +203,27 @@ module Minitest
203
203
 
204
204
  def sanitize_exception e # :nodoc:
205
205
  Marshal.dump e
206
- e
206
+ e # good: use as-is
207
207
  rescue TypeError
208
+ neuter_exception e
209
+ end
210
+
211
+ def neuter_exception e
208
212
  bt = e.backtrace
209
- e = RuntimeError.new "Wrapped undumpable exception for: #{e.class}: #{e.message}"
210
- e.set_backtrace bt
211
- e
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
212
227
  end
213
228
 
214
229
  def with_info_handler &block # :nodoc: