minitest 5.20.0 → 5.27.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 +4 -4
- data/History.rdoc +206 -3
- data/Manifest.txt +3 -0
- data/README.rdoc +30 -17
- data/Rakefile +24 -2
- data/design_rationale.rb +21 -19
- data/lib/hoe/minitest.rb +4 -2
- data/lib/minitest/assertions.rb +92 -100
- data/lib/minitest/autorun.rb +4 -11
- data/lib/minitest/benchmark.rb +8 -11
- data/lib/minitest/compress.rb +94 -0
- data/lib/minitest/error_on_warning.rb +11 -0
- data/lib/minitest/expectations.rb +2 -2
- data/lib/minitest/hell.rb +1 -1
- data/lib/minitest/manual_plugins.rb +16 -0
- data/lib/minitest/mock.rb +44 -44
- data/lib/minitest/parallel.rb +7 -5
- data/lib/minitest/pride.rb +1 -1
- data/lib/minitest/pride_plugin.rb +17 -24
- data/lib/minitest/spec.rb +22 -18
- data/lib/minitest/test.rb +19 -29
- data/lib/minitest/test_task.rb +45 -23
- data/lib/minitest/unit.rb +1 -1
- data/lib/minitest.rb +289 -160
- data/test/minitest/metametameta.rb +32 -18
- data/test/minitest/test_minitest_assertions.rb +173 -197
- data/test/minitest/test_minitest_benchmark.rb +1 -1
- data/test/minitest/test_minitest_mock.rb +156 -89
- data/test/minitest/test_minitest_reporter.rb +120 -24
- data/test/minitest/test_minitest_spec.rb +95 -82
- data/test/minitest/test_minitest_test.rb +212 -120
- data/test/minitest/test_minitest_test_task.rb +18 -7
- data.tar.gz.sig +0 -0
- metadata +36 -22
- metadata.gz.sig +0 -0
data/lib/minitest.rb
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
require "optparse"
|
|
2
|
-
require "thread"
|
|
3
|
-
require "mutex_m"
|
|
4
|
-
require "minitest/parallel"
|
|
5
2
|
require "stringio"
|
|
6
3
|
require "etc"
|
|
7
4
|
|
|
5
|
+
require_relative "minitest/parallel"
|
|
6
|
+
require_relative "minitest/compress"
|
|
7
|
+
|
|
8
8
|
##
|
|
9
|
-
#
|
|
9
|
+
# The top-level namespace for Minitest. Also the location of the main
|
|
10
|
+
# runtime. See +Minitest.run+ for more information.
|
|
10
11
|
|
|
11
12
|
module Minitest
|
|
12
|
-
VERSION = "5.
|
|
13
|
+
VERSION = "5.26.2" # :nodoc:
|
|
13
14
|
|
|
14
15
|
@@installed_at_exit ||= false
|
|
15
16
|
@@after_run = []
|
|
@@ -35,7 +36,7 @@ module Minitest
|
|
|
35
36
|
warn "DEPRECATED: use MT_CPU instead of N for parallel test runs" if ENV["N"] && ENV["N"].to_i > 0
|
|
36
37
|
n_threads = (ENV["MT_CPU"] || ENV["N"] || Etc.nprocessors).to_i
|
|
37
38
|
|
|
38
|
-
self.parallel_executor = Parallel::Executor.new n_threads
|
|
39
|
+
self.parallel_executor = Parallel::Executor.new n_threads if n_threads > 1
|
|
39
40
|
|
|
40
41
|
##
|
|
41
42
|
# Filter object for backtraces.
|
|
@@ -67,9 +68,7 @@ module Minitest
|
|
|
67
68
|
# Registers Minitest to run at process exit
|
|
68
69
|
|
|
69
70
|
def self.autorun
|
|
70
|
-
|
|
71
|
-
Warning[:deprecated] = true
|
|
72
|
-
end
|
|
71
|
+
Warning[:deprecated] = true
|
|
73
72
|
|
|
74
73
|
at_exit {
|
|
75
74
|
next if $! and not ($!.kind_of? SystemExit and $!.success?)
|
|
@@ -98,20 +97,19 @@ module Minitest
|
|
|
98
97
|
@@after_run << block
|
|
99
98
|
end
|
|
100
99
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
100
|
+
##
|
|
101
|
+
# Register a plugin to be used. Does NOT require / load it.
|
|
102
|
+
|
|
103
|
+
def self.register_plugin name_or_mod
|
|
104
|
+
self.extensions << name_or_mod
|
|
105
|
+
nil
|
|
106
106
|
end
|
|
107
107
|
|
|
108
108
|
def self.load_plugins # :nodoc:
|
|
109
|
-
return unless
|
|
109
|
+
return unless defined? Gem
|
|
110
110
|
|
|
111
111
|
seen = {}
|
|
112
112
|
|
|
113
|
-
require "rubygems" unless defined? Gem
|
|
114
|
-
|
|
115
113
|
Gem.find_files("minitest/*_plugin.rb").each do |plugin_path|
|
|
116
114
|
name = File.basename plugin_path, "_plugin.rb"
|
|
117
115
|
|
|
@@ -123,100 +121,65 @@ module Minitest
|
|
|
123
121
|
end
|
|
124
122
|
end
|
|
125
123
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
# klass.new(runnable_method).run
|
|
142
|
-
|
|
143
|
-
def self.run args = []
|
|
144
|
-
self.load_plugins unless args.delete("--no-plugins") || ENV["MT_NO_PLUGINS"]
|
|
145
|
-
|
|
146
|
-
options = process_args args
|
|
147
|
-
|
|
148
|
-
Minitest.seed = options[:seed]
|
|
149
|
-
srand Minitest.seed
|
|
150
|
-
|
|
151
|
-
reporter = CompositeReporter.new
|
|
152
|
-
reporter << SummaryReporter.new(options[:io], options)
|
|
153
|
-
reporter << ProgressReporter.new(options[:io], options)
|
|
154
|
-
|
|
155
|
-
self.reporter = reporter # this makes it available to plugins
|
|
156
|
-
self.init_plugins options
|
|
157
|
-
self.reporter = nil # runnables shouldn't depend on the reporter, ever
|
|
158
|
-
|
|
159
|
-
self.parallel_executor.start if parallel_executor.respond_to?(:start)
|
|
160
|
-
reporter.start
|
|
161
|
-
begin
|
|
162
|
-
__run reporter, options
|
|
163
|
-
rescue Interrupt
|
|
164
|
-
warn "Interrupted. Exiting..."
|
|
124
|
+
def self.init_plugins options # :nodoc:
|
|
125
|
+
self.extensions.each do |mod_or_meth|
|
|
126
|
+
case mod_or_meth
|
|
127
|
+
when Symbol, String then
|
|
128
|
+
name = mod_or_meth
|
|
129
|
+
msg = "plugin_#{name}_init"
|
|
130
|
+
next unless self.respond_to? msg
|
|
131
|
+
send msg, options
|
|
132
|
+
when Module then
|
|
133
|
+
recv = mod_or_meth
|
|
134
|
+
next unless recv.respond_to? :minitest_plugin_init
|
|
135
|
+
recv.minitest_plugin_init options
|
|
136
|
+
else
|
|
137
|
+
raise ArgumentError, "plugin is %p, but it must be a symbol, string or module" % [mod_or_meth]
|
|
138
|
+
end
|
|
165
139
|
end
|
|
166
|
-
self.parallel_executor.shutdown
|
|
167
|
-
reporter.report
|
|
168
|
-
|
|
169
|
-
reporter.passed?
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
##
|
|
173
|
-
# Internal run method. Responsible for telling all Runnable
|
|
174
|
-
# sub-classes to run.
|
|
175
|
-
|
|
176
|
-
def self.__run reporter, options
|
|
177
|
-
suites = Runnable.runnables.shuffle
|
|
178
|
-
parallel, serial = suites.partition { |s| s.test_order == :parallel }
|
|
179
|
-
|
|
180
|
-
# If we run the parallel tests before the serial tests, the parallel tests
|
|
181
|
-
# could run in parallel with the serial tests. This would be bad because
|
|
182
|
-
# the serial tests won't lock around Reporter#record. Run the serial tests
|
|
183
|
-
# first, so that after they complete, the parallel tests will lock when
|
|
184
|
-
# recording results.
|
|
185
|
-
serial.map { |suite| suite.run reporter, options } +
|
|
186
|
-
parallel.map { |suite| suite.run reporter, options }
|
|
187
140
|
end
|
|
188
141
|
|
|
189
142
|
def self.process_args args = [] # :nodoc:
|
|
190
143
|
options = {
|
|
191
|
-
|
|
144
|
+
:io => $stdout,
|
|
192
145
|
}
|
|
193
146
|
orig_args = args.dup
|
|
194
147
|
|
|
195
148
|
OptionParser.new do |opts|
|
|
196
|
-
opts.
|
|
149
|
+
opts.program_name = "minitest"
|
|
197
150
|
opts.version = Minitest::VERSION
|
|
198
151
|
|
|
152
|
+
opts.banner = [
|
|
153
|
+
"Usage: rake test [A=options] (see Minitest::TestTask for more options)",
|
|
154
|
+
"minitest [paths] [options] (with minitest-sprint gem)",
|
|
155
|
+
"ruby path/to/test.rb [options]\n\n",
|
|
156
|
+
].join "\n or: "
|
|
157
|
+
|
|
199
158
|
opts.on "-h", "--help", "Display this help." do
|
|
200
159
|
puts opts
|
|
201
160
|
exit
|
|
202
161
|
end
|
|
203
162
|
|
|
204
|
-
opts.on "--no-plugins", "Bypass minitest plugin auto-loading (or
|
|
163
|
+
opts.on "--no-plugins", "Bypass minitest plugin auto-loading (or env: MT_NO_PLUGINS=1)."
|
|
205
164
|
|
|
206
|
-
desc = "Sets random seed. Also via env
|
|
165
|
+
desc = "Sets random seed. Also via env, eg: SEED=42"
|
|
207
166
|
opts.on "-s", "--seed SEED", Integer, desc do |m|
|
|
208
|
-
options[:seed] = m
|
|
167
|
+
options[:seed] = m
|
|
209
168
|
end
|
|
210
169
|
|
|
211
|
-
opts.on "-v", "--verbose", "Verbose.
|
|
170
|
+
opts.on "-v", "--verbose", "Verbose. Print each name as they run." do
|
|
212
171
|
options[:verbose] = true
|
|
213
172
|
end
|
|
214
173
|
|
|
174
|
+
opts.on "-q", "--quiet", "Quiet. Show no dots while processing files." do
|
|
175
|
+
options[:quiet] = true
|
|
176
|
+
end
|
|
177
|
+
|
|
215
178
|
opts.on "--show-skips", "Show skipped at the end of run." do
|
|
216
179
|
options[:show_skips] = true
|
|
217
180
|
end
|
|
218
181
|
|
|
219
|
-
opts.on "-n", "--name PATTERN", "
|
|
182
|
+
opts.on "-n", "--name PATTERN", "Include /regexp/ or string for run." do |a|
|
|
220
183
|
options[:filter] = a
|
|
221
184
|
end
|
|
222
185
|
|
|
@@ -224,17 +187,48 @@ module Minitest
|
|
|
224
187
|
options[:exclude] = a
|
|
225
188
|
end
|
|
226
189
|
|
|
190
|
+
# part of my unofficial embedded gem "makeoptparseworkwell"
|
|
191
|
+
def opts.topdict(name) = (name.length > 1 ? top.long : top.short)
|
|
192
|
+
def opts.alias(from, to) = (dict = topdict(from) ; dict[to] = dict[from])
|
|
193
|
+
|
|
194
|
+
# these will work but won't show up in --help output:
|
|
195
|
+
opts.alias "name", "include"
|
|
196
|
+
opts.alias "n", "i"
|
|
197
|
+
opts.alias "e", "x"
|
|
198
|
+
|
|
227
199
|
opts.on "-S", "--skip CODES", String, "Skip reporting of certain types of results (eg E)." do |s|
|
|
228
200
|
options[:skip] = s.chars.to_a
|
|
229
201
|
end
|
|
230
202
|
|
|
203
|
+
opts.on "-W[error]", String, "Turn Ruby warnings into errors" do |s|
|
|
204
|
+
options[:Werror] = true
|
|
205
|
+
case s
|
|
206
|
+
when "error", "all", nil then
|
|
207
|
+
require_relative "minitest/error_on_warning"
|
|
208
|
+
$VERBOSE = true
|
|
209
|
+
::Warning[:deprecated] = true
|
|
210
|
+
else
|
|
211
|
+
::Warning[s.to_sym] = true # check validity of category
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
231
215
|
unless extensions.empty?
|
|
232
216
|
opts.separator ""
|
|
233
|
-
opts.separator "Known extensions: #{extensions.join
|
|
234
|
-
|
|
235
|
-
extensions.each do |
|
|
236
|
-
|
|
237
|
-
|
|
217
|
+
opts.separator "Known extensions: #{extensions.join ", "}"
|
|
218
|
+
|
|
219
|
+
extensions.each do |mod_or_meth|
|
|
220
|
+
case mod_or_meth
|
|
221
|
+
when Symbol, String then
|
|
222
|
+
meth = mod_or_meth
|
|
223
|
+
msg = "plugin_#{meth}_options"
|
|
224
|
+
send msg, opts, options if respond_to? msg
|
|
225
|
+
when Module
|
|
226
|
+
recv = mod_or_meth
|
|
227
|
+
next unless recv.respond_to? :minitest_plugin_options
|
|
228
|
+
recv.minitest_plugin_options opts, options
|
|
229
|
+
else
|
|
230
|
+
raise ArgumentError, "plugin is %p, but it must be a symbol, string or module" % [mod_or_meth]
|
|
231
|
+
end
|
|
238
232
|
end
|
|
239
233
|
end
|
|
240
234
|
|
|
@@ -258,12 +252,101 @@ module Minitest
|
|
|
258
252
|
end
|
|
259
253
|
|
|
260
254
|
options[:args] = orig_args.map { |s|
|
|
261
|
-
s
|
|
255
|
+
s.match?(/[\s|&<>$()]/) ? s.inspect : s
|
|
262
256
|
}.join " "
|
|
263
257
|
|
|
264
258
|
options
|
|
265
259
|
end
|
|
266
260
|
|
|
261
|
+
##
|
|
262
|
+
# This is the top-level run method. Everything starts from here. It
|
|
263
|
+
# tells each Runnable sub-class to run, and each of those are
|
|
264
|
+
# responsible for doing whatever they do.
|
|
265
|
+
#
|
|
266
|
+
# The overall structure of a run looks like this:
|
|
267
|
+
#
|
|
268
|
+
# Minitest.autorun
|
|
269
|
+
# Minitest.run(args)
|
|
270
|
+
# Minitest.load_plugins
|
|
271
|
+
# Minitest.process_args
|
|
272
|
+
# Minitest.init_plugins
|
|
273
|
+
# Minitest.__run(reporter, options)
|
|
274
|
+
# Runnable.runnables.each |runnable_klass|
|
|
275
|
+
# runnable_klass.run(reporter, options)
|
|
276
|
+
# filtered_methods = runnable_methods.select {...}.reject {...}
|
|
277
|
+
# filtered_methods.each |runnable_method|
|
|
278
|
+
# runnable_klass.run_one_method(self, runnable_method, reporter)
|
|
279
|
+
# Minitest.run_one_method(runnable_klass, runnable_method)
|
|
280
|
+
# runnable_klass.new(runnable_method).run
|
|
281
|
+
|
|
282
|
+
def self.run args = []
|
|
283
|
+
self.load_plugins unless args.delete("--no-plugins") || ENV["MT_NO_PLUGINS"]
|
|
284
|
+
|
|
285
|
+
options = process_args args
|
|
286
|
+
|
|
287
|
+
Minitest.seed = options[:seed]
|
|
288
|
+
srand Minitest.seed
|
|
289
|
+
|
|
290
|
+
reporter = CompositeReporter.new
|
|
291
|
+
reporter << SummaryReporter.new(options[:io], options)
|
|
292
|
+
reporter << ProgressReporter.new(options[:io], options) unless options[:quiet]
|
|
293
|
+
|
|
294
|
+
self.reporter = reporter # this makes it available to plugins
|
|
295
|
+
self.init_plugins options
|
|
296
|
+
self.reporter = nil # runnables shouldn't depend on the reporter, ever
|
|
297
|
+
|
|
298
|
+
self.parallel_executor.start if parallel_executor.respond_to? :start
|
|
299
|
+
reporter.start
|
|
300
|
+
begin
|
|
301
|
+
__run reporter, options
|
|
302
|
+
finished = true
|
|
303
|
+
rescue Interrupt
|
|
304
|
+
warn "Interrupted. Exiting..."
|
|
305
|
+
end
|
|
306
|
+
self.parallel_executor.shutdown if parallel_executor.respond_to? :shutdown
|
|
307
|
+
|
|
308
|
+
# might have been removed/replaced during init_plugins:
|
|
309
|
+
summary = reporter.reporters.grep(SummaryReporter).first
|
|
310
|
+
|
|
311
|
+
reporter.report
|
|
312
|
+
|
|
313
|
+
return empty_run! options if finished && summary && summary.count == 0
|
|
314
|
+
finished and reporter.passed?
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def self.empty_run! options # :nodoc:
|
|
318
|
+
filter = options[:filter]
|
|
319
|
+
return true unless filter # no filter, but nothing ran == success
|
|
320
|
+
|
|
321
|
+
warn "Nothing ran for filter: %s" % [filter]
|
|
322
|
+
|
|
323
|
+
require "did_you_mean" # soft dependency, punt if it doesn't load
|
|
324
|
+
|
|
325
|
+
ms = Runnable.runnables.flat_map(&:runnable_methods)
|
|
326
|
+
cs = DidYouMean::SpellChecker.new(dictionary: ms).correct filter
|
|
327
|
+
|
|
328
|
+
warn DidYouMean::Formatter.message_for cs unless cs.empty?
|
|
329
|
+
rescue LoadError
|
|
330
|
+
# do nothing
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
##
|
|
334
|
+
# Internal run method. Responsible for telling all Runnable
|
|
335
|
+
# sub-classes to run.
|
|
336
|
+
|
|
337
|
+
def self.__run reporter, options
|
|
338
|
+
suites = Runnable.runnables.shuffle
|
|
339
|
+
parallel, serial = suites.partition { |s| s.test_order == :parallel }
|
|
340
|
+
|
|
341
|
+
# If we run the parallel tests before the serial tests, the parallel tests
|
|
342
|
+
# could run in parallel with the serial tests. This would be bad because
|
|
343
|
+
# the serial tests won't lock around Reporter#record. Run the serial tests
|
|
344
|
+
# first, so that after they complete, the parallel tests will lock when
|
|
345
|
+
# recording results.
|
|
346
|
+
serial.map { |suite| suite.run reporter, options } +
|
|
347
|
+
parallel.map { |suite| suite.run reporter, options }
|
|
348
|
+
end
|
|
349
|
+
|
|
267
350
|
def self.filter_backtrace bt # :nodoc:
|
|
268
351
|
result = backtrace_filter.filter bt
|
|
269
352
|
result = bt.dup if result.empty?
|
|
@@ -334,30 +417,35 @@ module Minitest
|
|
|
334
417
|
# reporter to record.
|
|
335
418
|
|
|
336
419
|
def self.run reporter, options = {}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
filter = Regexp.new $1 if filter.is_a?(String) && filter =~ %r%/(.*)/%
|
|
340
|
-
|
|
341
|
-
self.runnable_methods.find_all { |m|
|
|
342
|
-
filter === m || filter === "#{self}##{m}"
|
|
343
|
-
}
|
|
344
|
-
else
|
|
345
|
-
self.runnable_methods
|
|
346
|
-
end
|
|
420
|
+
pos = options[:filter]
|
|
421
|
+
neg = options[:exclude]
|
|
347
422
|
|
|
348
|
-
if
|
|
349
|
-
|
|
350
|
-
exclude = Regexp.new $1 if exclude =~ %r%/(.*)/%
|
|
423
|
+
pos = Regexp.new $1 if pos.kind_of?(String) && pos =~ %r%/(.*)/%
|
|
424
|
+
neg = Regexp.new $1 if neg.kind_of?(String) && neg =~ %r%/(.*)/%
|
|
351
425
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
}
|
|
355
|
-
|
|
426
|
+
# at most 1-2% slower than a 1-pass version, stop optimizing this
|
|
427
|
+
filtered_methods = self.runnable_methods
|
|
428
|
+
.select { |m| !pos || pos === m || pos === "#{self}##{m}" }
|
|
429
|
+
.reject { |m| neg && (neg === m || neg === "#{self}##{m}") }
|
|
356
430
|
|
|
357
431
|
return if filtered_methods.empty?
|
|
358
432
|
|
|
433
|
+
t0 = name = nil
|
|
434
|
+
|
|
435
|
+
@_info_handler = lambda do
|
|
436
|
+
unless reporter.passed? then
|
|
437
|
+
warn "Current results:"
|
|
438
|
+
warn reporter.reporters.grep(SummaryReporter).first
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
warn "Current: %s#%s %.2fs" % [self, name, Minitest.clock_time - t0]
|
|
442
|
+
end
|
|
443
|
+
|
|
359
444
|
with_info_handler reporter do
|
|
360
445
|
filtered_methods.each do |method_name|
|
|
446
|
+
name = method_name
|
|
447
|
+
t0 = Minitest.clock_time
|
|
448
|
+
|
|
361
449
|
run_one_method self, method_name, reporter
|
|
362
450
|
end
|
|
363
451
|
end
|
|
@@ -383,16 +471,7 @@ module Minitest
|
|
|
383
471
|
end
|
|
384
472
|
|
|
385
473
|
def self.with_info_handler reporter, &block # :nodoc:
|
|
386
|
-
|
|
387
|
-
unless reporter.passed? then
|
|
388
|
-
warn "Current results:"
|
|
389
|
-
warn ""
|
|
390
|
-
warn reporter.reporters.first
|
|
391
|
-
warn ""
|
|
392
|
-
end
|
|
393
|
-
end
|
|
394
|
-
|
|
395
|
-
on_signal ::Minitest.info_signal, handler, &block
|
|
474
|
+
on_signal ::Minitest.info_signal, @_info_handler, &block
|
|
396
475
|
end
|
|
397
476
|
|
|
398
477
|
SIGNALS = Signal.list # :nodoc:
|
|
@@ -430,7 +509,7 @@ module Minitest
|
|
|
430
509
|
def marshal_dump # :nodoc:
|
|
431
510
|
unless @@marshal_dump_warned then
|
|
432
511
|
warn ["Minitest::Runnable#marshal_dump is deprecated.",
|
|
433
|
-
"You might be violating internals. From", caller.first].join " "
|
|
512
|
+
"You might be violating internals. From", caller(1..1).first].join " "
|
|
434
513
|
@@marshal_dump_warned = true
|
|
435
514
|
end
|
|
436
515
|
|
|
@@ -508,7 +587,7 @@ module Minitest
|
|
|
508
587
|
def skipped?
|
|
509
588
|
raise NotImplementedError, "subclass responsibility"
|
|
510
589
|
end
|
|
511
|
-
end
|
|
590
|
+
end # Runnable
|
|
512
591
|
|
|
513
592
|
##
|
|
514
593
|
# Shared code for anything that can get passed to a Reporter. See
|
|
@@ -525,12 +604,14 @@ module Minitest
|
|
|
525
604
|
not self.failure
|
|
526
605
|
end
|
|
527
606
|
|
|
607
|
+
BASE_DIR = "#{Dir.pwd}/" # :nodoc:
|
|
608
|
+
|
|
528
609
|
##
|
|
529
610
|
# The location identifier of this test. Depends on a method
|
|
530
611
|
# existing called class_name.
|
|
531
612
|
|
|
532
613
|
def location
|
|
533
|
-
loc = " [#{self.failure.location}]" unless passed? or error?
|
|
614
|
+
loc = " [#{self.failure.location.delete_prefix BASE_DIR}]" unless passed? or error?
|
|
534
615
|
"#{self.class_name}##{self.name}#{loc}"
|
|
535
616
|
end
|
|
536
617
|
|
|
@@ -556,9 +637,9 @@ module Minitest
|
|
|
556
637
|
# Did this run error?
|
|
557
638
|
|
|
558
639
|
def error?
|
|
559
|
-
self.failures.any?
|
|
640
|
+
self.failures.any? UnexpectedError
|
|
560
641
|
end
|
|
561
|
-
end
|
|
642
|
+
end # Reportable
|
|
562
643
|
|
|
563
644
|
##
|
|
564
645
|
# This represents a test result in a clean way that can be
|
|
@@ -612,14 +693,17 @@ module Minitest
|
|
|
612
693
|
"#{failure.result_label}:\n#{self.location}:\n#{failure.message}\n"
|
|
613
694
|
}.join "\n"
|
|
614
695
|
end
|
|
615
|
-
end
|
|
696
|
+
end # Result
|
|
616
697
|
|
|
617
698
|
##
|
|
618
699
|
# Defines the API for Reporters. Subclass this and override whatever
|
|
619
700
|
# you want. Go nuts.
|
|
620
701
|
|
|
621
702
|
class AbstractReporter
|
|
622
|
-
|
|
703
|
+
|
|
704
|
+
def initialize # :nodoc:
|
|
705
|
+
@mutex = Mutex.new
|
|
706
|
+
end
|
|
623
707
|
|
|
624
708
|
##
|
|
625
709
|
# Starts reporting on the run.
|
|
@@ -655,7 +739,11 @@ module Minitest
|
|
|
655
739
|
def passed?
|
|
656
740
|
true
|
|
657
741
|
end
|
|
658
|
-
|
|
742
|
+
|
|
743
|
+
def synchronize &block # :nodoc:
|
|
744
|
+
@mutex.synchronize(&block)
|
|
745
|
+
end
|
|
746
|
+
end # AbstractReportera
|
|
659
747
|
|
|
660
748
|
class Reporter < AbstractReporter # :nodoc:
|
|
661
749
|
##
|
|
@@ -684,11 +772,11 @@ module Minitest
|
|
|
684
772
|
# own.
|
|
685
773
|
|
|
686
774
|
class ProgressReporter < Reporter
|
|
687
|
-
def prerecord klass, name
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
775
|
+
def prerecord klass, name # :nodoc:
|
|
776
|
+
return unless options[:verbose]
|
|
777
|
+
|
|
778
|
+
io.print "%s#%s = " % [klass.name, name]
|
|
779
|
+
io.flush
|
|
692
780
|
end
|
|
693
781
|
|
|
694
782
|
def record result # :nodoc:
|
|
@@ -758,6 +846,11 @@ module Minitest
|
|
|
758
846
|
|
|
759
847
|
attr_accessor :errors
|
|
760
848
|
|
|
849
|
+
##
|
|
850
|
+
# Total number of tests that warned.
|
|
851
|
+
|
|
852
|
+
attr_accessor :warnings
|
|
853
|
+
|
|
761
854
|
##
|
|
762
855
|
# Total number of tests that where skipped.
|
|
763
856
|
|
|
@@ -773,6 +866,7 @@ module Minitest
|
|
|
773
866
|
self.total_time = nil
|
|
774
867
|
self.failures = nil
|
|
775
868
|
self.errors = nil
|
|
869
|
+
self.warnings = nil
|
|
776
870
|
self.skips = nil
|
|
777
871
|
end
|
|
778
872
|
|
|
@@ -801,9 +895,10 @@ module Minitest
|
|
|
801
895
|
self.total_time = Minitest.clock_time - start_time
|
|
802
896
|
self.failures = aggregate[Assertion].size
|
|
803
897
|
self.errors = aggregate[UnexpectedError].size
|
|
898
|
+
self.warnings = aggregate[UnexpectedWarning].size
|
|
804
899
|
self.skips = aggregate[Skip].size
|
|
805
900
|
end
|
|
806
|
-
end
|
|
901
|
+
end # StatisticsReporter
|
|
807
902
|
|
|
808
903
|
##
|
|
809
904
|
# A reporter that prints the header, summary, and failure details at
|
|
@@ -815,10 +910,8 @@ module Minitest
|
|
|
815
910
|
# own.
|
|
816
911
|
|
|
817
912
|
class SummaryReporter < StatisticsReporter
|
|
818
|
-
# :
|
|
819
|
-
attr_accessor :
|
|
820
|
-
attr_accessor :old_sync
|
|
821
|
-
# :startdoc:
|
|
913
|
+
attr_accessor :sync # :nodoc:
|
|
914
|
+
attr_accessor :old_sync # :nodoc:
|
|
822
915
|
|
|
823
916
|
def start # :nodoc:
|
|
824
917
|
super
|
|
@@ -828,7 +921,7 @@ module Minitest
|
|
|
828
921
|
io.puts "# Running:"
|
|
829
922
|
io.puts
|
|
830
923
|
|
|
831
|
-
self.sync = io.respond_to? :"sync="
|
|
924
|
+
self.sync = io.respond_to? :"sync="
|
|
832
925
|
self.old_sync, io.sync = io.sync, true if self.sync
|
|
833
926
|
end
|
|
834
927
|
|
|
@@ -866,20 +959,24 @@ module Minitest
|
|
|
866
959
|
end
|
|
867
960
|
|
|
868
961
|
def to_s # :nodoc:
|
|
869
|
-
aggregated_results(StringIO.new(
|
|
962
|
+
aggregated_results(StringIO.new("".b)).string
|
|
870
963
|
end
|
|
871
964
|
|
|
872
965
|
def summary # :nodoc:
|
|
873
|
-
extra =
|
|
966
|
+
extra = []
|
|
967
|
+
|
|
968
|
+
extra << ", %d warnings" % [warnings] if options[:Werror]
|
|
874
969
|
|
|
875
|
-
extra
|
|
970
|
+
extra << "\n\nYou have skipped tests. Run with --verbose for details." if
|
|
876
971
|
results.any?(&:skipped?) unless
|
|
877
|
-
options[:verbose]
|
|
972
|
+
options[:verbose] or
|
|
973
|
+
options[:show_skips] or
|
|
974
|
+
ENV["MT_NO_SKIP_MSG"]
|
|
878
975
|
|
|
879
976
|
"%d runs, %d assertions, %d failures, %d errors, %d skips%s" %
|
|
880
|
-
[count, assertions, failures, errors, skips, extra]
|
|
977
|
+
[count, assertions, failures, errors, skips, extra.join]
|
|
881
978
|
end
|
|
882
|
-
end
|
|
979
|
+
end # SummaryReporter
|
|
883
980
|
|
|
884
981
|
##
|
|
885
982
|
# Dispatch to multiple reporters as one.
|
|
@@ -930,12 +1027,14 @@ module Minitest
|
|
|
930
1027
|
def report # :nodoc:
|
|
931
1028
|
self.reporters.each(&:report)
|
|
932
1029
|
end
|
|
933
|
-
end
|
|
1030
|
+
end # CompositeReporter
|
|
934
1031
|
|
|
935
1032
|
##
|
|
936
1033
|
# Represents run failures.
|
|
937
1034
|
|
|
938
1035
|
class Assertion < Exception
|
|
1036
|
+
RE = /in [`'](?:[^']+[#.])?(?:assert|refute|flunk|pass|fail|raise|must|wont)/ # :nodoc:
|
|
1037
|
+
|
|
939
1038
|
def error # :nodoc:
|
|
940
1039
|
self
|
|
941
1040
|
end
|
|
@@ -944,12 +1043,11 @@ module Minitest
|
|
|
944
1043
|
# Where was this run before an assertion was raised?
|
|
945
1044
|
|
|
946
1045
|
def location
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
last_before_assertion.sub(/:in .*$/, "")
|
|
1046
|
+
bt = Minitest.filter_backtrace self.backtrace
|
|
1047
|
+
idx = bt.rindex { |s| s.match? RE } || -1 # fall back to first item
|
|
1048
|
+
loc = bt[idx+1] || bt.last || "unknown:-1"
|
|
1049
|
+
|
|
1050
|
+
loc.sub(/:in .*$/, "")
|
|
953
1051
|
end
|
|
954
1052
|
|
|
955
1053
|
def result_code # :nodoc:
|
|
@@ -974,11 +1072,21 @@ module Minitest
|
|
|
974
1072
|
# Assertion wrapping an unexpected error that was raised during a run.
|
|
975
1073
|
|
|
976
1074
|
class UnexpectedError < Assertion
|
|
1075
|
+
include Minitest::Compress
|
|
1076
|
+
|
|
977
1077
|
# TODO: figure out how to use `cause` instead
|
|
978
1078
|
attr_accessor :error # :nodoc:
|
|
979
1079
|
|
|
980
1080
|
def initialize error # :nodoc:
|
|
981
1081
|
super "Unexpected exception"
|
|
1082
|
+
|
|
1083
|
+
if SystemStackError === error then
|
|
1084
|
+
bt = error.backtrace
|
|
1085
|
+
new_bt = compress bt
|
|
1086
|
+
error = error.exception "#{bt.size} -> #{new_bt.size}"
|
|
1087
|
+
error.set_backtrace new_bt
|
|
1088
|
+
end
|
|
1089
|
+
|
|
982
1090
|
self.error = error
|
|
983
1091
|
end
|
|
984
1092
|
|
|
@@ -986,8 +1094,11 @@ module Minitest
|
|
|
986
1094
|
self.error.backtrace
|
|
987
1095
|
end
|
|
988
1096
|
|
|
1097
|
+
BASE_RE = %r%#{Regexp.escape Dir.pwd}/% # :nodoc:
|
|
1098
|
+
|
|
989
1099
|
def message # :nodoc:
|
|
990
|
-
bt = Minitest.filter_backtrace(self.backtrace).join
|
|
1100
|
+
bt = Minitest.filter_backtrace(self.backtrace).join("\n ")
|
|
1101
|
+
.gsub(BASE_RE, "")
|
|
991
1102
|
"#{self.error.class}: #{self.error.message}\n #{bt}"
|
|
992
1103
|
end
|
|
993
1104
|
|
|
@@ -996,6 +1107,15 @@ module Minitest
|
|
|
996
1107
|
end
|
|
997
1108
|
end
|
|
998
1109
|
|
|
1110
|
+
##
|
|
1111
|
+
# Assertion raised on warning when running in -Werror mode.
|
|
1112
|
+
|
|
1113
|
+
class UnexpectedWarning < Assertion
|
|
1114
|
+
def result_label # :nodoc:
|
|
1115
|
+
"Warning"
|
|
1116
|
+
end
|
|
1117
|
+
end
|
|
1118
|
+
|
|
999
1119
|
##
|
|
1000
1120
|
# Provides a simple set of guards that you can use in your tests
|
|
1001
1121
|
# to skip execution if it is not applicable. These methods are
|
|
@@ -1025,7 +1145,7 @@ module Minitest
|
|
|
1025
1145
|
|
|
1026
1146
|
def maglev? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
|
|
1027
1147
|
where = Minitest.filter_backtrace(caller).first
|
|
1028
|
-
where = where.split(
|
|
1148
|
+
where = where.split(":in ", 2).first # clean up noise
|
|
1029
1149
|
warn "DEPRECATED: `maglev?` called from #{where}. This will fail in Minitest 6."
|
|
1030
1150
|
"maglev" == platform
|
|
1031
1151
|
end
|
|
@@ -1034,14 +1154,14 @@ module Minitest
|
|
|
1034
1154
|
# Is this running on mri?
|
|
1035
1155
|
|
|
1036
1156
|
def mri? platform = RUBY_DESCRIPTION
|
|
1037
|
-
|
|
1157
|
+
platform.start_with? "ruby"
|
|
1038
1158
|
end
|
|
1039
1159
|
|
|
1040
1160
|
##
|
|
1041
1161
|
# Is this running on macOS?
|
|
1042
1162
|
|
|
1043
1163
|
def osx? platform = RUBY_PLATFORM
|
|
1044
|
-
|
|
1164
|
+
platform.include? "darwin"
|
|
1045
1165
|
end
|
|
1046
1166
|
|
|
1047
1167
|
##
|
|
@@ -1049,7 +1169,7 @@ module Minitest
|
|
|
1049
1169
|
|
|
1050
1170
|
def rubinius? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
|
|
1051
1171
|
where = Minitest.filter_backtrace(caller).first
|
|
1052
|
-
where = where.split(
|
|
1172
|
+
where = where.split(":in ", 2).first # clean up noise
|
|
1053
1173
|
warn "DEPRECATED: `rubinius?` called from #{where}. This will fail in Minitest 6."
|
|
1054
1174
|
"rbx" == platform
|
|
1055
1175
|
end
|
|
@@ -1058,7 +1178,7 @@ module Minitest
|
|
|
1058
1178
|
# Is this running on windows?
|
|
1059
1179
|
|
|
1060
1180
|
def windows? platform = RUBY_PLATFORM
|
|
1061
|
-
/mswin|mingw
|
|
1181
|
+
/mswin|mingw/.match? platform
|
|
1062
1182
|
end
|
|
1063
1183
|
end
|
|
1064
1184
|
|
|
@@ -1069,7 +1189,16 @@ module Minitest
|
|
|
1069
1189
|
|
|
1070
1190
|
class BacktraceFilter
|
|
1071
1191
|
|
|
1072
|
-
MT_RE = %r%lib/minitest%
|
|
1192
|
+
MT_RE = %r%lib/minitest|internal:warning% # :nodoc:
|
|
1193
|
+
|
|
1194
|
+
##
|
|
1195
|
+
# The regular expression to use to filter backtraces. Defaults to +MT_RE+.
|
|
1196
|
+
|
|
1197
|
+
attr_accessor :regexp
|
|
1198
|
+
|
|
1199
|
+
def initialize regexp = MT_RE # :nodoc:
|
|
1200
|
+
self.regexp = regexp
|
|
1201
|
+
end
|
|
1073
1202
|
|
|
1074
1203
|
##
|
|
1075
1204
|
# Filter +bt+ to something useful. Returns the whole thing if
|
|
@@ -1080,9 +1209,9 @@ module Minitest
|
|
|
1080
1209
|
|
|
1081
1210
|
return bt.dup if $DEBUG || ENV["MT_DEBUG"]
|
|
1082
1211
|
|
|
1083
|
-
new_bt = bt.take_while { |line| line
|
|
1084
|
-
new_bt = bt.select { |line| line
|
|
1085
|
-
new_bt = bt.dup
|
|
1212
|
+
new_bt = bt.take_while { |line| !regexp.match? line.to_s }
|
|
1213
|
+
new_bt = bt.select { |line| !regexp.match? line.to_s } if new_bt.empty?
|
|
1214
|
+
new_bt = bt.dup if new_bt.empty?
|
|
1086
1215
|
|
|
1087
1216
|
new_bt
|
|
1088
1217
|
end
|
|
@@ -1118,4 +1247,4 @@ module Minitest
|
|
|
1118
1247
|
# :startdoc:
|
|
1119
1248
|
end
|
|
1120
1249
|
|
|
1121
|
-
|
|
1250
|
+
require_relative "minitest/test"
|