minitest 5.18.0 → 5.25.5
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 +0 -0
- data/History.rdoc +187 -1
- data/Manifest.txt +3 -0
- data/README.rdoc +28 -17
- data/Rakefile +7 -1
- data/lib/hoe/minitest.rb +2 -1
- data/lib/minitest/assertions.rb +77 -80
- data/lib/minitest/autorun.rb +0 -7
- data/lib/minitest/benchmark.rb +6 -9
- 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/manual_plugins.rb +16 -0
- data/lib/minitest/mock.rb +39 -19
- data/lib/minitest/parallel.rb +5 -5
- data/lib/minitest/pride_plugin.rb +16 -23
- data/lib/minitest/spec.rb +13 -12
- data/lib/minitest/test.rb +17 -36
- data/lib/minitest/test_task.rb +21 -19
- data/lib/minitest.rb +298 -141
- data/test/minitest/metametameta.rb +32 -18
- data/test/minitest/test_minitest_assertions.rb +159 -140
- data/test/minitest/test_minitest_benchmark.rb +1 -1
- data/test/minitest/test_minitest_mock.rb +151 -79
- data/test/minitest/test_minitest_reporter.rb +143 -19
- data/test/minitest/test_minitest_spec.rb +73 -56
- data/test/minitest/test_minitest_test.rb +218 -116
- data/test/minitest/test_minitest_test_task.rb +18 -7
- data.tar.gz.sig +0 -0
- metadata +21 -20
- 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.25.5" # :nodoc:
|
13
14
|
|
14
15
|
@@installed_at_exit ||= false
|
15
16
|
@@after_run = []
|
@@ -32,7 +33,7 @@ module Minitest
|
|
32
33
|
|
33
34
|
cattr_accessor :parallel_executor
|
34
35
|
|
35
|
-
warn "DEPRECATED: use MT_CPU instead of N for parallel test runs" if ENV["N"]
|
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
39
|
self.parallel_executor = Parallel::Executor.new n_threads
|
@@ -60,13 +61,15 @@ module Minitest
|
|
60
61
|
cattr_accessor :info_signal
|
61
62
|
self.info_signal = "INFO"
|
62
63
|
|
64
|
+
cattr_accessor :allow_fork
|
65
|
+
self.allow_fork = false
|
66
|
+
|
63
67
|
##
|
64
68
|
# Registers Minitest to run at process exit
|
65
69
|
|
66
70
|
def self.autorun
|
67
|
-
|
68
|
-
Warning[
|
69
|
-
end
|
71
|
+
Warning[:deprecated] = true if
|
72
|
+
Object.const_defined?(:Warning) && Warning.respond_to?(:[]=)
|
70
73
|
|
71
74
|
at_exit {
|
72
75
|
next if $! and not ($!.kind_of? SystemExit and $!.success?)
|
@@ -75,7 +78,7 @@ module Minitest
|
|
75
78
|
|
76
79
|
pid = Process.pid
|
77
80
|
at_exit {
|
78
|
-
next if Process.pid != pid
|
81
|
+
next if !Minitest.allow_fork && Process.pid != pid
|
79
82
|
@@after_run.reverse_each(&:call)
|
80
83
|
exit exit_code || false
|
81
84
|
}
|
@@ -95,20 +98,19 @@ module Minitest
|
|
95
98
|
@@after_run << block
|
96
99
|
end
|
97
100
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
101
|
+
##
|
102
|
+
# Register a plugin to be used. Does NOT require / load it.
|
103
|
+
|
104
|
+
def self.register_plugin name_or_mod
|
105
|
+
self.extensions << name_or_mod
|
106
|
+
nil
|
103
107
|
end
|
104
108
|
|
105
109
|
def self.load_plugins # :nodoc:
|
106
|
-
return unless
|
110
|
+
return unless defined? Gem
|
107
111
|
|
108
112
|
seen = {}
|
109
113
|
|
110
|
-
require "rubygems" unless defined? Gem
|
111
|
-
|
112
114
|
Gem.find_files("minitest/*_plugin.rb").each do |plugin_path|
|
113
115
|
name = File.basename plugin_path, "_plugin.rb"
|
114
116
|
|
@@ -120,72 +122,27 @@ module Minitest
|
|
120
122
|
end
|
121
123
|
end
|
122
124
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
# klass.new(runnable_method).run
|
139
|
-
|
140
|
-
def self.run args = []
|
141
|
-
self.load_plugins unless args.delete("--no-plugins") || ENV["MT_NO_PLUGINS"]
|
142
|
-
|
143
|
-
options = process_args args
|
144
|
-
|
145
|
-
Minitest.seed = options[:seed]
|
146
|
-
srand Minitest.seed
|
147
|
-
|
148
|
-
reporter = CompositeReporter.new
|
149
|
-
reporter << SummaryReporter.new(options[:io], options)
|
150
|
-
reporter << ProgressReporter.new(options[:io], options)
|
151
|
-
|
152
|
-
self.reporter = reporter # this makes it available to plugins
|
153
|
-
self.init_plugins options
|
154
|
-
self.reporter = nil # runnables shouldn't depend on the reporter, ever
|
155
|
-
|
156
|
-
self.parallel_executor.start if parallel_executor.respond_to?(:start)
|
157
|
-
reporter.start
|
158
|
-
begin
|
159
|
-
__run reporter, options
|
160
|
-
rescue Interrupt
|
161
|
-
warn "Interrupted. Exiting..."
|
125
|
+
def self.init_plugins options # :nodoc:
|
126
|
+
self.extensions.each do |mod_or_meth|
|
127
|
+
case mod_or_meth
|
128
|
+
when Symbol, String then
|
129
|
+
name = mod_or_meth
|
130
|
+
msg = "plugin_#{name}_init"
|
131
|
+
next unless self.respond_to? msg
|
132
|
+
send msg, options
|
133
|
+
when Module then
|
134
|
+
recv = mod_or_meth
|
135
|
+
next unless recv.respond_to? :minitest_plugin_init
|
136
|
+
recv.minitest_plugin_init options
|
137
|
+
else
|
138
|
+
raise ArgumentError, "plugin is %p, but it must be a symbol, string or module" % [mod_or_meth]
|
139
|
+
end
|
162
140
|
end
|
163
|
-
self.parallel_executor.shutdown
|
164
|
-
reporter.report
|
165
|
-
|
166
|
-
reporter.passed?
|
167
|
-
end
|
168
|
-
|
169
|
-
##
|
170
|
-
# Internal run method. Responsible for telling all Runnable
|
171
|
-
# sub-classes to run.
|
172
|
-
|
173
|
-
def self.__run reporter, options
|
174
|
-
suites = Runnable.runnables.shuffle
|
175
|
-
parallel, serial = suites.partition { |s| s.test_order == :parallel }
|
176
|
-
|
177
|
-
# If we run the parallel tests before the serial tests, the parallel tests
|
178
|
-
# could run in parallel with the serial tests. This would be bad because
|
179
|
-
# the serial tests won't lock around Reporter#record. Run the serial tests
|
180
|
-
# first, so that after they complete, the parallel tests will lock when
|
181
|
-
# recording results.
|
182
|
-
serial.map { |suite| suite.run reporter, options } +
|
183
|
-
parallel.map { |suite| suite.run reporter, options }
|
184
141
|
end
|
185
142
|
|
186
143
|
def self.process_args args = [] # :nodoc:
|
187
144
|
options = {
|
188
|
-
|
145
|
+
:io => $stdout,
|
189
146
|
}
|
190
147
|
orig_args = args.dup
|
191
148
|
|
@@ -209,6 +166,10 @@ module Minitest
|
|
209
166
|
options[:verbose] = true
|
210
167
|
end
|
211
168
|
|
169
|
+
opts.on "-q", "--quiet", "Quiet. Show no progress processing files." do
|
170
|
+
options[:quiet] = true
|
171
|
+
end
|
172
|
+
|
212
173
|
opts.on "--show-skips", "Show skipped at the end of run." do
|
213
174
|
options[:show_skips] = true
|
214
175
|
end
|
@@ -225,13 +186,37 @@ module Minitest
|
|
225
186
|
options[:skip] = s.chars.to_a
|
226
187
|
end
|
227
188
|
|
189
|
+
ruby27plus = ::Warning.respond_to? :[]=
|
190
|
+
|
191
|
+
opts.on "-W[error]", String, "Turn Ruby warnings into errors" do |s|
|
192
|
+
options[:Werror] = true
|
193
|
+
case s
|
194
|
+
when "error", "all", nil then
|
195
|
+
require "minitest/error_on_warning"
|
196
|
+
$VERBOSE = true
|
197
|
+
::Warning[:deprecated] = true if ruby27plus
|
198
|
+
else
|
199
|
+
::Warning[s.to_sym] = true if ruby27plus # check validity of category
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
228
203
|
unless extensions.empty?
|
229
204
|
opts.separator ""
|
230
|
-
opts.separator "Known extensions: #{extensions.join
|
231
|
-
|
232
|
-
extensions.each do |
|
233
|
-
|
234
|
-
|
205
|
+
opts.separator "Known extensions: #{extensions.join ", "}"
|
206
|
+
|
207
|
+
extensions.each do |mod_or_meth|
|
208
|
+
case mod_or_meth
|
209
|
+
when Symbol, String then
|
210
|
+
meth = mod_or_meth
|
211
|
+
msg = "plugin_#{meth}_options"
|
212
|
+
send msg, opts, options if respond_to? msg
|
213
|
+
when Module
|
214
|
+
recv = mod_or_meth
|
215
|
+
next unless recv.respond_to? :minitest_plugin_options
|
216
|
+
recv.minitest_plugin_options opts, options
|
217
|
+
else
|
218
|
+
raise ArgumentError, "plugin is %p, but it must be a symbol, string or module" % [mod_or_meth]
|
219
|
+
end
|
235
220
|
end
|
236
221
|
end
|
237
222
|
|
@@ -255,12 +240,99 @@ module Minitest
|
|
255
240
|
end
|
256
241
|
|
257
242
|
options[:args] = orig_args.map { |s|
|
258
|
-
s
|
243
|
+
s.match?(/[\s|&<>$()]/) ? s.inspect : s
|
259
244
|
}.join " "
|
260
245
|
|
261
246
|
options
|
262
247
|
end
|
263
248
|
|
249
|
+
##
|
250
|
+
# This is the top-level run method. Everything starts from here. It
|
251
|
+
# tells each Runnable sub-class to run, and each of those are
|
252
|
+
# responsible for doing whatever they do.
|
253
|
+
#
|
254
|
+
# The overall structure of a run looks like this:
|
255
|
+
#
|
256
|
+
# Minitest.autorun
|
257
|
+
# Minitest.run(args)
|
258
|
+
# Minitest.load_plugins
|
259
|
+
# Minitest.process_args
|
260
|
+
# Minitest.init_plugins
|
261
|
+
# Minitest.__run(reporter, options)
|
262
|
+
# Runnable.runnables.each
|
263
|
+
# runnable_klass.run(reporter, options)
|
264
|
+
# self.runnable_methods.each
|
265
|
+
# self.run_one_method(self, runnable_method, reporter)
|
266
|
+
# Minitest.run_one_method(klass, runnable_method)
|
267
|
+
# klass.new(runnable_method).run
|
268
|
+
|
269
|
+
def self.run args = []
|
270
|
+
self.load_plugins unless args.delete("--no-plugins") || ENV["MT_NO_PLUGINS"]
|
271
|
+
|
272
|
+
options = process_args args
|
273
|
+
|
274
|
+
Minitest.seed = options[:seed]
|
275
|
+
srand Minitest.seed
|
276
|
+
|
277
|
+
reporter = CompositeReporter.new
|
278
|
+
reporter << SummaryReporter.new(options[:io], options)
|
279
|
+
reporter << ProgressReporter.new(options[:io], options) unless options[:quiet]
|
280
|
+
|
281
|
+
self.reporter = reporter # this makes it available to plugins
|
282
|
+
self.init_plugins options
|
283
|
+
self.reporter = nil # runnables shouldn't depend on the reporter, ever
|
284
|
+
|
285
|
+
self.parallel_executor.start if parallel_executor.respond_to? :start
|
286
|
+
reporter.start
|
287
|
+
begin
|
288
|
+
__run reporter, options
|
289
|
+
rescue Interrupt
|
290
|
+
warn "Interrupted. Exiting..."
|
291
|
+
end
|
292
|
+
self.parallel_executor.shutdown
|
293
|
+
|
294
|
+
# might have been removed/replaced during init_plugins:
|
295
|
+
summary = reporter.reporters.grep(SummaryReporter).first
|
296
|
+
|
297
|
+
reporter.report
|
298
|
+
|
299
|
+
return empty_run! options if summary && summary.count == 0
|
300
|
+
reporter.passed?
|
301
|
+
end
|
302
|
+
|
303
|
+
def self.empty_run! options # :nodoc:
|
304
|
+
filter = options[:filter]
|
305
|
+
return true unless filter # no filter, but nothing ran == success
|
306
|
+
|
307
|
+
warn "Nothing ran for filter: %s" % [filter]
|
308
|
+
|
309
|
+
require "did_you_mean" # soft dependency, punt if it doesn't load
|
310
|
+
|
311
|
+
ms = Runnable.runnables.flat_map(&:runnable_methods)
|
312
|
+
cs = DidYouMean::SpellChecker.new(dictionary: ms).correct filter
|
313
|
+
|
314
|
+
warn DidYouMean::Formatter.message_for cs unless cs.empty?
|
315
|
+
rescue LoadError
|
316
|
+
# do nothing
|
317
|
+
end
|
318
|
+
|
319
|
+
##
|
320
|
+
# Internal run method. Responsible for telling all Runnable
|
321
|
+
# sub-classes to run.
|
322
|
+
|
323
|
+
def self.__run reporter, options
|
324
|
+
suites = Runnable.runnables.shuffle
|
325
|
+
parallel, serial = suites.partition { |s| s.test_order == :parallel }
|
326
|
+
|
327
|
+
# If we run the parallel tests before the serial tests, the parallel tests
|
328
|
+
# could run in parallel with the serial tests. This would be bad because
|
329
|
+
# the serial tests won't lock around Reporter#record. Run the serial tests
|
330
|
+
# first, so that after they complete, the parallel tests will lock when
|
331
|
+
# recording results.
|
332
|
+
serial.map { |suite| suite.run reporter, options } +
|
333
|
+
parallel.map { |suite| suite.run reporter, options }
|
334
|
+
end
|
335
|
+
|
264
336
|
def self.filter_backtrace bt # :nodoc:
|
265
337
|
result = backtrace_filter.filter bt
|
266
338
|
result = bt.dup if result.empty?
|
@@ -331,24 +403,34 @@ module Minitest
|
|
331
403
|
# reporter to record.
|
332
404
|
|
333
405
|
def self.run reporter, options = {}
|
334
|
-
|
335
|
-
|
406
|
+
pos = options[:filter]
|
407
|
+
neg = options[:exclude]
|
336
408
|
|
337
|
-
|
338
|
-
|
339
|
-
}
|
409
|
+
pos = Regexp.new $1 if pos.kind_of?(String) && pos =~ %r%/(.*)/%
|
410
|
+
neg = Regexp.new $1 if neg.kind_of?(String) && neg =~ %r%/(.*)/%
|
340
411
|
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
filtered_methods.delete_if { |m|
|
345
|
-
exclude === m || exclude === "#{self}##{m}"
|
346
|
-
}
|
412
|
+
filtered_methods = self.runnable_methods
|
413
|
+
.select { |m| !pos || pos === m || pos === "#{self}##{m}" }
|
414
|
+
.reject { |m| neg && (neg === m || neg === "#{self}##{m}") }
|
347
415
|
|
348
416
|
return if filtered_methods.empty?
|
349
417
|
|
418
|
+
t0 = name = nil
|
419
|
+
|
420
|
+
@_info_handler = lambda do
|
421
|
+
unless reporter.passed? then
|
422
|
+
warn "Current results:"
|
423
|
+
warn reporter.reporters.grep(SummaryReporter).first
|
424
|
+
end
|
425
|
+
|
426
|
+
warn "Current: %s#%s %.2fs" % [self, name, Minitest.clock_time - t0]
|
427
|
+
end
|
428
|
+
|
350
429
|
with_info_handler reporter do
|
351
430
|
filtered_methods.each do |method_name|
|
431
|
+
name = method_name
|
432
|
+
t0 = Minitest.clock_time
|
433
|
+
|
352
434
|
run_one_method self, method_name, reporter
|
353
435
|
end
|
354
436
|
end
|
@@ -365,17 +447,16 @@ module Minitest
|
|
365
447
|
reporter.record Minitest.run_one_method(klass, method_name)
|
366
448
|
end
|
367
449
|
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
warn "Current results:"
|
372
|
-
warn ""
|
373
|
-
warn reporter.reporters.first
|
374
|
-
warn ""
|
375
|
-
end
|
376
|
-
end
|
450
|
+
##
|
451
|
+
# Defines the order to run tests (:random by default). Override
|
452
|
+
# this or use a convenience method to change it for your tests.
|
377
453
|
|
378
|
-
|
454
|
+
def self.test_order
|
455
|
+
:random
|
456
|
+
end
|
457
|
+
|
458
|
+
def self.with_info_handler reporter, &block # :nodoc:
|
459
|
+
on_signal ::Minitest.info_signal, @_info_handler, &block
|
379
460
|
end
|
380
461
|
|
381
462
|
SIGNALS = Signal.list # :nodoc:
|
@@ -413,7 +494,7 @@ module Minitest
|
|
413
494
|
def marshal_dump # :nodoc:
|
414
495
|
unless @@marshal_dump_warned then
|
415
496
|
warn ["Minitest::Runnable#marshal_dump is deprecated.",
|
416
|
-
"You might be violating internals. From", caller.first].join " "
|
497
|
+
"You might be violating internals. From", caller(1..1).first].join " "
|
417
498
|
@@marshal_dump_warned = true
|
418
499
|
end
|
419
500
|
|
@@ -432,6 +513,31 @@ module Minitest
|
|
432
513
|
self.name = name
|
433
514
|
self.failures = []
|
434
515
|
self.assertions = 0
|
516
|
+
# lazy initializer for metadata
|
517
|
+
end
|
518
|
+
|
519
|
+
##
|
520
|
+
# Metadata you attach to the test results that get sent to the reporter.
|
521
|
+
#
|
522
|
+
# Lazily initializes to a hash, to keep memory down.
|
523
|
+
#
|
524
|
+
# NOTE: this data *must* be plain (read: marshal-able) data!
|
525
|
+
# Hashes! Arrays! Strings!
|
526
|
+
|
527
|
+
def metadata
|
528
|
+
@metadata ||= {}
|
529
|
+
end
|
530
|
+
|
531
|
+
##
|
532
|
+
# Sets metadata, mainly used for +Result.from+.
|
533
|
+
|
534
|
+
attr_writer :metadata
|
535
|
+
|
536
|
+
##
|
537
|
+
# Returns true if metadata exists.
|
538
|
+
|
539
|
+
def metadata?
|
540
|
+
defined? @metadata
|
435
541
|
end
|
436
542
|
|
437
543
|
##
|
@@ -483,12 +589,14 @@ module Minitest
|
|
483
589
|
not self.failure
|
484
590
|
end
|
485
591
|
|
592
|
+
BASE_DIR = "#{Dir.pwd}/" # :nodoc:
|
593
|
+
|
486
594
|
##
|
487
595
|
# The location identifier of this test. Depends on a method
|
488
596
|
# existing called class_name.
|
489
597
|
|
490
598
|
def location
|
491
|
-
loc = " [#{self.failure.location}]" unless passed? or error?
|
599
|
+
loc = " [#{self.failure.location.delete_prefix BASE_DIR}]" unless passed? or error?
|
492
600
|
"#{self.class_name}##{self.name}#{loc}"
|
493
601
|
end
|
494
602
|
|
@@ -514,7 +622,7 @@ module Minitest
|
|
514
622
|
# Did this run error?
|
515
623
|
|
516
624
|
def error?
|
517
|
-
self.failures.any?
|
625
|
+
self.failures.any? UnexpectedError
|
518
626
|
end
|
519
627
|
end
|
520
628
|
|
@@ -552,6 +660,7 @@ module Minitest
|
|
552
660
|
r.assertions = o.assertions
|
553
661
|
r.failures = o.failures.dup
|
554
662
|
r.time = o.time
|
663
|
+
r.metadata = o.metadata if o.metadata?
|
555
664
|
|
556
665
|
r.source_location = o.method(o.name).source_location rescue ["unknown", -1]
|
557
666
|
|
@@ -576,7 +685,10 @@ module Minitest
|
|
576
685
|
# you want. Go nuts.
|
577
686
|
|
578
687
|
class AbstractReporter
|
579
|
-
|
688
|
+
|
689
|
+
def initialize # :nodoc:
|
690
|
+
@mutex = Mutex.new
|
691
|
+
end
|
580
692
|
|
581
693
|
##
|
582
694
|
# Starts reporting on the run.
|
@@ -612,6 +724,10 @@ module Minitest
|
|
612
724
|
def passed?
|
613
725
|
true
|
614
726
|
end
|
727
|
+
|
728
|
+
def synchronize &block # :nodoc:
|
729
|
+
@mutex.synchronize(&block)
|
730
|
+
end
|
615
731
|
end
|
616
732
|
|
617
733
|
class Reporter < AbstractReporter # :nodoc:
|
@@ -641,11 +757,11 @@ module Minitest
|
|
641
757
|
# own.
|
642
758
|
|
643
759
|
class ProgressReporter < Reporter
|
644
|
-
def prerecord klass, name
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
760
|
+
def prerecord klass, name # :nodoc:
|
761
|
+
return unless options[:verbose]
|
762
|
+
|
763
|
+
io.print "%s#%s = " % [klass.name, name]
|
764
|
+
io.flush
|
649
765
|
end
|
650
766
|
|
651
767
|
def record result # :nodoc:
|
@@ -715,6 +831,11 @@ module Minitest
|
|
715
831
|
|
716
832
|
attr_accessor :errors
|
717
833
|
|
834
|
+
##
|
835
|
+
# Total number of tests that warned.
|
836
|
+
|
837
|
+
attr_accessor :warnings
|
838
|
+
|
718
839
|
##
|
719
840
|
# Total number of tests that where skipped.
|
720
841
|
|
@@ -730,6 +851,7 @@ module Minitest
|
|
730
851
|
self.total_time = nil
|
731
852
|
self.failures = nil
|
732
853
|
self.errors = nil
|
854
|
+
self.warnings = nil
|
733
855
|
self.skips = nil
|
734
856
|
end
|
735
857
|
|
@@ -758,6 +880,7 @@ module Minitest
|
|
758
880
|
self.total_time = Minitest.clock_time - start_time
|
759
881
|
self.failures = aggregate[Assertion].size
|
760
882
|
self.errors = aggregate[UnexpectedError].size
|
883
|
+
self.warnings = aggregate[UnexpectedWarning].size
|
761
884
|
self.skips = aggregate[Skip].size
|
762
885
|
end
|
763
886
|
end
|
@@ -772,10 +895,8 @@ module Minitest
|
|
772
895
|
# own.
|
773
896
|
|
774
897
|
class SummaryReporter < StatisticsReporter
|
775
|
-
# :
|
776
|
-
attr_accessor :
|
777
|
-
attr_accessor :old_sync
|
778
|
-
# :startdoc:
|
898
|
+
attr_accessor :sync # :nodoc:
|
899
|
+
attr_accessor :old_sync # :nodoc:
|
779
900
|
|
780
901
|
def start # :nodoc:
|
781
902
|
super
|
@@ -785,7 +906,7 @@ module Minitest
|
|
785
906
|
io.puts "# Running:"
|
786
907
|
io.puts
|
787
908
|
|
788
|
-
self.sync = io.respond_to? :"sync="
|
909
|
+
self.sync = io.respond_to? :"sync="
|
789
910
|
self.old_sync, io.sync = io.sync, true if self.sync
|
790
911
|
end
|
791
912
|
|
@@ -823,18 +944,22 @@ module Minitest
|
|
823
944
|
end
|
824
945
|
|
825
946
|
def to_s # :nodoc:
|
826
|
-
aggregated_results(StringIO.new(
|
947
|
+
aggregated_results(StringIO.new("".b)).string
|
827
948
|
end
|
828
949
|
|
829
950
|
def summary # :nodoc:
|
830
|
-
extra =
|
951
|
+
extra = []
|
952
|
+
|
953
|
+
extra << ", %d warnings" % [warnings] if options[:Werror]
|
831
954
|
|
832
|
-
extra
|
955
|
+
extra << "\n\nYou have skipped tests. Run with --verbose for details." if
|
833
956
|
results.any?(&:skipped?) unless
|
834
|
-
options[:verbose]
|
957
|
+
options[:verbose] or
|
958
|
+
options[:show_skips] or
|
959
|
+
ENV["MT_NO_SKIP_MSG"]
|
835
960
|
|
836
961
|
"%d runs, %d assertions, %d failures, %d errors, %d skips%s" %
|
837
|
-
[count, assertions, failures, errors, skips, extra]
|
962
|
+
[count, assertions, failures, errors, skips, extra.join]
|
838
963
|
end
|
839
964
|
end
|
840
965
|
|
@@ -893,6 +1018,8 @@ module Minitest
|
|
893
1018
|
# Represents run failures.
|
894
1019
|
|
895
1020
|
class Assertion < Exception
|
1021
|
+
RE = /in [`'](?:[^']+[#.])?(?:assert|refute|flunk|pass|fail|raise|must|wont)/ # :nodoc:
|
1022
|
+
|
896
1023
|
def error # :nodoc:
|
897
1024
|
self
|
898
1025
|
end
|
@@ -901,12 +1028,11 @@ module Minitest
|
|
901
1028
|
# Where was this run before an assertion was raised?
|
902
1029
|
|
903
1030
|
def location
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
last_before_assertion.sub(/:in .*$/, "")
|
1031
|
+
bt = Minitest.filter_backtrace self.backtrace
|
1032
|
+
idx = bt.rindex { |s| s.match? RE } || -1 # fall back to first item
|
1033
|
+
loc = bt[idx+1] || bt.last || "unknown:-1"
|
1034
|
+
|
1035
|
+
loc.sub(/:in .*$/, "")
|
910
1036
|
end
|
911
1037
|
|
912
1038
|
def result_code # :nodoc:
|
@@ -931,11 +1057,21 @@ module Minitest
|
|
931
1057
|
# Assertion wrapping an unexpected error that was raised during a run.
|
932
1058
|
|
933
1059
|
class UnexpectedError < Assertion
|
1060
|
+
include Minitest::Compress
|
1061
|
+
|
934
1062
|
# TODO: figure out how to use `cause` instead
|
935
1063
|
attr_accessor :error # :nodoc:
|
936
1064
|
|
937
1065
|
def initialize error # :nodoc:
|
938
1066
|
super "Unexpected exception"
|
1067
|
+
|
1068
|
+
if SystemStackError === error then
|
1069
|
+
bt = error.backtrace
|
1070
|
+
new_bt = compress bt
|
1071
|
+
error = error.exception "#{bt.size} -> #{new_bt.size}"
|
1072
|
+
error.set_backtrace new_bt
|
1073
|
+
end
|
1074
|
+
|
939
1075
|
self.error = error
|
940
1076
|
end
|
941
1077
|
|
@@ -943,8 +1079,11 @@ module Minitest
|
|
943
1079
|
self.error.backtrace
|
944
1080
|
end
|
945
1081
|
|
1082
|
+
BASE_RE = %r%#{Dir.pwd}/% # :nodoc:
|
1083
|
+
|
946
1084
|
def message # :nodoc:
|
947
|
-
bt = Minitest.filter_backtrace(self.backtrace).join
|
1085
|
+
bt = Minitest.filter_backtrace(self.backtrace).join("\n ")
|
1086
|
+
.gsub(BASE_RE, "")
|
948
1087
|
"#{self.error.class}: #{self.error.message}\n #{bt}"
|
949
1088
|
end
|
950
1089
|
|
@@ -953,6 +1092,15 @@ module Minitest
|
|
953
1092
|
end
|
954
1093
|
end
|
955
1094
|
|
1095
|
+
##
|
1096
|
+
# Assertion raised on warning when running in -Werror mode.
|
1097
|
+
|
1098
|
+
class UnexpectedWarning < Assertion
|
1099
|
+
def result_label # :nodoc:
|
1100
|
+
"Warning"
|
1101
|
+
end
|
1102
|
+
end
|
1103
|
+
|
956
1104
|
##
|
957
1105
|
# Provides a simple set of guards that you can use in your tests
|
958
1106
|
# to skip execution if it is not applicable. These methods are
|
@@ -982,7 +1130,7 @@ module Minitest
|
|
982
1130
|
|
983
1131
|
def maglev? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
|
984
1132
|
where = Minitest.filter_backtrace(caller).first
|
985
|
-
where = where.split(
|
1133
|
+
where = where.split(":in ", 2).first # clean up noise
|
986
1134
|
warn "DEPRECATED: `maglev?` called from #{where}. This will fail in Minitest 6."
|
987
1135
|
"maglev" == platform
|
988
1136
|
end
|
@@ -991,14 +1139,14 @@ module Minitest
|
|
991
1139
|
# Is this running on mri?
|
992
1140
|
|
993
1141
|
def mri? platform = RUBY_DESCRIPTION
|
994
|
-
|
1142
|
+
platform.start_with? "ruby"
|
995
1143
|
end
|
996
1144
|
|
997
1145
|
##
|
998
1146
|
# Is this running on macOS?
|
999
1147
|
|
1000
1148
|
def osx? platform = RUBY_PLATFORM
|
1001
|
-
|
1149
|
+
platform.include? "darwin"
|
1002
1150
|
end
|
1003
1151
|
|
1004
1152
|
##
|
@@ -1006,7 +1154,7 @@ module Minitest
|
|
1006
1154
|
|
1007
1155
|
def rubinius? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
|
1008
1156
|
where = Minitest.filter_backtrace(caller).first
|
1009
|
-
where = where.split(
|
1157
|
+
where = where.split(":in ", 2).first # clean up noise
|
1010
1158
|
warn "DEPRECATED: `rubinius?` called from #{where}. This will fail in Minitest 6."
|
1011
1159
|
"rbx" == platform
|
1012
1160
|
end
|
@@ -1015,7 +1163,7 @@ module Minitest
|
|
1015
1163
|
# Is this running on windows?
|
1016
1164
|
|
1017
1165
|
def windows? platform = RUBY_PLATFORM
|
1018
|
-
/mswin|mingw
|
1166
|
+
/mswin|mingw/.match? platform
|
1019
1167
|
end
|
1020
1168
|
end
|
1021
1169
|
|
@@ -1026,7 +1174,16 @@ module Minitest
|
|
1026
1174
|
|
1027
1175
|
class BacktraceFilter
|
1028
1176
|
|
1029
|
-
MT_RE = %r%lib/minitest%
|
1177
|
+
MT_RE = %r%lib/minitest|internal:warning% # :nodoc:
|
1178
|
+
|
1179
|
+
##
|
1180
|
+
# The regular expression to use to filter backtraces. Defaults to +MT_RE+.
|
1181
|
+
|
1182
|
+
attr_accessor :regexp
|
1183
|
+
|
1184
|
+
def initialize regexp = MT_RE # :nodoc:
|
1185
|
+
self.regexp = regexp
|
1186
|
+
end
|
1030
1187
|
|
1031
1188
|
##
|
1032
1189
|
# Filter +bt+ to something useful. Returns the whole thing if
|
@@ -1037,9 +1194,9 @@ module Minitest
|
|
1037
1194
|
|
1038
1195
|
return bt.dup if $DEBUG || ENV["MT_DEBUG"]
|
1039
1196
|
|
1040
|
-
new_bt = bt.take_while { |line| line
|
1041
|
-
new_bt = bt.select { |line| line
|
1042
|
-
new_bt = bt.dup
|
1197
|
+
new_bt = bt.take_while { |line| !regexp.match? line.to_s }
|
1198
|
+
new_bt = bt.select { |line| !regexp.match? line.to_s } if new_bt.empty?
|
1199
|
+
new_bt = bt.dup if new_bt.empty?
|
1043
1200
|
|
1044
1201
|
new_bt
|
1045
1202
|
end
|