minitest 5.20.0 → 5.24.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 +102 -3
- data/Manifest.txt +3 -0
- data/README.rdoc +16 -13
- data/Rakefile +6 -0
- data/lib/minitest/assertions.rb +15 -13
- data/lib/minitest/autorun.rb +0 -7
- 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 +4 -2
- data/lib/minitest/parallel.rb +1 -1
- data/lib/minitest/pride_plugin.rb +7 -10
- data/lib/minitest/test.rb +4 -3
- data/lib/minitest/test_task.rb +8 -3
- data/lib/minitest.rb +212 -106
- data/test/minitest/metametameta.rb +29 -12
- data/test/minitest/test_minitest_assertions.rb +50 -31
- data/test/minitest/test_minitest_mock.rb +15 -13
- data/test/minitest/test_minitest_reporter.rb +102 -3
- data/test/minitest/test_minitest_spec.rb +19 -17
- data/test/minitest/test_minitest_test.rb +114 -21
- data/test/minitest/test_minitest_test_task.rb +9 -1
- 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.24.0" # :nodoc:
|
|
13
13
|
|
|
14
14
|
@@installed_at_exit ||= false
|
|
15
15
|
@@after_run = []
|
|
@@ -98,20 +98,19 @@ module Minitest
|
|
|
98
98
|
@@after_run << block
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
|
106
107
|
end
|
|
107
108
|
|
|
108
109
|
def self.load_plugins # :nodoc:
|
|
109
|
-
return unless
|
|
110
|
+
return unless defined? Gem
|
|
110
111
|
|
|
111
112
|
seen = {}
|
|
112
113
|
|
|
113
|
-
require "rubygems" unless defined? Gem
|
|
114
|
-
|
|
115
114
|
Gem.find_files("minitest/*_plugin.rb").each do |plugin_path|
|
|
116
115
|
name = File.basename plugin_path, "_plugin.rb"
|
|
117
116
|
|
|
@@ -123,67 +122,22 @@ module Minitest
|
|
|
123
122
|
end
|
|
124
123
|
end
|
|
125
124
|
|
|
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..."
|
|
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
|
|
165
140
|
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
141
|
end
|
|
188
142
|
|
|
189
143
|
def self.process_args args = [] # :nodoc:
|
|
@@ -212,6 +166,10 @@ module Minitest
|
|
|
212
166
|
options[:verbose] = true
|
|
213
167
|
end
|
|
214
168
|
|
|
169
|
+
opts.on "-q", "--quiet", "Quiet. Show no progress processing files." do
|
|
170
|
+
options[:quiet] = true
|
|
171
|
+
end
|
|
172
|
+
|
|
215
173
|
opts.on "--show-skips", "Show skipped at the end of run." do
|
|
216
174
|
options[:show_skips] = true
|
|
217
175
|
end
|
|
@@ -228,13 +186,37 @@ module Minitest
|
|
|
228
186
|
options[:skip] = s.chars.to_a
|
|
229
187
|
end
|
|
230
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
|
+
|
|
231
203
|
unless extensions.empty?
|
|
232
204
|
opts.separator ""
|
|
233
205
|
opts.separator "Known extensions: #{extensions.join(", ")}"
|
|
234
206
|
|
|
235
|
-
extensions.each do |
|
|
236
|
-
|
|
237
|
-
|
|
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
|
|
238
220
|
end
|
|
239
221
|
end
|
|
240
222
|
|
|
@@ -264,6 +246,93 @@ module Minitest
|
|
|
264
246
|
options
|
|
265
247
|
end
|
|
266
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
|
+
|
|
267
336
|
def self.filter_backtrace bt # :nodoc:
|
|
268
337
|
result = backtrace_filter.filter bt
|
|
269
338
|
result = bt.dup if result.empty?
|
|
@@ -334,25 +403,15 @@ module Minitest
|
|
|
334
403
|
# reporter to record.
|
|
335
404
|
|
|
336
405
|
def self.run reporter, options = {}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
filter = Regexp.new $1 if filter.is_a?(String) && filter =~ %r%/(.*)/%
|
|
406
|
+
pos = options[:filter]
|
|
407
|
+
neg = options[:exclude]
|
|
340
408
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
}
|
|
344
|
-
else
|
|
345
|
-
self.runnable_methods
|
|
346
|
-
end
|
|
409
|
+
pos = Regexp.new $1 if pos.is_a?(String) && pos =~ %r%/(.*)/%
|
|
410
|
+
neg = Regexp.new $1 if neg.is_a?(String) && neg =~ %r%/(.*)/%
|
|
347
411
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
filtered_methods.delete_if { |m|
|
|
353
|
-
exclude === m || exclude === "#{self}##{m}"
|
|
354
|
-
}
|
|
355
|
-
end
|
|
412
|
+
filtered_methods = self.runnable_methods
|
|
413
|
+
.select { |m| !pos || pos === m || pos === "#{self}##{m}" }
|
|
414
|
+
.reject { |m| neg && (neg === m || neg === "#{self}##{m}") }
|
|
356
415
|
|
|
357
416
|
return if filtered_methods.empty?
|
|
358
417
|
|
|
@@ -525,12 +584,14 @@ module Minitest
|
|
|
525
584
|
not self.failure
|
|
526
585
|
end
|
|
527
586
|
|
|
587
|
+
BASE_DIR = "#{Dir.pwd}/" # :nodoc:
|
|
588
|
+
|
|
528
589
|
##
|
|
529
590
|
# The location identifier of this test. Depends on a method
|
|
530
591
|
# existing called class_name.
|
|
531
592
|
|
|
532
593
|
def location
|
|
533
|
-
loc = " [#{self.failure.location}]" unless passed? or error?
|
|
594
|
+
loc = " [#{self.failure.location.delete_prefix BASE_DIR}]" unless passed? or error?
|
|
534
595
|
"#{self.class_name}##{self.name}#{loc}"
|
|
535
596
|
end
|
|
536
597
|
|
|
@@ -619,7 +680,10 @@ module Minitest
|
|
|
619
680
|
# you want. Go nuts.
|
|
620
681
|
|
|
621
682
|
class AbstractReporter
|
|
622
|
-
|
|
683
|
+
|
|
684
|
+
def initialize # :nodoc:
|
|
685
|
+
@mutex = Mutex.new
|
|
686
|
+
end
|
|
623
687
|
|
|
624
688
|
##
|
|
625
689
|
# Starts reporting on the run.
|
|
@@ -655,6 +719,10 @@ module Minitest
|
|
|
655
719
|
def passed?
|
|
656
720
|
true
|
|
657
721
|
end
|
|
722
|
+
|
|
723
|
+
def synchronize(&block) # :nodoc:
|
|
724
|
+
@mutex.synchronize(&block)
|
|
725
|
+
end
|
|
658
726
|
end
|
|
659
727
|
|
|
660
728
|
class Reporter < AbstractReporter # :nodoc:
|
|
@@ -758,6 +826,11 @@ module Minitest
|
|
|
758
826
|
|
|
759
827
|
attr_accessor :errors
|
|
760
828
|
|
|
829
|
+
##
|
|
830
|
+
# Total number of tests that warned.
|
|
831
|
+
|
|
832
|
+
attr_accessor :warnings
|
|
833
|
+
|
|
761
834
|
##
|
|
762
835
|
# Total number of tests that where skipped.
|
|
763
836
|
|
|
@@ -773,6 +846,7 @@ module Minitest
|
|
|
773
846
|
self.total_time = nil
|
|
774
847
|
self.failures = nil
|
|
775
848
|
self.errors = nil
|
|
849
|
+
self.warnings = nil
|
|
776
850
|
self.skips = nil
|
|
777
851
|
end
|
|
778
852
|
|
|
@@ -801,6 +875,7 @@ module Minitest
|
|
|
801
875
|
self.total_time = Minitest.clock_time - start_time
|
|
802
876
|
self.failures = aggregate[Assertion].size
|
|
803
877
|
self.errors = aggregate[UnexpectedError].size
|
|
878
|
+
self.warnings = aggregate[UnexpectedWarning].size
|
|
804
879
|
self.skips = aggregate[Skip].size
|
|
805
880
|
end
|
|
806
881
|
end
|
|
@@ -828,7 +903,7 @@ module Minitest
|
|
|
828
903
|
io.puts "# Running:"
|
|
829
904
|
io.puts
|
|
830
905
|
|
|
831
|
-
self.sync = io.respond_to? :"sync="
|
|
906
|
+
self.sync = io.respond_to? :"sync="
|
|
832
907
|
self.old_sync, io.sync = io.sync, true if self.sync
|
|
833
908
|
end
|
|
834
909
|
|
|
@@ -876,6 +951,8 @@ module Minitest
|
|
|
876
951
|
results.any?(&:skipped?) unless
|
|
877
952
|
options[:verbose] or options[:show_skips] or ENV["MT_NO_SKIP_MSG"]
|
|
878
953
|
|
|
954
|
+
extra.prepend ", %d warnings" % [warnings] if options[:Werror]
|
|
955
|
+
|
|
879
956
|
"%d runs, %d assertions, %d failures, %d errors, %d skips%s" %
|
|
880
957
|
[count, assertions, failures, errors, skips, extra]
|
|
881
958
|
end
|
|
@@ -936,6 +1013,8 @@ module Minitest
|
|
|
936
1013
|
# Represents run failures.
|
|
937
1014
|
|
|
938
1015
|
class Assertion < Exception
|
|
1016
|
+
RE = /in [`'](?:[^']+[#.])?(?:assert|refute|flunk|pass|fail|raise|must|wont)/ # :nodoc:
|
|
1017
|
+
|
|
939
1018
|
def error # :nodoc:
|
|
940
1019
|
self
|
|
941
1020
|
end
|
|
@@ -944,12 +1023,11 @@ module Minitest
|
|
|
944
1023
|
# Where was this run before an assertion was raised?
|
|
945
1024
|
|
|
946
1025
|
def location
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
last_before_assertion.sub(/:in .*$/, "")
|
|
1026
|
+
bt = Minitest.filter_backtrace self.backtrace
|
|
1027
|
+
idx = bt.rindex { |s| s.match? RE } || -1 # fall back to first item
|
|
1028
|
+
loc = bt[idx+1] || bt.last || "unknown:-1"
|
|
1029
|
+
|
|
1030
|
+
loc.sub(/:in .*$/, "")
|
|
953
1031
|
end
|
|
954
1032
|
|
|
955
1033
|
def result_code # :nodoc:
|
|
@@ -974,11 +1052,21 @@ module Minitest
|
|
|
974
1052
|
# Assertion wrapping an unexpected error that was raised during a run.
|
|
975
1053
|
|
|
976
1054
|
class UnexpectedError < Assertion
|
|
1055
|
+
include Minitest::Compress
|
|
1056
|
+
|
|
977
1057
|
# TODO: figure out how to use `cause` instead
|
|
978
1058
|
attr_accessor :error # :nodoc:
|
|
979
1059
|
|
|
980
1060
|
def initialize error # :nodoc:
|
|
981
1061
|
super "Unexpected exception"
|
|
1062
|
+
|
|
1063
|
+
if SystemStackError === error then
|
|
1064
|
+
bt = error.backtrace
|
|
1065
|
+
new_bt = compress bt
|
|
1066
|
+
error = error.exception "#{bt.size} -> #{new_bt.size}"
|
|
1067
|
+
error.set_backtrace new_bt
|
|
1068
|
+
end
|
|
1069
|
+
|
|
982
1070
|
self.error = error
|
|
983
1071
|
end
|
|
984
1072
|
|
|
@@ -986,8 +1074,11 @@ module Minitest
|
|
|
986
1074
|
self.error.backtrace
|
|
987
1075
|
end
|
|
988
1076
|
|
|
1077
|
+
BASE_RE = %r%#{Dir.pwd}/% # :nodoc:
|
|
1078
|
+
|
|
989
1079
|
def message # :nodoc:
|
|
990
|
-
bt = Minitest.filter_backtrace(self.backtrace).join
|
|
1080
|
+
bt = Minitest.filter_backtrace(self.backtrace).join("\n ")
|
|
1081
|
+
.gsub(BASE_RE, "")
|
|
991
1082
|
"#{self.error.class}: #{self.error.message}\n #{bt}"
|
|
992
1083
|
end
|
|
993
1084
|
|
|
@@ -996,6 +1087,15 @@ module Minitest
|
|
|
996
1087
|
end
|
|
997
1088
|
end
|
|
998
1089
|
|
|
1090
|
+
##
|
|
1091
|
+
# Assertion raised on warning when running in -Werror mode.
|
|
1092
|
+
|
|
1093
|
+
class UnexpectedWarning < Assertion
|
|
1094
|
+
def result_label # :nodoc:
|
|
1095
|
+
"Warning"
|
|
1096
|
+
end
|
|
1097
|
+
end
|
|
1098
|
+
|
|
999
1099
|
##
|
|
1000
1100
|
# Provides a simple set of guards that you can use in your tests
|
|
1001
1101
|
# to skip execution if it is not applicable. These methods are
|
|
@@ -1069,7 +1169,13 @@ module Minitest
|
|
|
1069
1169
|
|
|
1070
1170
|
class BacktraceFilter
|
|
1071
1171
|
|
|
1072
|
-
MT_RE = %r%lib/minitest% #:nodoc:
|
|
1172
|
+
MT_RE = %r%lib/minitest|internal:warning% #:nodoc:
|
|
1173
|
+
|
|
1174
|
+
attr_accessor :regexp
|
|
1175
|
+
|
|
1176
|
+
def initialize regexp = MT_RE
|
|
1177
|
+
self.regexp = regexp
|
|
1178
|
+
end
|
|
1073
1179
|
|
|
1074
1180
|
##
|
|
1075
1181
|
# Filter +bt+ to something useful. Returns the whole thing if
|
|
@@ -1080,9 +1186,9 @@ module Minitest
|
|
|
1080
1186
|
|
|
1081
1187
|
return bt.dup if $DEBUG || ENV["MT_DEBUG"]
|
|
1082
1188
|
|
|
1083
|
-
new_bt = bt.take_while { |line| line !~
|
|
1084
|
-
new_bt = bt.select { |line| line !~
|
|
1085
|
-
new_bt = bt.dup
|
|
1189
|
+
new_bt = bt.take_while { |line| line.to_s !~ regexp }
|
|
1190
|
+
new_bt = bt.select { |line| line.to_s !~ regexp } if new_bt.empty?
|
|
1191
|
+
new_bt = bt.dup if new_bt.empty?
|
|
1086
1192
|
|
|
1087
1193
|
new_bt
|
|
1088
1194
|
end
|
|
@@ -8,24 +8,36 @@ class Minitest::Test
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def with_empty_backtrace_filter
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
obj = Minitest::BacktraceFilter.new
|
|
14
|
-
def obj.filter _bt
|
|
15
|
-
[]
|
|
11
|
+
with_backtrace_filter Minitest::BacktraceFilter.new %r%.% do
|
|
12
|
+
yield
|
|
16
13
|
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def with_backtrace_filter filter
|
|
17
|
+
original = Minitest.backtrace_filter
|
|
17
18
|
|
|
18
19
|
Minitest::Test.io_lock.synchronize do # try not to trounce in parallel
|
|
19
20
|
begin
|
|
20
|
-
Minitest.backtrace_filter =
|
|
21
|
+
Minitest.backtrace_filter = filter
|
|
21
22
|
yield
|
|
22
23
|
ensure
|
|
23
24
|
Minitest.backtrace_filter = original
|
|
24
25
|
end
|
|
25
26
|
end
|
|
26
27
|
end
|
|
27
|
-
end
|
|
28
28
|
|
|
29
|
+
def error_on_warn?
|
|
30
|
+
defined?(Minitest::ErrorOnWarning)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def assert_deprecation re = /DEPRECATED/
|
|
34
|
+
assert_output "", re do
|
|
35
|
+
yield
|
|
36
|
+
end
|
|
37
|
+
rescue Minitest::UnexpectedWarning => e # raised if -Werror was used
|
|
38
|
+
assert_match re, e.message
|
|
39
|
+
end
|
|
40
|
+
end
|
|
29
41
|
|
|
30
42
|
class FakeNamedTest < Minitest::Test
|
|
31
43
|
@@count = 0
|
|
@@ -55,7 +67,7 @@ class MetaMetaMetaTestCase < Minitest::Test
|
|
|
55
67
|
def run_tu_with_fresh_reporter flags = %w[--seed 42]
|
|
56
68
|
options = Minitest.process_args flags
|
|
57
69
|
|
|
58
|
-
@output = StringIO.new("".encode(
|
|
70
|
+
@output = StringIO.new("".encode(Encoding::UTF_8))
|
|
59
71
|
|
|
60
72
|
self.reporter = Minitest::CompositeReporter.new
|
|
61
73
|
reporter << Minitest::SummaryReporter.new(@output, options)
|
|
@@ -105,15 +117,20 @@ class MetaMetaMetaTestCase < Minitest::Test
|
|
|
105
117
|
output.gsub!(/0x[A-Fa-f0-9]+/, "0xXXX")
|
|
106
118
|
output.gsub!(/ +$/, "")
|
|
107
119
|
|
|
120
|
+
file = ->(s) { s.start_with?("/") ? "FULLFILE" : "FILE" }
|
|
121
|
+
|
|
108
122
|
if windows? then
|
|
109
123
|
output.gsub!(/\[(?:[A-Za-z]:)?[^\]:]+:\d+\]/, "[FILE:LINE]")
|
|
110
|
-
output.gsub!(/^(\s+)(?:[A-Za-z]:)?[^:]+:\d+:in/, '\1FILE:LINE:in')
|
|
124
|
+
output.gsub!(/^(\s+)(?:[A-Za-z]:)?[^:]+:\d+:in [`']/, '\1FILE:LINE:in \'')
|
|
111
125
|
else
|
|
112
|
-
output.gsub!(/\[[^\]:]
|
|
113
|
-
output.gsub!(/^(\s+)[^:]
|
|
126
|
+
output.gsub!(/\[([^\]:]+):\d+\]/) { "[#{file[$1]}:LINE]" }
|
|
127
|
+
output.gsub!(/^(\s+)([^:]+):\d+:in [`']/) { "#{$1}#{file[$2]}:LINE:in '" }
|
|
114
128
|
end
|
|
115
129
|
|
|
116
|
-
output.gsub!(/
|
|
130
|
+
output.gsub!(/in [`']block in (?:([^']+)[#.])?/, "in 'block in")
|
|
131
|
+
output.gsub!(/in [`'](?:([^']+)[#.])?/, "in '")
|
|
132
|
+
|
|
133
|
+
output.gsub!(/( at )[^:]+:\d+/) { "#{$1}[#{file[$2]}:LINE]" } # eval?
|
|
117
134
|
|
|
118
135
|
output
|
|
119
136
|
end
|