minitest 5.20.0 → 5.25.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/History.rdoc +130 -3
- data/Manifest.txt +3 -0
- data/README.rdoc +16 -13
- data/Rakefile +6 -0
- 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/manual_plugins.rb +16 -0
- data/lib/minitest/mock.rb +17 -15
- data/lib/minitest/parallel.rb +5 -5
- data/lib/minitest/pride_plugin.rb +16 -23
- data/lib/minitest/spec.rb +5 -5
- data/lib/minitest/test.rb +14 -25
- data/lib/minitest/test_task.rb +17 -12
- data/lib/minitest.rb +257 -144
- 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 +80 -75
- data/test/minitest/test_minitest_reporter.rb +111 -16
- data/test/minitest/test_minitest_spec.rb +54 -55
- data/test/minitest/test_minitest_test.rb +191 -117
- data/test/minitest/test_minitest_test_task.rb +18 -7
- data.tar.gz.sig +0 -0
- metadata +17 -13
- metadata.gz.sig +0 -0
data/lib/minitest.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
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
|
# :include: README.rdoc
|
10
10
|
|
11
11
|
module Minitest
|
12
|
-
VERSION = "5.
|
12
|
+
VERSION = "5.25.1" # :nodoc:
|
13
13
|
|
14
14
|
@@installed_at_exit ||= false
|
15
15
|
@@after_run = []
|
@@ -67,9 +67,8 @@ module Minitest
|
|
67
67
|
# Registers Minitest to run at process exit
|
68
68
|
|
69
69
|
def self.autorun
|
70
|
-
|
71
|
-
Warning[
|
72
|
-
end
|
70
|
+
Warning[:deprecated] = true if
|
71
|
+
Object.const_defined?(:Warning) && Warning.respond_to?(:[]=)
|
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,72 +121,27 @@ 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
|
|
@@ -212,6 +165,10 @@ module Minitest
|
|
212
165
|
options[:verbose] = true
|
213
166
|
end
|
214
167
|
|
168
|
+
opts.on "-q", "--quiet", "Quiet. Show no progress processing files." do
|
169
|
+
options[:quiet] = true
|
170
|
+
end
|
171
|
+
|
215
172
|
opts.on "--show-skips", "Show skipped at the end of run." do
|
216
173
|
options[:show_skips] = true
|
217
174
|
end
|
@@ -228,13 +185,37 @@ module Minitest
|
|
228
185
|
options[:skip] = s.chars.to_a
|
229
186
|
end
|
230
187
|
|
188
|
+
ruby27plus = ::Warning.respond_to? :[]=
|
189
|
+
|
190
|
+
opts.on "-W[error]", String, "Turn Ruby warnings into errors" do |s|
|
191
|
+
options[:Werror] = true
|
192
|
+
case s
|
193
|
+
when "error", "all", nil then
|
194
|
+
require "minitest/error_on_warning"
|
195
|
+
$VERBOSE = true
|
196
|
+
::Warning[:deprecated] = true if ruby27plus
|
197
|
+
else
|
198
|
+
::Warning[s.to_sym] = true if ruby27plus # check validity of category
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
231
202
|
unless extensions.empty?
|
232
203
|
opts.separator ""
|
233
|
-
opts.separator "Known extensions: #{extensions.join
|
234
|
-
|
235
|
-
extensions.each do |
|
236
|
-
|
237
|
-
|
204
|
+
opts.separator "Known extensions: #{extensions.join ", "}"
|
205
|
+
|
206
|
+
extensions.each do |mod_or_meth|
|
207
|
+
case mod_or_meth
|
208
|
+
when Symbol, String then
|
209
|
+
meth = mod_or_meth
|
210
|
+
msg = "plugin_#{meth}_options"
|
211
|
+
send msg, opts, options if respond_to? msg
|
212
|
+
when Module
|
213
|
+
recv = mod_or_meth
|
214
|
+
next unless recv.respond_to? :minitest_plugin_options
|
215
|
+
recv.minitest_plugin_options opts, options
|
216
|
+
else
|
217
|
+
raise ArgumentError, "plugin is %p, but it must be a symbol, string or module" % [mod_or_meth]
|
218
|
+
end
|
238
219
|
end
|
239
220
|
end
|
240
221
|
|
@@ -258,12 +239,99 @@ module Minitest
|
|
258
239
|
end
|
259
240
|
|
260
241
|
options[:args] = orig_args.map { |s|
|
261
|
-
s
|
242
|
+
s.match?(/[\s|&<>$()]/) ? s.inspect : s
|
262
243
|
}.join " "
|
263
244
|
|
264
245
|
options
|
265
246
|
end
|
266
247
|
|
248
|
+
##
|
249
|
+
# This is the top-level run method. Everything starts from here. It
|
250
|
+
# tells each Runnable sub-class to run, and each of those are
|
251
|
+
# responsible for doing whatever they do.
|
252
|
+
#
|
253
|
+
# The overall structure of a run looks like this:
|
254
|
+
#
|
255
|
+
# Minitest.autorun
|
256
|
+
# Minitest.run(args)
|
257
|
+
# Minitest.load_plugins
|
258
|
+
# Minitest.process_args
|
259
|
+
# Minitest.init_plugins
|
260
|
+
# Minitest.__run(reporter, options)
|
261
|
+
# Runnable.runnables.each
|
262
|
+
# runnable_klass.run(reporter, options)
|
263
|
+
# self.runnable_methods.each
|
264
|
+
# self.run_one_method(self, runnable_method, reporter)
|
265
|
+
# Minitest.run_one_method(klass, runnable_method)
|
266
|
+
# klass.new(runnable_method).run
|
267
|
+
|
268
|
+
def self.run args = []
|
269
|
+
self.load_plugins unless args.delete("--no-plugins") || ENV["MT_NO_PLUGINS"]
|
270
|
+
|
271
|
+
options = process_args args
|
272
|
+
|
273
|
+
Minitest.seed = options[:seed]
|
274
|
+
srand Minitest.seed
|
275
|
+
|
276
|
+
reporter = CompositeReporter.new
|
277
|
+
reporter << SummaryReporter.new(options[:io], options)
|
278
|
+
reporter << ProgressReporter.new(options[:io], options) unless options[:quiet]
|
279
|
+
|
280
|
+
self.reporter = reporter # this makes it available to plugins
|
281
|
+
self.init_plugins options
|
282
|
+
self.reporter = nil # runnables shouldn't depend on the reporter, ever
|
283
|
+
|
284
|
+
self.parallel_executor.start if parallel_executor.respond_to? :start
|
285
|
+
reporter.start
|
286
|
+
begin
|
287
|
+
__run reporter, options
|
288
|
+
rescue Interrupt
|
289
|
+
warn "Interrupted. Exiting..."
|
290
|
+
end
|
291
|
+
self.parallel_executor.shutdown
|
292
|
+
|
293
|
+
# might have been removed/replaced during init_plugins:
|
294
|
+
summary = reporter.reporters.grep(SummaryReporter).first
|
295
|
+
|
296
|
+
reporter.report
|
297
|
+
|
298
|
+
return empty_run! options if summary && summary.count == 0
|
299
|
+
reporter.passed?
|
300
|
+
end
|
301
|
+
|
302
|
+
def self.empty_run! options # :nodoc:
|
303
|
+
filter = options[:filter]
|
304
|
+
return true unless filter # no filter, but nothing ran == success
|
305
|
+
|
306
|
+
warn "Nothing ran for filter: %s" % [filter]
|
307
|
+
|
308
|
+
require "did_you_mean" # soft dependency, punt if it doesn't load
|
309
|
+
|
310
|
+
ms = Runnable.runnables.flat_map(&:runnable_methods)
|
311
|
+
cs = DidYouMean::SpellChecker.new(dictionary: ms).correct filter
|
312
|
+
|
313
|
+
warn DidYouMean::Formatter.message_for cs unless cs.empty?
|
314
|
+
rescue LoadError
|
315
|
+
# do nothing
|
316
|
+
end
|
317
|
+
|
318
|
+
##
|
319
|
+
# Internal run method. Responsible for telling all Runnable
|
320
|
+
# sub-classes to run.
|
321
|
+
|
322
|
+
def self.__run reporter, options
|
323
|
+
suites = Runnable.runnables.shuffle
|
324
|
+
parallel, serial = suites.partition { |s| s.test_order == :parallel }
|
325
|
+
|
326
|
+
# If we run the parallel tests before the serial tests, the parallel tests
|
327
|
+
# could run in parallel with the serial tests. This would be bad because
|
328
|
+
# the serial tests won't lock around Reporter#record. Run the serial tests
|
329
|
+
# first, so that after they complete, the parallel tests will lock when
|
330
|
+
# recording results.
|
331
|
+
serial.map { |suite| suite.run reporter, options } +
|
332
|
+
parallel.map { |suite| suite.run reporter, options }
|
333
|
+
end
|
334
|
+
|
267
335
|
def self.filter_backtrace bt # :nodoc:
|
268
336
|
result = backtrace_filter.filter bt
|
269
337
|
result = bt.dup if result.empty?
|
@@ -334,30 +402,34 @@ module Minitest
|
|
334
402
|
# reporter to record.
|
335
403
|
|
336
404
|
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
|
405
|
+
pos = options[:filter]
|
406
|
+
neg = options[:exclude]
|
347
407
|
|
348
|
-
if
|
349
|
-
|
350
|
-
exclude = Regexp.new $1 if exclude =~ %r%/(.*)/%
|
408
|
+
pos = Regexp.new $1 if pos.kind_of?(String) && pos =~ %r%/(.*)/%
|
409
|
+
neg = Regexp.new $1 if neg.kind_of?(String) && neg =~ %r%/(.*)/%
|
351
410
|
|
352
|
-
|
353
|
-
|
354
|
-
}
|
355
|
-
end
|
411
|
+
filtered_methods = self.runnable_methods
|
412
|
+
.select { |m| !pos || pos === m || pos === "#{self}##{m}" }
|
413
|
+
.reject { |m| neg && (neg === m || neg === "#{self}##{m}") }
|
356
414
|
|
357
415
|
return if filtered_methods.empty?
|
358
416
|
|
417
|
+
t0 = name = nil
|
418
|
+
|
419
|
+
@_info_handler = lambda do
|
420
|
+
unless reporter.passed? then
|
421
|
+
warn "Current results:"
|
422
|
+
warn reporter.reporters.grep(SummaryReporter).first
|
423
|
+
end
|
424
|
+
|
425
|
+
warn "Current: %s#%s %.2fs" % [self, name, Minitest.clock_time - t0]
|
426
|
+
end
|
427
|
+
|
359
428
|
with_info_handler reporter do
|
360
429
|
filtered_methods.each do |method_name|
|
430
|
+
name = method_name
|
431
|
+
t0 = Minitest.clock_time
|
432
|
+
|
361
433
|
run_one_method self, method_name, reporter
|
362
434
|
end
|
363
435
|
end
|
@@ -383,16 +455,7 @@ module Minitest
|
|
383
455
|
end
|
384
456
|
|
385
457
|
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
|
458
|
+
on_signal ::Minitest.info_signal, @_info_handler, &block
|
396
459
|
end
|
397
460
|
|
398
461
|
SIGNALS = Signal.list # :nodoc:
|
@@ -430,7 +493,7 @@ module Minitest
|
|
430
493
|
def marshal_dump # :nodoc:
|
431
494
|
unless @@marshal_dump_warned then
|
432
495
|
warn ["Minitest::Runnable#marshal_dump is deprecated.",
|
433
|
-
"You might be violating internals. From", caller.first].join " "
|
496
|
+
"You might be violating internals. From", caller(1..1).first].join " "
|
434
497
|
@@marshal_dump_warned = true
|
435
498
|
end
|
436
499
|
|
@@ -525,12 +588,14 @@ module Minitest
|
|
525
588
|
not self.failure
|
526
589
|
end
|
527
590
|
|
591
|
+
BASE_DIR = "#{Dir.pwd}/" # :nodoc:
|
592
|
+
|
528
593
|
##
|
529
594
|
# The location identifier of this test. Depends on a method
|
530
595
|
# existing called class_name.
|
531
596
|
|
532
597
|
def location
|
533
|
-
loc = " [#{self.failure.location}]" unless passed? or error?
|
598
|
+
loc = " [#{self.failure.location.delete_prefix BASE_DIR}]" unless passed? or error?
|
534
599
|
"#{self.class_name}##{self.name}#{loc}"
|
535
600
|
end
|
536
601
|
|
@@ -556,7 +621,7 @@ module Minitest
|
|
556
621
|
# Did this run error?
|
557
622
|
|
558
623
|
def error?
|
559
|
-
self.failures.any?
|
624
|
+
self.failures.any? UnexpectedError
|
560
625
|
end
|
561
626
|
end
|
562
627
|
|
@@ -619,7 +684,10 @@ module Minitest
|
|
619
684
|
# you want. Go nuts.
|
620
685
|
|
621
686
|
class AbstractReporter
|
622
|
-
|
687
|
+
|
688
|
+
def initialize # :nodoc:
|
689
|
+
@mutex = Mutex.new
|
690
|
+
end
|
623
691
|
|
624
692
|
##
|
625
693
|
# Starts reporting on the run.
|
@@ -655,6 +723,10 @@ module Minitest
|
|
655
723
|
def passed?
|
656
724
|
true
|
657
725
|
end
|
726
|
+
|
727
|
+
def synchronize &block # :nodoc:
|
728
|
+
@mutex.synchronize(&block)
|
729
|
+
end
|
658
730
|
end
|
659
731
|
|
660
732
|
class Reporter < AbstractReporter # :nodoc:
|
@@ -684,11 +756,11 @@ module Minitest
|
|
684
756
|
# own.
|
685
757
|
|
686
758
|
class ProgressReporter < Reporter
|
687
|
-
def prerecord klass, name
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
759
|
+
def prerecord klass, name # :nodoc:
|
760
|
+
return unless options[:verbose]
|
761
|
+
|
762
|
+
io.print "%s#%s = " % [klass.name, name]
|
763
|
+
io.flush
|
692
764
|
end
|
693
765
|
|
694
766
|
def record result # :nodoc:
|
@@ -758,6 +830,11 @@ module Minitest
|
|
758
830
|
|
759
831
|
attr_accessor :errors
|
760
832
|
|
833
|
+
##
|
834
|
+
# Total number of tests that warned.
|
835
|
+
|
836
|
+
attr_accessor :warnings
|
837
|
+
|
761
838
|
##
|
762
839
|
# Total number of tests that where skipped.
|
763
840
|
|
@@ -773,6 +850,7 @@ module Minitest
|
|
773
850
|
self.total_time = nil
|
774
851
|
self.failures = nil
|
775
852
|
self.errors = nil
|
853
|
+
self.warnings = nil
|
776
854
|
self.skips = nil
|
777
855
|
end
|
778
856
|
|
@@ -801,6 +879,7 @@ module Minitest
|
|
801
879
|
self.total_time = Minitest.clock_time - start_time
|
802
880
|
self.failures = aggregate[Assertion].size
|
803
881
|
self.errors = aggregate[UnexpectedError].size
|
882
|
+
self.warnings = aggregate[UnexpectedWarning].size
|
804
883
|
self.skips = aggregate[Skip].size
|
805
884
|
end
|
806
885
|
end
|
@@ -815,10 +894,8 @@ module Minitest
|
|
815
894
|
# own.
|
816
895
|
|
817
896
|
class SummaryReporter < StatisticsReporter
|
818
|
-
# :
|
819
|
-
attr_accessor :
|
820
|
-
attr_accessor :old_sync
|
821
|
-
# :startdoc:
|
897
|
+
attr_accessor :sync # :nodoc:
|
898
|
+
attr_accessor :old_sync # :nodoc:
|
822
899
|
|
823
900
|
def start # :nodoc:
|
824
901
|
super
|
@@ -828,7 +905,7 @@ module Minitest
|
|
828
905
|
io.puts "# Running:"
|
829
906
|
io.puts
|
830
907
|
|
831
|
-
self.sync = io.respond_to? :"sync="
|
908
|
+
self.sync = io.respond_to? :"sync="
|
832
909
|
self.old_sync, io.sync = io.sync, true if self.sync
|
833
910
|
end
|
834
911
|
|
@@ -866,18 +943,22 @@ module Minitest
|
|
866
943
|
end
|
867
944
|
|
868
945
|
def to_s # :nodoc:
|
869
|
-
aggregated_results(StringIO.new(
|
946
|
+
aggregated_results(StringIO.new("".b)).string
|
870
947
|
end
|
871
948
|
|
872
949
|
def summary # :nodoc:
|
873
|
-
extra =
|
950
|
+
extra = []
|
874
951
|
|
875
|
-
extra
|
952
|
+
extra << ", %d warnings" % [warnings] if options[:Werror]
|
953
|
+
|
954
|
+
extra << "\n\nYou have skipped tests. Run with --verbose for details." if
|
876
955
|
results.any?(&:skipped?) unless
|
877
|
-
options[:verbose]
|
956
|
+
options[:verbose] or
|
957
|
+
options[:show_skips] or
|
958
|
+
ENV["MT_NO_SKIP_MSG"]
|
878
959
|
|
879
960
|
"%d runs, %d assertions, %d failures, %d errors, %d skips%s" %
|
880
|
-
[count, assertions, failures, errors, skips, extra]
|
961
|
+
[count, assertions, failures, errors, skips, extra.join]
|
881
962
|
end
|
882
963
|
end
|
883
964
|
|
@@ -936,6 +1017,8 @@ module Minitest
|
|
936
1017
|
# Represents run failures.
|
937
1018
|
|
938
1019
|
class Assertion < Exception
|
1020
|
+
RE = /in [`'](?:[^']+[#.])?(?:assert|refute|flunk|pass|fail|raise|must|wont)/ # :nodoc:
|
1021
|
+
|
939
1022
|
def error # :nodoc:
|
940
1023
|
self
|
941
1024
|
end
|
@@ -944,12 +1027,11 @@ module Minitest
|
|
944
1027
|
# Where was this run before an assertion was raised?
|
945
1028
|
|
946
1029
|
def location
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
last_before_assertion.sub(/:in .*$/, "")
|
1030
|
+
bt = Minitest.filter_backtrace self.backtrace
|
1031
|
+
idx = bt.rindex { |s| s.match? RE } || -1 # fall back to first item
|
1032
|
+
loc = bt[idx+1] || bt.last || "unknown:-1"
|
1033
|
+
|
1034
|
+
loc.sub(/:in .*$/, "")
|
953
1035
|
end
|
954
1036
|
|
955
1037
|
def result_code # :nodoc:
|
@@ -974,11 +1056,21 @@ module Minitest
|
|
974
1056
|
# Assertion wrapping an unexpected error that was raised during a run.
|
975
1057
|
|
976
1058
|
class UnexpectedError < Assertion
|
1059
|
+
include Minitest::Compress
|
1060
|
+
|
977
1061
|
# TODO: figure out how to use `cause` instead
|
978
1062
|
attr_accessor :error # :nodoc:
|
979
1063
|
|
980
1064
|
def initialize error # :nodoc:
|
981
1065
|
super "Unexpected exception"
|
1066
|
+
|
1067
|
+
if SystemStackError === error then
|
1068
|
+
bt = error.backtrace
|
1069
|
+
new_bt = compress bt
|
1070
|
+
error = error.exception "#{bt.size} -> #{new_bt.size}"
|
1071
|
+
error.set_backtrace new_bt
|
1072
|
+
end
|
1073
|
+
|
982
1074
|
self.error = error
|
983
1075
|
end
|
984
1076
|
|
@@ -986,8 +1078,11 @@ module Minitest
|
|
986
1078
|
self.error.backtrace
|
987
1079
|
end
|
988
1080
|
|
1081
|
+
BASE_RE = %r%#{Dir.pwd}/% # :nodoc:
|
1082
|
+
|
989
1083
|
def message # :nodoc:
|
990
|
-
bt = Minitest.filter_backtrace(self.backtrace).join
|
1084
|
+
bt = Minitest.filter_backtrace(self.backtrace).join("\n ")
|
1085
|
+
.gsub(BASE_RE, "")
|
991
1086
|
"#{self.error.class}: #{self.error.message}\n #{bt}"
|
992
1087
|
end
|
993
1088
|
|
@@ -996,6 +1091,15 @@ module Minitest
|
|
996
1091
|
end
|
997
1092
|
end
|
998
1093
|
|
1094
|
+
##
|
1095
|
+
# Assertion raised on warning when running in -Werror mode.
|
1096
|
+
|
1097
|
+
class UnexpectedWarning < Assertion
|
1098
|
+
def result_label # :nodoc:
|
1099
|
+
"Warning"
|
1100
|
+
end
|
1101
|
+
end
|
1102
|
+
|
999
1103
|
##
|
1000
1104
|
# Provides a simple set of guards that you can use in your tests
|
1001
1105
|
# to skip execution if it is not applicable. These methods are
|
@@ -1025,7 +1129,7 @@ module Minitest
|
|
1025
1129
|
|
1026
1130
|
def maglev? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
|
1027
1131
|
where = Minitest.filter_backtrace(caller).first
|
1028
|
-
where = where.split(
|
1132
|
+
where = where.split(":in ", 2).first # clean up noise
|
1029
1133
|
warn "DEPRECATED: `maglev?` called from #{where}. This will fail in Minitest 6."
|
1030
1134
|
"maglev" == platform
|
1031
1135
|
end
|
@@ -1034,14 +1138,14 @@ module Minitest
|
|
1034
1138
|
# Is this running on mri?
|
1035
1139
|
|
1036
1140
|
def mri? platform = RUBY_DESCRIPTION
|
1037
|
-
|
1141
|
+
platform.start_with? "ruby"
|
1038
1142
|
end
|
1039
1143
|
|
1040
1144
|
##
|
1041
1145
|
# Is this running on macOS?
|
1042
1146
|
|
1043
1147
|
def osx? platform = RUBY_PLATFORM
|
1044
|
-
|
1148
|
+
platform.include? "darwin"
|
1045
1149
|
end
|
1046
1150
|
|
1047
1151
|
##
|
@@ -1049,7 +1153,7 @@ module Minitest
|
|
1049
1153
|
|
1050
1154
|
def rubinius? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
|
1051
1155
|
where = Minitest.filter_backtrace(caller).first
|
1052
|
-
where = where.split(
|
1156
|
+
where = where.split(":in ", 2).first # clean up noise
|
1053
1157
|
warn "DEPRECATED: `rubinius?` called from #{where}. This will fail in Minitest 6."
|
1054
1158
|
"rbx" == platform
|
1055
1159
|
end
|
@@ -1058,7 +1162,7 @@ module Minitest
|
|
1058
1162
|
# Is this running on windows?
|
1059
1163
|
|
1060
1164
|
def windows? platform = RUBY_PLATFORM
|
1061
|
-
/mswin|mingw
|
1165
|
+
/mswin|mingw/.match? platform
|
1062
1166
|
end
|
1063
1167
|
end
|
1064
1168
|
|
@@ -1069,7 +1173,16 @@ module Minitest
|
|
1069
1173
|
|
1070
1174
|
class BacktraceFilter
|
1071
1175
|
|
1072
|
-
MT_RE = %r%lib/minitest%
|
1176
|
+
MT_RE = %r%lib/minitest|internal:warning% # :nodoc:
|
1177
|
+
|
1178
|
+
##
|
1179
|
+
# The regular expression to use to filter backtraces. Defaults to +MT_RE+.
|
1180
|
+
|
1181
|
+
attr_accessor :regexp
|
1182
|
+
|
1183
|
+
def initialize regexp = MT_RE # :nodoc:
|
1184
|
+
self.regexp = regexp
|
1185
|
+
end
|
1073
1186
|
|
1074
1187
|
##
|
1075
1188
|
# Filter +bt+ to something useful. Returns the whole thing if
|
@@ -1080,9 +1193,9 @@ module Minitest
|
|
1080
1193
|
|
1081
1194
|
return bt.dup if $DEBUG || ENV["MT_DEBUG"]
|
1082
1195
|
|
1083
|
-
new_bt = bt.take_while { |line| line
|
1084
|
-
new_bt = bt.select { |line| line
|
1085
|
-
new_bt = bt.dup
|
1196
|
+
new_bt = bt.take_while { |line| !regexp.match? line.to_s }
|
1197
|
+
new_bt = bt.select { |line| !regexp.match? line.to_s } if new_bt.empty?
|
1198
|
+
new_bt = bt.dup if new_bt.empty?
|
1086
1199
|
|
1087
1200
|
new_bt
|
1088
1201
|
end
|