minitest 5.12.0 → 5.22.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/History.rdoc +262 -5
- data/Manifest.txt +3 -0
- data/README.rdoc +90 -17
- data/Rakefile +5 -16
- data/lib/hoe/minitest.rb +0 -4
- data/lib/minitest/assertions.rb +171 -37
- data/lib/minitest/benchmark.rb +7 -7
- data/lib/minitest/compress.rb +94 -0
- data/lib/minitest/expectations.rb +72 -35
- data/lib/minitest/mock.rb +123 -34
- data/lib/minitest/pride_plugin.rb +1 -1
- data/lib/minitest/spec.rb +24 -10
- data/lib/minitest/test.rb +44 -16
- data/lib/minitest/test_task.rb +301 -0
- data/lib/minitest/unit.rb +5 -8
- data/lib/minitest.rb +245 -70
- data/test/minitest/metametameta.rb +45 -11
- data/test/minitest/test_minitest_assertions.rb +357 -29
- data/test/minitest/test_minitest_benchmark.rb +2 -2
- data/test/minitest/test_minitest_mock.rb +287 -15
- data/test/minitest/test_minitest_reporter.rb +158 -17
- data/test/minitest/test_minitest_spec.rb +184 -59
- data/test/minitest/test_minitest_test.rb +362 -42
- data/test/minitest/test_minitest_test_task.rb +46 -0
- data.tar.gz.sig +2 -2
- metadata +28 -19
- metadata.gz.sig +0 -0
data/lib/minitest.rb
CHANGED
@@ -1,64 +1,84 @@
|
|
1
1
|
require "optparse"
|
2
|
-
require "thread"
|
3
|
-
require "mutex_m"
|
4
|
-
require "minitest/parallel"
|
5
2
|
require "stringio"
|
3
|
+
require "etc"
|
4
|
+
|
5
|
+
require_relative "minitest/parallel"
|
6
|
+
require_relative "minitest/compress"
|
6
7
|
|
7
8
|
##
|
8
9
|
# :include: README.rdoc
|
9
10
|
|
10
11
|
module Minitest
|
11
|
-
VERSION = "5.
|
12
|
-
ENCS = "".respond_to? :encoding # :nodoc:
|
12
|
+
VERSION = "5.22.2" # :nodoc:
|
13
13
|
|
14
14
|
@@installed_at_exit ||= false
|
15
15
|
@@after_run = []
|
16
16
|
@extensions = []
|
17
17
|
|
18
|
-
|
18
|
+
def self.cattr_accessor name # :nodoc:
|
19
|
+
(class << self; self; end).attr_accessor name
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# The random seed used for this run. This is used to srand at the
|
24
|
+
# start of the run and between each +Runnable.run+.
|
25
|
+
#
|
26
|
+
# Set via Minitest.run after processing args.
|
27
|
+
|
28
|
+
cattr_accessor :seed
|
19
29
|
|
20
30
|
##
|
21
31
|
# Parallel test executor
|
22
32
|
|
23
|
-
|
33
|
+
cattr_accessor :parallel_executor
|
34
|
+
|
35
|
+
warn "DEPRECATED: use MT_CPU instead of N for parallel test runs" if ENV["N"] && ENV["N"].to_i > 0
|
36
|
+
n_threads = (ENV["MT_CPU"] || ENV["N"] || Etc.nprocessors).to_i
|
24
37
|
|
25
|
-
warn "DEPRECATED: use MT_CPU instead of N for parallel test runs" if ENV["N"]
|
26
|
-
n_threads = (ENV["MT_CPU"] || ENV["N"] || 2).to_i
|
27
38
|
self.parallel_executor = Parallel::Executor.new n_threads
|
28
39
|
|
29
40
|
##
|
30
41
|
# Filter object for backtraces.
|
31
42
|
|
32
|
-
|
43
|
+
cattr_accessor :backtrace_filter
|
33
44
|
|
34
45
|
##
|
35
46
|
# Reporter object to be used for all runs.
|
36
47
|
#
|
37
48
|
# NOTE: This accessor is only available during setup, not during runs.
|
38
49
|
|
39
|
-
|
50
|
+
cattr_accessor :reporter
|
40
51
|
|
41
52
|
##
|
42
53
|
# Names of known extension plugins.
|
43
54
|
|
44
|
-
|
55
|
+
cattr_accessor :extensions
|
45
56
|
|
46
57
|
##
|
47
58
|
# The signal to use for dumping information to STDERR. Defaults to "INFO".
|
48
59
|
|
49
|
-
|
60
|
+
cattr_accessor :info_signal
|
50
61
|
self.info_signal = "INFO"
|
51
62
|
|
63
|
+
cattr_accessor :allow_fork
|
64
|
+
self.allow_fork = false
|
65
|
+
|
52
66
|
##
|
53
67
|
# Registers Minitest to run at process exit
|
54
68
|
|
55
69
|
def self.autorun
|
70
|
+
if Object.const_defined?(:Warning) && Warning.respond_to?(:[]=)
|
71
|
+
Warning[:deprecated] = true
|
72
|
+
end
|
73
|
+
|
56
74
|
at_exit {
|
57
75
|
next if $! and not ($!.kind_of? SystemExit and $!.success?)
|
58
76
|
|
59
77
|
exit_code = nil
|
60
78
|
|
79
|
+
pid = Process.pid
|
61
80
|
at_exit {
|
81
|
+
next if !Minitest.allow_fork && Process.pid != pid
|
62
82
|
@@after_run.reverse_each(&:call)
|
63
83
|
exit exit_code || false
|
64
84
|
}
|
@@ -114,7 +134,7 @@ module Minitest
|
|
114
134
|
# Minitest.run(args)
|
115
135
|
# Minitest.__run(reporter, options)
|
116
136
|
# Runnable.runnables.each
|
117
|
-
#
|
137
|
+
# runnable_klass.run(reporter, options)
|
118
138
|
# self.runnable_methods.each
|
119
139
|
# self.run_one_method(self, runnable_method, reporter)
|
120
140
|
# Minitest.run_one_method(klass, runnable_method)
|
@@ -125,9 +145,12 @@ module Minitest
|
|
125
145
|
|
126
146
|
options = process_args args
|
127
147
|
|
148
|
+
Minitest.seed = options[:seed]
|
149
|
+
srand Minitest.seed
|
150
|
+
|
128
151
|
reporter = CompositeReporter.new
|
129
152
|
reporter << SummaryReporter.new(options[:io], options)
|
130
|
-
reporter << ProgressReporter.new(options[:io], options)
|
153
|
+
reporter << ProgressReporter.new(options[:io], options) unless options[:quiet]
|
131
154
|
|
132
155
|
self.reporter = reporter # this makes it available to plugins
|
133
156
|
self.init_plugins options
|
@@ -141,17 +164,38 @@ module Minitest
|
|
141
164
|
warn "Interrupted. Exiting..."
|
142
165
|
end
|
143
166
|
self.parallel_executor.shutdown
|
167
|
+
|
168
|
+
# might have been removed/replaced during init_plugins:
|
169
|
+
summary = reporter.reporters.grep(SummaryReporter).first
|
170
|
+
return empty_run! options if summary && summary.count == 0
|
171
|
+
|
144
172
|
reporter.report
|
145
173
|
|
146
174
|
reporter.passed?
|
147
175
|
end
|
148
176
|
|
177
|
+
def self.empty_run! options # :nodoc:
|
178
|
+
filter = options[:filter]
|
179
|
+
return true unless filter # no filter, but nothing ran == success
|
180
|
+
|
181
|
+
warn "Nothing ran for filter: %s" % [filter]
|
182
|
+
|
183
|
+
require "did_you_mean" # soft dependency, punt if it doesn't load
|
184
|
+
|
185
|
+
ms = Runnable.runnables.flat_map(&:runnable_methods)
|
186
|
+
cs = DidYouMean::SpellChecker.new(dictionary: ms).correct filter
|
187
|
+
|
188
|
+
warn DidYouMean::Formatter.message_for cs unless cs.empty?
|
189
|
+
rescue LoadError
|
190
|
+
# do nothing
|
191
|
+
end
|
192
|
+
|
149
193
|
##
|
150
194
|
# Internal run method. Responsible for telling all Runnable
|
151
195
|
# sub-classes to run.
|
152
196
|
|
153
197
|
def self.__run reporter, options
|
154
|
-
suites = Runnable.runnables.
|
198
|
+
suites = Runnable.runnables.shuffle
|
155
199
|
parallel, serial = suites.partition { |s| s.test_order == :parallel }
|
156
200
|
|
157
201
|
# If we run the parallel tests before the serial tests, the parallel tests
|
@@ -189,6 +233,14 @@ module Minitest
|
|
189
233
|
options[:verbose] = true
|
190
234
|
end
|
191
235
|
|
236
|
+
opts.on "-q", "--quiet", "Quiet. Show no progress processing files." do
|
237
|
+
options[:quiet] = true
|
238
|
+
end
|
239
|
+
|
240
|
+
opts.on "--show-skips", "Show skipped at the end of run." do
|
241
|
+
options[:show_skips] = true
|
242
|
+
end
|
243
|
+
|
192
244
|
opts.on "-n", "--name PATTERN", "Filter run on /regexp/ or string." do |a|
|
193
245
|
options[:filter] = a
|
194
246
|
end
|
@@ -197,6 +249,10 @@ module Minitest
|
|
197
249
|
options[:exclude] = a
|
198
250
|
end
|
199
251
|
|
252
|
+
opts.on "-S", "--skip CODES", String, "Skip reporting of certain types of results (eg E)." do |s|
|
253
|
+
options[:skip] = s.chars.to_a
|
254
|
+
end
|
255
|
+
|
200
256
|
unless extensions.empty?
|
201
257
|
opts.separator ""
|
202
258
|
opts.separator "Known extensions: #{extensions.join(", ")}"
|
@@ -226,8 +282,6 @@ module Minitest
|
|
226
282
|
orig_args << "--seed" << options[:seed].to_s
|
227
283
|
end
|
228
284
|
|
229
|
-
srand options[:seed]
|
230
|
-
|
231
285
|
options[:args] = orig_args.map { |s|
|
232
286
|
s =~ /[\s|&<>$()]/ ? s.inspect : s
|
233
287
|
}.join " "
|
@@ -236,7 +290,9 @@ module Minitest
|
|
236
290
|
end
|
237
291
|
|
238
292
|
def self.filter_backtrace bt # :nodoc:
|
239
|
-
backtrace_filter.filter bt
|
293
|
+
result = backtrace_filter.filter bt
|
294
|
+
result = bt.dup if result.empty?
|
295
|
+
result
|
240
296
|
end
|
241
297
|
|
242
298
|
##
|
@@ -303,19 +359,15 @@ module Minitest
|
|
303
359
|
# reporter to record.
|
304
360
|
|
305
361
|
def self.run reporter, options = {}
|
306
|
-
|
307
|
-
|
362
|
+
pos = options[:filter]
|
363
|
+
neg = options[:exclude]
|
308
364
|
|
309
|
-
|
310
|
-
|
311
|
-
}
|
312
|
-
|
313
|
-
exclude = options[:exclude]
|
314
|
-
exclude = Regexp.new $1 if exclude =~ %r%/(.*)/%
|
365
|
+
pos = Regexp.new $1 if pos.is_a?(String) && pos =~ %r%/(.*)/%
|
366
|
+
neg = Regexp.new $1 if neg.is_a?(String) && neg =~ %r%/(.*)/%
|
315
367
|
|
316
|
-
filtered_methods
|
317
|
-
|
318
|
-
|
368
|
+
filtered_methods = self.runnable_methods
|
369
|
+
.select { |m| !pos || pos === m || pos === "#{self}##{m}" }
|
370
|
+
.reject { |m| neg && (neg === m || neg === "#{self}##{m}") }
|
319
371
|
|
320
372
|
return if filtered_methods.empty?
|
321
373
|
|
@@ -337,6 +389,14 @@ module Minitest
|
|
337
389
|
reporter.record Minitest.run_one_method(klass, method_name)
|
338
390
|
end
|
339
391
|
|
392
|
+
##
|
393
|
+
# Defines the order to run tests (:random by default). Override
|
394
|
+
# this or use a convenience method to change it for your tests.
|
395
|
+
|
396
|
+
def self.test_order
|
397
|
+
:random
|
398
|
+
end
|
399
|
+
|
340
400
|
def self.with_info_handler reporter, &block # :nodoc:
|
341
401
|
handler = lambda do
|
342
402
|
unless reporter.passed? then
|
@@ -404,6 +464,31 @@ module Minitest
|
|
404
464
|
self.name = name
|
405
465
|
self.failures = []
|
406
466
|
self.assertions = 0
|
467
|
+
# lazy initializer for metadata
|
468
|
+
end
|
469
|
+
|
470
|
+
##
|
471
|
+
# Metadata you attach to the test results that get sent to the reporter.
|
472
|
+
#
|
473
|
+
# Lazily initializes to a hash, to keep memory down.
|
474
|
+
#
|
475
|
+
# NOTE: this data *must* be plain (read: marshal-able) data!
|
476
|
+
# Hashes! Arrays! Strings!
|
477
|
+
|
478
|
+
def metadata
|
479
|
+
@metadata ||= {}
|
480
|
+
end
|
481
|
+
|
482
|
+
##
|
483
|
+
# Sets metadata, mainly used for +Result.from+.
|
484
|
+
|
485
|
+
attr_writer :metadata
|
486
|
+
|
487
|
+
##
|
488
|
+
# Returns true if metadata exists.
|
489
|
+
|
490
|
+
def metadata?
|
491
|
+
defined? @metadata
|
407
492
|
end
|
408
493
|
|
409
494
|
##
|
@@ -425,7 +510,8 @@ module Minitest
|
|
425
510
|
|
426
511
|
##
|
427
512
|
# Returns a single character string to print based on the result
|
428
|
-
# of the run.
|
513
|
+
# of the run. One of <tt>"."</tt>, <tt>"F"</tt>,
|
514
|
+
# <tt>"E"</tt> or <tt>"S"</tt>.
|
429
515
|
|
430
516
|
def result_code
|
431
517
|
raise NotImplementedError, "subclass responsibility"
|
@@ -454,12 +540,14 @@ module Minitest
|
|
454
540
|
not self.failure
|
455
541
|
end
|
456
542
|
|
543
|
+
BASE_DIR = "#{Dir.pwd}/" # :nodoc:
|
544
|
+
|
457
545
|
##
|
458
546
|
# The location identifier of this test. Depends on a method
|
459
547
|
# existing called class_name.
|
460
548
|
|
461
549
|
def location
|
462
|
-
loc = " [#{self.failure.location}]" unless passed? or error?
|
550
|
+
loc = " [#{self.failure.location.delete_prefix BASE_DIR}]" unless passed? or error?
|
463
551
|
"#{self.class_name}##{self.name}#{loc}"
|
464
552
|
end
|
465
553
|
|
@@ -523,6 +611,7 @@ module Minitest
|
|
523
611
|
r.assertions = o.assertions
|
524
612
|
r.failures = o.failures.dup
|
525
613
|
r.time = o.time
|
614
|
+
r.metadata = o.metadata if o.metadata?
|
526
615
|
|
527
616
|
r.source_location = o.method(o.name).source_location rescue ["unknown", -1]
|
528
617
|
|
@@ -547,7 +636,10 @@ module Minitest
|
|
547
636
|
# you want. Go nuts.
|
548
637
|
|
549
638
|
class AbstractReporter
|
550
|
-
|
639
|
+
|
640
|
+
def initialize # :nodoc:
|
641
|
+
@mutex = Mutex.new
|
642
|
+
end
|
551
643
|
|
552
644
|
##
|
553
645
|
# Starts reporting on the run.
|
@@ -563,8 +655,10 @@ module Minitest
|
|
563
655
|
end
|
564
656
|
|
565
657
|
##
|
566
|
-
#
|
567
|
-
# result
|
658
|
+
# Output and record the result of the test. Call
|
659
|
+
# {result#result_code}[rdoc-ref:Runnable#result_code] to get the
|
660
|
+
# result character string. Stores the result of the run if the run
|
661
|
+
# did not pass.
|
568
662
|
|
569
663
|
def record result
|
570
664
|
end
|
@@ -581,6 +675,10 @@ module Minitest
|
|
581
675
|
def passed?
|
582
676
|
true
|
583
677
|
end
|
678
|
+
|
679
|
+
def synchronize(&block) # :nodoc:
|
680
|
+
@mutex.synchronize(&block)
|
681
|
+
end
|
584
682
|
end
|
585
683
|
|
586
684
|
class Reporter < AbstractReporter # :nodoc:
|
@@ -631,18 +729,63 @@ module Minitest
|
|
631
729
|
#
|
632
730
|
# If you want to create an entirely different type of output (eg,
|
633
731
|
# CI, HTML, etc), this is the place to start.
|
732
|
+
#
|
733
|
+
# Example:
|
734
|
+
#
|
735
|
+
# class JenkinsCIReporter < StatisticsReporter
|
736
|
+
# def report
|
737
|
+
# super # Needed to calculate some statistics
|
738
|
+
#
|
739
|
+
# print "<testsuite "
|
740
|
+
# print "tests='#{count}' "
|
741
|
+
# print "failures='#{failures}' "
|
742
|
+
# # Remaining XML...
|
743
|
+
# end
|
744
|
+
# end
|
634
745
|
|
635
746
|
class StatisticsReporter < Reporter
|
636
|
-
|
747
|
+
##
|
748
|
+
# Total number of assertions.
|
749
|
+
|
637
750
|
attr_accessor :assertions
|
751
|
+
|
752
|
+
##
|
753
|
+
# Total number of test cases.
|
754
|
+
|
638
755
|
attr_accessor :count
|
756
|
+
|
757
|
+
##
|
758
|
+
# An +Array+ of test cases that failed or were skipped.
|
759
|
+
|
639
760
|
attr_accessor :results
|
761
|
+
|
762
|
+
##
|
763
|
+
# Time the test run started. If available, the monotonic clock is
|
764
|
+
# used and this is a +Float+, otherwise it's an instance of
|
765
|
+
# +Time+.
|
766
|
+
|
640
767
|
attr_accessor :start_time
|
768
|
+
|
769
|
+
##
|
770
|
+
# Test run time. If available, the monotonic clock is used and
|
771
|
+
# this is a +Float+, otherwise it's an instance of +Time+.
|
772
|
+
|
641
773
|
attr_accessor :total_time
|
774
|
+
|
775
|
+
##
|
776
|
+
# Total number of tests that failed.
|
777
|
+
|
642
778
|
attr_accessor :failures
|
779
|
+
|
780
|
+
##
|
781
|
+
# Total number of tests that erred.
|
782
|
+
|
643
783
|
attr_accessor :errors
|
784
|
+
|
785
|
+
##
|
786
|
+
# Total number of tests that where skipped.
|
787
|
+
|
644
788
|
attr_accessor :skips
|
645
|
-
# :startdoc:
|
646
789
|
|
647
790
|
def initialize io = $stdout, options = {} # :nodoc:
|
648
791
|
super
|
@@ -672,7 +815,10 @@ module Minitest
|
|
672
815
|
results << result if not result.passed? or result.skipped?
|
673
816
|
end
|
674
817
|
|
675
|
-
|
818
|
+
##
|
819
|
+
# Report on the tracked statistics.
|
820
|
+
|
821
|
+
def report
|
676
822
|
aggregate = results.group_by { |r| r.failure.class }
|
677
823
|
aggregate.default = [] # dumb. group_by should provide this
|
678
824
|
|
@@ -706,7 +852,7 @@ module Minitest
|
|
706
852
|
io.puts "# Running:"
|
707
853
|
io.puts
|
708
854
|
|
709
|
-
self.sync = io.respond_to? :"sync="
|
855
|
+
self.sync = io.respond_to? :"sync="
|
710
856
|
self.old_sync, io.sync = io.sync, true if self.sync
|
711
857
|
end
|
712
858
|
|
@@ -729,9 +875,14 @@ module Minitest
|
|
729
875
|
|
730
876
|
def aggregated_results io # :nodoc:
|
731
877
|
filtered_results = results.dup
|
732
|
-
filtered_results.reject!(&:skipped?) unless
|
878
|
+
filtered_results.reject!(&:skipped?) unless
|
879
|
+
options[:verbose] or options[:show_skips]
|
880
|
+
|
881
|
+
skip = options[:skip] || []
|
733
882
|
|
734
883
|
filtered_results.each_with_index { |result, i|
|
884
|
+
next if skip.include? result.result_code
|
885
|
+
|
735
886
|
io.puts "\n%3d) %s" % [i+1, result]
|
736
887
|
}
|
737
888
|
io.puts
|
@@ -739,26 +890,19 @@ module Minitest
|
|
739
890
|
end
|
740
891
|
|
741
892
|
def to_s # :nodoc:
|
742
|
-
aggregated_results(StringIO.new(
|
893
|
+
aggregated_results(StringIO.new(''.b)).string
|
743
894
|
end
|
744
895
|
|
745
896
|
def summary # :nodoc:
|
746
897
|
extra = ""
|
747
898
|
|
748
899
|
extra = "\n\nYou have skipped tests. Run with --verbose for details." if
|
749
|
-
results.any?(&:skipped?) unless
|
900
|
+
results.any?(&:skipped?) unless
|
901
|
+
options[:verbose] or options[:show_skips] or ENV["MT_NO_SKIP_MSG"]
|
750
902
|
|
751
903
|
"%d runs, %d assertions, %d failures, %d errors, %d skips%s" %
|
752
904
|
[count, assertions, failures, errors, skips, extra]
|
753
905
|
end
|
754
|
-
|
755
|
-
private
|
756
|
-
|
757
|
-
if '<3'.respond_to? :b
|
758
|
-
def binary_string; ''.b; end
|
759
|
-
else
|
760
|
-
def binary_string; ''.force_encoding(Encoding::ASCII_8BIT); end
|
761
|
-
end
|
762
906
|
end
|
763
907
|
|
764
908
|
##
|
@@ -816,6 +960,8 @@ module Minitest
|
|
816
960
|
# Represents run failures.
|
817
961
|
|
818
962
|
class Assertion < Exception
|
963
|
+
RE = /in .(?:assert|refute|flunk|pass|fail|raise|must|wont)/ # :nodoc:
|
964
|
+
|
819
965
|
def error # :nodoc:
|
820
966
|
self
|
821
967
|
end
|
@@ -824,12 +970,11 @@ module Minitest
|
|
824
970
|
# Where was this run before an assertion was raised?
|
825
971
|
|
826
972
|
def location
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
last_before_assertion.sub(/:in .*$/, "")
|
973
|
+
bt = Minitest.filter_backtrace self.backtrace
|
974
|
+
idx = bt.rindex { |s| s.match? RE } || -1 # fall back to first item
|
975
|
+
loc = bt[idx+1] || bt.last || "unknown:-1"
|
976
|
+
|
977
|
+
loc.sub(/:in .*$/, "")
|
833
978
|
end
|
834
979
|
|
835
980
|
def result_code # :nodoc:
|
@@ -854,24 +999,34 @@ module Minitest
|
|
854
999
|
# Assertion wrapping an unexpected error that was raised during a run.
|
855
1000
|
|
856
1001
|
class UnexpectedError < Assertion
|
857
|
-
|
1002
|
+
include Minitest::Compress
|
858
1003
|
|
859
|
-
|
1004
|
+
# TODO: figure out how to use `cause` instead
|
1005
|
+
attr_accessor :error # :nodoc:
|
1006
|
+
|
1007
|
+
def initialize error # :nodoc:
|
860
1008
|
super "Unexpected exception"
|
861
|
-
|
1009
|
+
|
1010
|
+
if SystemStackError === error then
|
1011
|
+
bt = error.backtrace
|
1012
|
+
new_bt = compress bt
|
1013
|
+
error = error.exception "#{bt.size} -> #{new_bt.size}"
|
1014
|
+
error.set_backtrace new_bt
|
1015
|
+
end
|
1016
|
+
|
1017
|
+
self.error = error
|
862
1018
|
end
|
863
1019
|
|
864
1020
|
def backtrace # :nodoc:
|
865
|
-
self.
|
1021
|
+
self.error.backtrace
|
866
1022
|
end
|
867
1023
|
|
868
|
-
|
869
|
-
self.exception
|
870
|
-
end
|
1024
|
+
BASE_RE = %r%#{Dir.pwd}/% # :nodoc:
|
871
1025
|
|
872
1026
|
def message # :nodoc:
|
873
|
-
bt = Minitest.filter_backtrace(self.backtrace).join
|
874
|
-
|
1027
|
+
bt = Minitest.filter_backtrace(self.backtrace).join("\n ")
|
1028
|
+
.gsub(BASE_RE, "")
|
1029
|
+
"#{self.error.class}: #{self.error.message}\n #{bt}"
|
875
1030
|
end
|
876
1031
|
|
877
1032
|
def result_label # :nodoc:
|
@@ -907,6 +1062,9 @@ module Minitest
|
|
907
1062
|
# Is this running on maglev?
|
908
1063
|
|
909
1064
|
def maglev? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
|
1065
|
+
where = Minitest.filter_backtrace(caller).first
|
1066
|
+
where = where.split(/:in /, 2).first # clean up noise
|
1067
|
+
warn "DEPRECATED: `maglev?` called from #{where}. This will fail in Minitest 6."
|
910
1068
|
"maglev" == platform
|
911
1069
|
end
|
912
1070
|
|
@@ -917,10 +1075,20 @@ module Minitest
|
|
917
1075
|
/^ruby/ =~ platform
|
918
1076
|
end
|
919
1077
|
|
1078
|
+
##
|
1079
|
+
# Is this running on macOS?
|
1080
|
+
|
1081
|
+
def osx? platform = RUBY_PLATFORM
|
1082
|
+
/darwin/ =~ platform
|
1083
|
+
end
|
1084
|
+
|
920
1085
|
##
|
921
1086
|
# Is this running on rubinius?
|
922
1087
|
|
923
1088
|
def rubinius? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
|
1089
|
+
where = Minitest.filter_backtrace(caller).first
|
1090
|
+
where = where.split(/:in /, 2).first # clean up noise
|
1091
|
+
warn "DEPRECATED: `rubinius?` called from #{where}. This will fail in Minitest 6."
|
924
1092
|
"rbx" == platform
|
925
1093
|
end
|
926
1094
|
|
@@ -941,17 +1109,24 @@ module Minitest
|
|
941
1109
|
|
942
1110
|
MT_RE = %r%lib/minitest% #:nodoc:
|
943
1111
|
|
1112
|
+
attr_accessor :regexp
|
1113
|
+
|
1114
|
+
def initialize regexp = MT_RE
|
1115
|
+
self.regexp = regexp
|
1116
|
+
end
|
1117
|
+
|
944
1118
|
##
|
945
|
-
# Filter +bt+ to something useful. Returns the whole thing if
|
1119
|
+
# Filter +bt+ to something useful. Returns the whole thing if
|
1120
|
+
# $DEBUG (ruby) or $MT_DEBUG (env).
|
946
1121
|
|
947
1122
|
def filter bt
|
948
1123
|
return ["No backtrace"] unless bt
|
949
1124
|
|
950
|
-
return bt.dup if $DEBUG
|
1125
|
+
return bt.dup if $DEBUG || ENV["MT_DEBUG"]
|
951
1126
|
|
952
|
-
new_bt = bt.take_while { |line| line !~
|
953
|
-
new_bt = bt.select { |line| line !~
|
954
|
-
new_bt = bt.dup
|
1127
|
+
new_bt = bt.take_while { |line| line.to_s !~ regexp }
|
1128
|
+
new_bt = bt.select { |line| line.to_s !~ regexp } if new_bt.empty?
|
1129
|
+
new_bt = bt.dup if new_bt.empty?
|
955
1130
|
|
956
1131
|
new_bt
|
957
1132
|
end
|
@@ -6,8 +6,28 @@ class Minitest::Test
|
|
6
6
|
def clean s
|
7
7
|
s.gsub(/^ {6}/, "")
|
8
8
|
end
|
9
|
+
|
10
|
+
def with_empty_backtrace_filter
|
11
|
+
with_backtrace_filter Minitest::BacktraceFilter.new %r%.% do
|
12
|
+
yield
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def with_backtrace_filter filter
|
17
|
+
original = Minitest.backtrace_filter
|
18
|
+
|
19
|
+
Minitest::Test.io_lock.synchronize do # try not to trounce in parallel
|
20
|
+
begin
|
21
|
+
Minitest.backtrace_filter = filter
|
22
|
+
yield
|
23
|
+
ensure
|
24
|
+
Minitest.backtrace_filter = original
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
9
28
|
end
|
10
29
|
|
30
|
+
|
11
31
|
class FakeNamedTest < Minitest::Test
|
12
32
|
@@count = 0
|
13
33
|
|
@@ -25,6 +45,14 @@ class AnError < StandardError; include MyModule; end
|
|
25
45
|
class MetaMetaMetaTestCase < Minitest::Test
|
26
46
|
attr_accessor :reporter, :output, :tu
|
27
47
|
|
48
|
+
def with_stderr err
|
49
|
+
old = $stderr
|
50
|
+
$stderr = err
|
51
|
+
yield
|
52
|
+
ensure
|
53
|
+
$stderr = old
|
54
|
+
end
|
55
|
+
|
28
56
|
def run_tu_with_fresh_reporter flags = %w[--seed 42]
|
29
57
|
options = Minitest.process_args flags
|
30
58
|
|
@@ -34,18 +62,20 @@ class MetaMetaMetaTestCase < Minitest::Test
|
|
34
62
|
reporter << Minitest::SummaryReporter.new(@output, options)
|
35
63
|
reporter << Minitest::ProgressReporter.new(@output, options)
|
36
64
|
|
37
|
-
|
65
|
+
with_stderr @output do
|
66
|
+
reporter.start
|
38
67
|
|
39
|
-
|
68
|
+
yield(reporter) if block_given?
|
40
69
|
|
41
|
-
|
42
|
-
|
43
|
-
|
70
|
+
@tus ||= [@tu]
|
71
|
+
@tus.each do |tu|
|
72
|
+
Minitest::Runnable.runnables.delete tu
|
44
73
|
|
45
|
-
|
46
|
-
|
74
|
+
tu.run reporter, options
|
75
|
+
end
|
47
76
|
|
48
|
-
|
77
|
+
reporter.report
|
78
|
+
end
|
49
79
|
end
|
50
80
|
|
51
81
|
def first_reporter
|
@@ -76,14 +106,18 @@ class MetaMetaMetaTestCase < Minitest::Test
|
|
76
106
|
output.gsub!(/0x[A-Fa-f0-9]+/, "0xXXX")
|
77
107
|
output.gsub!(/ +$/, "")
|
78
108
|
|
109
|
+
file = ->(s) { s.start_with?("/") ? "FULLFILE" : "FILE" }
|
110
|
+
|
79
111
|
if windows? then
|
80
112
|
output.gsub!(/\[(?:[A-Za-z]:)?[^\]:]+:\d+\]/, "[FILE:LINE]")
|
81
113
|
output.gsub!(/^(\s+)(?:[A-Za-z]:)?[^:]+:\d+:in/, '\1FILE:LINE:in')
|
82
114
|
else
|
83
|
-
output.gsub!(/\[[^\]:]
|
84
|
-
output.gsub!(/^(\s+)[^:]
|
115
|
+
output.gsub!(/\[([^\]:]+):\d+\]/) { "[#{file[$1]}:LINE]" }
|
116
|
+
output.gsub!(/^(\s+)([^:]+):\d+:in/) { "#{$1}#{file[$2]}:LINE:in" }
|
85
117
|
end
|
86
118
|
|
119
|
+
output.gsub!(/( at )[^:]+:\d+/) { "#{$1}[#{file[$2]}:LINE]" } # eval?
|
120
|
+
|
87
121
|
output
|
88
122
|
end
|
89
123
|
|
@@ -98,7 +132,7 @@ class MetaMetaMetaTestCase < Minitest::Test
|
|
98
132
|
|
99
133
|
def setup
|
100
134
|
super
|
101
|
-
|
135
|
+
Minitest.seed = 42
|
102
136
|
Minitest::Test.reset
|
103
137
|
@tu = nil
|
104
138
|
end
|