minitest 5.16.3 → 5.25.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -124,6 +124,15 @@ module Minitest::Expectations
124
124
 
125
125
  infect_an_assertion :assert_output, :must_output, :block
126
126
 
127
+ ##
128
+ # See Minitest::Assertions#assert_pattern_match
129
+ #
130
+ # _ { ... }.must_pattern_match [...]
131
+ #
132
+ # :method: must_pattern_match
133
+
134
+ infect_an_assertion :assert_pattern, :must_pattern_match, :block
135
+
127
136
  ##
128
137
  # See Minitest::Assertions#assert_raises
129
138
  #
@@ -283,6 +292,15 @@ module Minitest::Expectations
283
292
 
284
293
  infect_an_assertion :refute_operator, :wont_be, :reverse
285
294
 
295
+ ##
296
+ # See Minitest::Assertions#refute_pattern_match
297
+ #
298
+ # _ { ... }.wont_pattern_match [...]
299
+ #
300
+ # :method: wont_pattern_match
301
+
302
+ infect_an_assertion :refute_pattern, :wont_pattern_match, :block
303
+
286
304
  ##
287
305
  # See Minitest::Assertions#refute_respond_to
288
306
  #
@@ -0,0 +1,16 @@
1
+ require "minitest"
2
+
3
+ ARGV << "--no-plugins"
4
+
5
+ module Minitest
6
+ ##
7
+ # Manually load plugins by name.
8
+
9
+ def self.load *names
10
+ names.each do |name|
11
+ require "minitest/#{name}_plugin"
12
+
13
+ self.extensions << name.to_s
14
+ end
15
+ end
16
+ end
data/lib/minitest/mock.rb CHANGED
@@ -8,9 +8,9 @@ module Minitest # :nodoc:
8
8
  # All mock objects are an instance of Mock
9
9
 
10
10
  class Mock
11
- alias :__respond_to? :respond_to?
11
+ alias __respond_to? respond_to?
12
12
 
13
- overridden_methods = %w[
13
+ overridden_methods = %i[
14
14
  ===
15
15
  class
16
16
  inspect
@@ -23,8 +23,10 @@ module Minitest # :nodoc:
23
23
  to_s
24
24
  ]
25
25
 
26
+ overridden_methods << :singleton_method_added if defined?(::DEBUGGER__)
27
+
26
28
  instance_methods.each do |m|
27
- undef_method m unless overridden_methods.include?(m.to_s) || m =~ /^__/
29
+ undef_method m unless overridden_methods.include?(m) || m =~ /^__/
28
30
  end
29
31
 
30
32
  overridden_methods.map(&:to_sym).each do |method_id|
@@ -55,7 +57,7 @@ module Minitest # :nodoc:
55
57
 
56
58
  ##
57
59
  # Expect that method +name+ is called, optionally with +args+ (and
58
- # +kwargs+ or a +blk+, and returns +retval+.
60
+ # +kwargs+ or a +blk+), and returns +retval+.
59
61
  #
60
62
  # @mock.expect(:meaning_of_life, 42)
61
63
  # @mock.meaning_of_life # => 42
@@ -91,7 +93,7 @@ module Minitest # :nodoc:
91
93
  def expect name, retval, args = [], **kwargs, &blk
92
94
  name = name.to_sym
93
95
 
94
- if block_given?
96
+ if blk then
95
97
  raise ArgumentError, "args ignored when block given" unless args.empty?
96
98
  raise ArgumentError, "kwargs ignored when block given" unless kwargs.empty?
97
99
  @expected_calls[name] << { :retval => retval, :block => blk }
@@ -104,7 +106,7 @@ module Minitest # :nodoc:
104
106
  kwargs = args.pop
105
107
  else
106
108
  unless @@KW_WARNED then
107
- from = caller.first
109
+ from = caller(1..1).first
108
110
  warn "Using MT_KWARGS_HAC\K yet passing kwargs. From #{from}"
109
111
  @@KW_WARNED = true
110
112
  end
@@ -139,7 +141,7 @@ module Minitest # :nodoc:
139
141
 
140
142
  def verify
141
143
  @expected_calls.each do |name, expected|
142
- actual = @actual_calls.fetch(name, nil)
144
+ actual = @actual_calls.fetch name, nil # defaults to []
143
145
  raise MockExpectationError, "expected #{__call name, expected[0]}" unless actual
144
146
  raise MockExpectationError, "expected #{__call name, expected[actual.size]}, got [#{__call name, actual}]" if
145
147
  actual.size < expected.size
@@ -148,9 +150,13 @@ module Minitest # :nodoc:
148
150
  end
149
151
 
150
152
  def method_missing sym, *args, **kwargs, &block # :nodoc:
151
- unless @expected_calls.key?(sym) then
153
+ unless @expected_calls.key? sym then
152
154
  if @delegator && @delegator.respond_to?(sym)
153
- return @delegator.public_send(sym, *args, **kwargs, &block)
155
+ if kwargs.empty? then # FIX: drop this after 2.7 dead
156
+ return @delegator.public_send(sym, *args, &block)
157
+ else
158
+ return @delegator.public_send(sym, *args, **kwargs, &block)
159
+ end
154
160
  else
155
161
  raise NoMethodError, "unmocked method %p, expected one of %p" %
156
162
  [sym, @expected_calls.keys.sort_by(&:to_s)]
@@ -166,9 +172,9 @@ module Minitest # :nodoc:
166
172
  end
167
173
 
168
174
  expected_args, expected_kwargs, retval, val_block =
169
- expected_call.values_at(:args, :kwargs, :retval, :block)
175
+ expected_call.values_at :args, :kwargs, :retval, :block
170
176
 
171
- expected_kwargs = kwargs.map { |ak, av| [ak, Object] }.to_h if
177
+ expected_kwargs = kwargs.to_h { |ak, av| [ak, Object] } if
172
178
  Hash == expected_kwargs
173
179
 
174
180
  if val_block then
@@ -191,7 +197,7 @@ module Minitest # :nodoc:
191
197
  [sym, expected_kwargs.size, kwargs]
192
198
  end
193
199
 
194
- zipped_args = expected_args.zip(args)
200
+ zipped_args = expected_args.zip args
195
201
  fully_matched = zipped_args.all? { |mod, a|
196
202
  mod === a or mod == a
197
203
  }
@@ -206,10 +212,10 @@ module Minitest # :nodoc:
206
212
  raise MockExpectationError, fmt % [sym, expected_kwargs.keys, kwargs.keys]
207
213
  end
208
214
 
209
- zipped_kwargs = expected_kwargs.map { |ek, ev|
215
+ zipped_kwargs = expected_kwargs.to_h { |ek, ev|
210
216
  av = kwargs[ek]
211
217
  [ek, [ev, av]]
212
- }.to_h
218
+ }
213
219
 
214
220
  fully_matched = zipped_kwargs.all? { |ek, (ev, av)|
215
221
  ev === av or ev == av
@@ -222,8 +228,8 @@ module Minitest # :nodoc:
222
228
 
223
229
  @actual_calls[sym] << {
224
230
  :retval => retval,
225
- :args => zipped_args.map { |e, a| e === a ? e : a },
226
- :kwargs => zipped_kwargs.map { |k, (e, a)| [k, e === a ? e : a] }.to_h,
231
+ :args => zipped_args.map { |e, a| e === a ? e : a },
232
+ :kwargs => zipped_kwargs.to_h { |k, (e, a)| [k, e === a ? e : a] },
227
233
  }
228
234
 
229
235
  retval
@@ -232,7 +238,7 @@ module Minitest # :nodoc:
232
238
  def respond_to? sym, include_private = false # :nodoc:
233
239
  return true if @expected_calls.key? sym.to_sym
234
240
  return true if @delegator && @delegator.respond_to?(sym, include_private)
235
- __respond_to?(sym, include_private)
241
+ __respond_to? sym, include_private
236
242
  end
237
243
  end
238
244
  end
@@ -1,5 +1,5 @@
1
1
  module Minitest
2
- module Parallel #:nodoc:
2
+ module Parallel # :nodoc:
3
3
 
4
4
  ##
5
5
  # The engine used to run multiple tests in parallel.
@@ -16,7 +16,7 @@ module Minitest
16
16
 
17
17
  def initialize size
18
18
  @size = size
19
- @queue = Queue.new
19
+ @queue = Thread::Queue.new
20
20
  @pool = nil
21
21
  end
22
22
 
@@ -24,10 +24,10 @@ module Minitest
24
24
  # Start the executor
25
25
 
26
26
  def start
27
- @pool = size.times.map {
28
- Thread.new(@queue) do |queue|
27
+ @pool = Array.new(size) {
28
+ Thread.new @queue do |queue|
29
29
  Thread.current.abort_on_exception = true
30
- while (job = queue.pop)
30
+ while job = queue.pop do
31
31
  klass, method, reporter = job
32
32
  reporter.synchronize { reporter.prerecord klass, method }
33
33
  result = Minitest.run_one_method klass, method
@@ -8,13 +8,13 @@ module Minitest
8
8
  end
9
9
 
10
10
  def self.plugin_pride_init options # :nodoc:
11
- if PrideIO.pride? then
12
- klass = ENV["TERM"] =~ /^xterm|-256color$/ ? PrideLOL : PrideIO
13
- io = klass.new options[:io]
11
+ return unless PrideIO.pride?
14
12
 
15
- self.reporter.reporters.grep(Minitest::Reporter).each do |rep|
16
- rep.io = io if rep.io.tty?
17
- end
13
+ klass = ENV["TERM"] =~ /^xterm|-256color$/ ? PrideLOL : PrideIO
14
+ io = klass.new options[:io]
15
+
16
+ self.reporter.reporters.grep(Minitest::Reporter).each do |rep|
17
+ rep.io = io if rep.io.tty?
18
18
  end
19
19
  end
20
20
 
@@ -59,12 +59,10 @@ module Minitest
59
59
 
60
60
  def print o
61
61
  case o
62
- when "." then
62
+ when ".", "S" then
63
63
  io.print pride o
64
64
  when "E", "F" then
65
65
  io.print "#{ESC}41m#{ESC}37m#{o}#{NND}"
66
- when "S" then
67
- io.print pride o
68
66
  else
69
67
  io.print o
70
68
  end
@@ -72,11 +70,9 @@ module Minitest
72
70
 
73
71
  def puts *o # :nodoc:
74
72
  o.map! { |s|
75
- s.to_s.sub(/Finished/) {
73
+ s.to_s.sub("Finished") {
76
74
  @index = 0
77
- "Fabulous run".split(//).map { |c|
78
- pride(c)
79
- }.join
75
+ "Fabulous run".chars.map { |c| pride(c) }.join
80
76
  }
81
77
  }
82
78
 
@@ -113,19 +109,16 @@ module Minitest
113
109
  #
114
110
  # plot (3*sin(x)+3), (3*sin(x+2*pi/3)+3), (3*sin(x+4*pi/3)+3)
115
111
 
116
- # 6 has wide pretty gradients. 3 == lolcat, about half the width
117
- @colors = (0...(6 * 7)).map { |n|
118
- n *= 1.0 / 6
112
+ @colors = Array.new(6 * 7) { |n|
113
+ n *= 1.0 / 3
119
114
  r = (3 * Math.sin(n ) + 3).to_i
120
- g = (3 * Math.sin(n + 2 * PI_3) + 3).to_i
121
- b = (3 * Math.sin(n + 4 * PI_3) + 3).to_i
122
-
123
- # Then we take rgb and encode them in a single number using base 6.
124
- # For some mysterious reason, we add 16... to clear the bottom 4 bits?
125
- # Yes... they're ugly.
115
+ g = (3 * Math.sin(n + 4 * PI_3) + 3).to_i
116
+ b = (3 * Math.sin(n + 2 * PI_3) + 3).to_i
126
117
 
118
+ # Then we take rgb and encode them in a single number using
119
+ # base 6, shifted by 16 for the base 16 ansi colors.
127
120
  36 * r + 6 * g + b + 16
128
- }
121
+ }.rotate(4) # puts "red" first
129
122
 
130
123
  super
131
124
  end
data/lib/minitest/spec.rb CHANGED
@@ -4,7 +4,11 @@ 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
+ target_obj = block ? "_{obj.method}" : "_(obj)"
8
+
9
+ # https://eregon.me/blog/2021/02/13/correct-delegation-in-ruby-2-27-3.html
10
+ # Drop this when we can drop ruby 2.6 (aka after rails 6.1 EOL, ~2024-06)
11
+ kw_extra = "ruby2_keywords %p" % [new_name] if respond_to? :ruby2_keywords, true
8
12
 
9
13
  # warn "%-22p -> %p %p" % [meth, new_name, dont_flip]
10
14
  self.class_eval <<-EOM, __FILE__, __LINE__ + 1
@@ -14,6 +18,7 @@ class Module # :nodoc:
14
18
  Kernel.warn "DEPRECATED: global use of #{new_name} from #\{where}. Use #{target_obj}.#{new_name} instead. This will fail in Minitest 6."
15
19
  Minitest::Expectation.new(self, Minitest::Spec.current).#{new_name}(*args)
16
20
  end
21
+ #{kw_extra}
17
22
  EOM
18
23
 
19
24
  Minitest::Expectation.class_eval <<-EOM, __FILE__, __LINE__ + 1
@@ -28,6 +33,7 @@ class Module # :nodoc:
28
33
  ctx.#{meth}(args.first, target, *args[1..-1])
29
34
  end
30
35
  end
36
+ #{kw_extra}
31
37
  EOM
32
38
  end
33
39
  end
@@ -243,7 +249,7 @@ class Minitest::Spec < Minitest::Test
243
249
  pre, post = "let '#{name}' cannot ", ". Please use another name."
244
250
  methods = Minitest::Spec.instance_methods.map(&:to_s) - %w[subject]
245
251
  raise ArgumentError, "#{pre}begin with 'test'#{post}" if
246
- name =~ /\Atest/
252
+ name.start_with? "test"
247
253
  raise ArgumentError, "#{pre}override a method in Minitest::Spec#{post}" if
248
254
  methods.include? name
249
255
 
@@ -262,7 +268,7 @@ class Minitest::Spec < Minitest::Test
262
268
  end
263
269
 
264
270
  def create name, desc # :nodoc:
265
- cls = Class.new(self) do
271
+ cls = Class.new self do
266
272
  @name = name
267
273
  @desc = desc
268
274
 
@@ -283,7 +289,7 @@ class Minitest::Spec < Minitest::Test
283
289
  end
284
290
 
285
291
  attr_reader :desc # :nodoc:
286
- alias :specify :it
292
+ alias specify it
287
293
 
288
294
  ##
289
295
  # Rdoc... why are you so dumb?
data/lib/minitest/test.rb CHANGED
@@ -18,6 +18,10 @@ module Minitest
18
18
 
19
19
  PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, SystemExit] # :nodoc:
20
20
 
21
+ SETUP_METHODS = %w[ before_setup setup after_setup ] # :nodoc:
22
+
23
+ TEARDOWN_METHODS = %w[ before_teardown teardown after_teardown ] # :nodoc:
24
+
21
25
  # :stopdoc:
22
26
  class << self; attr_accessor :io_lock; end
23
27
  self.io_lock = Mutex.new
@@ -48,9 +52,10 @@ module Minitest
48
52
  end
49
53
 
50
54
  ##
51
- # Call this at the top of your tests when you want to run your
52
- # tests in parallel. In doing so, you're admitting that you rule
53
- # and your tests are awesome.
55
+ # Call this at the top of your tests (inside the +Minitest::Test+
56
+ # subclass or +describe+ block) when you want to run your tests in
57
+ # parallel. In doing so, you're admitting that you rule and your
58
+ # tests are awesome.
54
59
 
55
60
  def self.parallelize_me!
56
61
  include Minitest::Parallel::Test
@@ -76,32 +81,22 @@ module Minitest
76
81
  end
77
82
  end
78
83
 
79
- ##
80
- # Defines the order to run tests (:random by default). Override
81
- # this or use a convenience method to change it for your tests.
82
-
83
- def self.test_order
84
- :random
85
- end
86
-
87
- TEARDOWN_METHODS = %w[ before_teardown teardown after_teardown ] # :nodoc:
88
-
89
84
  ##
90
85
  # Runs a single test with setup/teardown hooks.
91
86
 
92
87
  def run
93
- with_info_handler do
94
- time_it do
95
- capture_exceptions do
96
- before_setup; setup; after_setup
97
-
98
- self.send self.name
88
+ time_it do
89
+ capture_exceptions do
90
+ SETUP_METHODS.each do |hook|
91
+ self.send hook
99
92
  end
100
93
 
101
- TEARDOWN_METHODS.each do |hook|
102
- capture_exceptions do
103
- self.send hook
104
- end
94
+ self.send self.name
95
+ end
96
+
97
+ TEARDOWN_METHODS.each do |hook|
98
+ capture_exceptions do
99
+ self.send hook
105
100
  end
106
101
  end
107
102
  end
@@ -145,7 +140,7 @@ module Minitest
145
140
  # end
146
141
  # end
147
142
  #
148
- # class MiniTest::Test
143
+ # class Minitest::Test
149
144
  # include MyMinitestPlugin
150
145
  # end
151
146
 
@@ -208,7 +203,7 @@ module Minitest
208
203
  neuter_exception e
209
204
  end
210
205
 
211
- def neuter_exception e
206
+ def neuter_exception e # :nodoc:
212
207
  bt = e.backtrace
213
208
  msg = e.message.dup
214
209
 
@@ -219,7 +214,7 @@ module Minitest
219
214
  new_exception RuntimeError, msg, bt, true # but if this raises, we die
220
215
  end
221
216
 
222
- def new_exception klass, msg, bt, kill = false
217
+ def new_exception klass, msg, bt, kill = false # :nodoc:
223
218
  ne = klass.new msg
224
219
  ne.set_backtrace bt
225
220
 
@@ -233,20 +228,10 @@ module Minitest
233
228
  ne
234
229
  end
235
230
 
236
- def with_info_handler &block # :nodoc:
237
- t0 = Minitest.clock_time
238
-
239
- handler = lambda do
240
- warn "\nCurrent: %s#%s %.2fs" % [self.class, self.name, Minitest.clock_time - t0]
241
- end
242
-
243
- self.class.on_signal ::Minitest.info_signal, handler, &block
244
- end
245
-
246
231
  include LifecycleHooks
247
232
  include Guard
248
233
  extend Guard
249
234
  end # Test
250
235
  end
251
236
 
252
- require "minitest/unit" unless defined?(MiniTest) # compatibility layer only
237
+ require "minitest/unit" if ENV["MT_COMPAT"] # compatibility layer only
@@ -1,6 +1,12 @@
1
1
  require "shellwords"
2
2
  require "rbconfig"
3
- require "rake/tasklib"
3
+
4
+ begin
5
+ require "rake/tasklib"
6
+ rescue LoadError => e
7
+ warn e.message
8
+ return
9
+ end
4
10
 
5
11
  module Minitest # :nodoc:
6
12
 
@@ -29,6 +35,10 @@ module Minitest # :nodoc:
29
35
  # end
30
36
  #
31
37
  # Customize the name and only run unit tests.
38
+ #
39
+ # NOTE: To hook this task up to the default, make it a dependency:
40
+ #
41
+ # task default: :unit
32
42
 
33
43
  class TestTask < Rake::TaskLib
34
44
  WINDOWS = RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ # :nodoc:
@@ -110,7 +120,7 @@ module Minitest # :nodoc:
110
120
  self.test_globs = ["test/**/test_*.rb",
111
121
  "test/**/*_test.rb"]
112
122
  self.test_prelude = nil
113
- self.verbose = Rake.application.options.trace
123
+ self.verbose = Rake.application.options.trace || Rake.verbose == true
114
124
  self.warning = true
115
125
  end
116
126
 
@@ -140,7 +150,7 @@ module Minitest # :nodoc:
140
150
  ENV["N"] && ENV["N"].to_i > 0
141
151
 
142
152
  lib_extras = (ENV["MT_LIB_EXTRAS"] || "").split File::PATH_SEPARATOR
143
- self.libs[0,0] = lib_extras
153
+ self.libs[0, 0] = lib_extras
144
154
 
145
155
  extra_args << "-n" << ENV["N"] if ENV["N"]
146
156
  extra_args << "-e" << ENV["X"] if ENV["X"]
@@ -157,11 +167,9 @@ module Minitest # :nodoc:
157
167
  end
158
168
 
159
169
  def define # :nodoc:
160
- default_tasks = []
161
-
162
170
  desc "Run the test suite. Use N, X, A, and TESTOPTS to add flags/args."
163
171
  task name do
164
- ruby make_test_cmd, verbose:verbose
172
+ ruby make_test_cmd, verbose: verbose
165
173
  end
166
174
 
167
175
  desc "Print out the test command. Good for profiling and other tools."
@@ -175,7 +183,7 @@ module Minitest # :nodoc:
175
183
 
176
184
  # 3 seems to be the magic number... (tho not by that much)
177
185
  bad, good, n = {}, [], (ENV.delete("K") || 3).to_i
178
- file = ENV.delete("F")
186
+ file = ENV.delete "F"
179
187
  times = {}
180
188
 
181
189
  tt0 = Time.now
@@ -236,18 +244,13 @@ module Minitest # :nodoc:
236
244
 
237
245
  task "#{name}:deps" => "#{name}:isolated" # now just an alias
238
246
 
239
- desc "Show bottom 25 tests wrt time."
247
+ desc "Run the test suite and report the slowest 25 tests."
240
248
  task "#{name}:slow" do
241
249
  sh ["rake #{name} A=-v",
242
250
  "egrep '#test_.* s = .'",
243
251
  "sort -n -k2 -t=",
244
252
  "tail -25"].join " | "
245
253
  end
246
-
247
- default_tasks << name
248
-
249
- desc "Run the default task(s)."
250
- task :default => default_tasks
251
254
  end
252
255
 
253
256
  ##
@@ -265,11 +268,11 @@ module Minitest # :nodoc:
265
268
  runner = runner.join "; "
266
269
 
267
270
  args = []
268
- args << "-I#{libs.join(File::PATH_SEPARATOR)}" unless libs.empty?
271
+ args << "-I#{libs.join File::PATH_SEPARATOR}" unless libs.empty?
269
272
  args << "-w" if warning
270
- args << '-e'
273
+ args << "-e"
271
274
  args << "'#{runner}'"
272
- args << '--'
275
+ args << "--"
273
276
  args << extra_args.map(&:shellescape)
274
277
 
275
278
  args.join " "
@@ -277,8 +280,8 @@ module Minitest # :nodoc:
277
280
  end
278
281
  end
279
282
 
280
- class Work < Queue
281
- def initialize jobs = []
283
+ class Work < Queue # :nodoc:
284
+ def initialize jobs = [] # :nodoc:
282
285
  super()
283
286
 
284
287
  jobs.each do |job|
@@ -289,12 +292,11 @@ class Work < Queue
289
292
  end
290
293
  end
291
294
 
292
- class Integer
293
- def threads_do(jobs) # :nodoc:
294
- require "thread"
295
+ class Integer # :nodoc:
296
+ def threads_do jobs # :nodoc:
295
297
  q = Work.new jobs
296
298
 
297
- self.times.map {
299
+ Array.new(self) {
298
300
  Thread.new do
299
301
  while job = q.pop # go until quit value
300
302
  yield job