minitest 5.15.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d7d16c7decb91ba01a888704bd527d1e5569454b444fe1b4e41a8a3a7db7406
4
- data.tar.gz: 1ee0d2823a94b63b8cd019198fe2ca20a5c3d9d7bf4918148bdfa543fb65945d
3
+ metadata.gz: 9253f08ed8cc9ec5b362ff80aee1be1b0b0d7873fea50c97893d2e62ef013fd2
4
+ data.tar.gz: e674a1a6f27a4bb130b735585f31658efdec0bb4eae4140e63f1bc30a5d59779
5
5
  SHA512:
6
- metadata.gz: 933a300969aa30dc8f254952dd17f9975cb1f3aad9c10c96260394d088b76900273773374b5ed72731356f2b7f1cfeb131583ae943322250a60401e554e11f45
7
- data.tar.gz: 24a356e1d3c06e28d03860b4dca92d17b88979ebad6316fe97298207c58b29b0ae207657d0044a43ede1bf9a27ac43ca8c779e24fc9ca5ed4c920beca2eaf143
6
+ metadata.gz: 925355cd00438e04a789b67a4c79796c590d4d18a2e0bedf33592d471a6c3586a77aec61fec8882099ab3980ccb4e9be87de7dd31c6ae9d938f39a13188788f7
7
+ data.tar.gz: 48e0507f508e989bf2a6dbe137114377b4cb552041d52a1cf232feb062ab6bcfb43097e551f061c23a35fce074093ddbe5259c9a51dbee7e88d10843c15db2f8
checksums.yaml.gz.sig CHANGED
Binary file
data/History.rdoc CHANGED
@@ -1,3 +1,30 @@
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
+
1
28
  === 5.15.0 / 2021-12-14
2
29
 
3
30
  * 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
@@ -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
@@ -211,30 +250,38 @@ class Object
211
250
  # NOTE: keyword args in callables are NOT checked for correctness
212
251
  # against the existing method. Too many edge cases to be worth it.
213
252
 
214
- def stub name, val_or_callable, *block_args
253
+ def stub name, val_or_callable, *block_args, **block_kwargs
215
254
  new_name = "__minitest_stub__#{name}"
216
255
 
217
256
  metaclass = class << self; self; end
218
257
 
219
258
  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)
259
+ metaclass.send :define_method, name do |*args, **kwargs|
260
+ super(*args, **kwargs)
222
261
  end
223
262
  end
224
263
 
225
264
  metaclass.send :alias_method, new_name, name
226
265
 
227
- metaclass.send :define_method, name do |*args, &blk|
266
+ metaclass.send :define_method, name do |*args, **kwargs, &blk|
228
267
  if val_or_callable.respond_to? :call then
229
- 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
230
273
  else
231
- 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
232
281
  val_or_callable
233
282
  end
234
283
  end
235
284
 
236
- metaclass.send(:ruby2_keywords, name) if metaclass.respond_to?(:ruby2_keywords, true)
237
-
238
285
  yield self
239
286
  ensure
240
287
  metaclass.send :undef_method, 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: