minitest 5.20.0 → 5.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/History.rdoc +46 -3
- data/Manifest.txt +1 -0
- data/README.rdoc +1 -0
- data/lib/minitest/assertions.rb +15 -13
- data/lib/minitest/compress.rb +94 -0
- data/lib/minitest/mock.rb +4 -2
- data/lib/minitest/test_task.rb +0 -1
- data/lib/minitest.rb +81 -36
- data/test/minitest/metametameta.rb +12 -9
- data/test/minitest/test_minitest_assertions.rb +22 -6
- data/test/minitest/test_minitest_reporter.rb +99 -0
- data/test/minitest/test_minitest_test.rb +93 -0
- data.tar.gz.sig +4 -4
- metadata +15 -13
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36a02c1522b429152689b46166cd66d5325797d0f4efb35c96458932a7917ba8
|
4
|
+
data.tar.gz: 699070f4a0c1e0acd2e277c602638373b1d470768a668793e6890aae6e7e49b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e95a14b71c9cd2e27a26c6593d59075357ecc177b8b618e82dd0c5e03ba13f0322f1f0b36c429022450ae98a0fe6039e210dd7a774c0af93ca970d641e6acb16
|
7
|
+
data.tar.gz: 7b1bf55227d08443c8270e04d093981fda13aa37f9fd855a3fb74e77ad0c9b8e9c8d391f519f5173151614b3c074e86639a0a9503ff89afd6fad8ddbd44b800f
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/History.rdoc
CHANGED
@@ -1,3 +1,46 @@
|
|
1
|
+
=== 5.22.0 / 2024-02-05
|
2
|
+
|
3
|
+
* 1 minor enhancement:
|
4
|
+
|
5
|
+
* Added "did you mean" output if your --name filter matches nothing. (tenderlove)
|
6
|
+
|
7
|
+
* 2 bug fixes:
|
8
|
+
|
9
|
+
* Big cleanup of test filtering. Much prettier / more functional.
|
10
|
+
* Fix situation where Assertion#location can't find the location. (pftg)
|
11
|
+
|
12
|
+
=== 5.21.2 / 2024-01-17
|
13
|
+
|
14
|
+
* 1 bug fix:
|
15
|
+
|
16
|
+
* Fixed bug in Minitest::Compress#compress formatting w/ nested patterns. Now recurses properly.
|
17
|
+
|
18
|
+
=== 5.21.1 / 2024-01-11
|
19
|
+
|
20
|
+
* 1 bug fix:
|
21
|
+
|
22
|
+
* Rails' default backtrace filter can't currently work with caller_locations, so reverting back to caller.
|
23
|
+
|
24
|
+
=== 5.21.0 / 2024-01-11
|
25
|
+
|
26
|
+
* 10 minor enhancements:
|
27
|
+
|
28
|
+
* Add include_all kw arg to assert_respond_to and refute_respond_to.
|
29
|
+
* Added --quiet flag to skip ProgressReporter (prints the dots). Minor speedup.
|
30
|
+
* Added Minitest::Compress#compress and added it to UnexpectedError.
|
31
|
+
* Added ability to initialize BacktraceFilter w/ custom regexp.
|
32
|
+
* Filter failure backtraces using backtrace_filter before calculating location. (thomasmarshall)
|
33
|
+
* Make BacktraceFilter#filter compatible with locations (still compares strings).
|
34
|
+
* Optimized Assertion#location ~30%.
|
35
|
+
* Output relative paths for all failures/errors/backtraces.
|
36
|
+
* Refactored location information in assertions, now using locations.
|
37
|
+
* Removed thread and mutex_m dependencies. (hsbt, eregon)
|
38
|
+
|
39
|
+
* 2 bug fixes:
|
40
|
+
|
41
|
+
* Drop undocumented bt arg in #skip. Dunno why that ever happened, prolly for testing?
|
42
|
+
* Fix mock to work with ruby debugger enabled. (keithlayne)
|
43
|
+
|
1
44
|
=== 5.20.0 / 2023-09-06
|
2
45
|
|
3
46
|
* 1 minor enhancement:
|
@@ -9,7 +52,7 @@
|
|
9
52
|
* 2 minor enhancements:
|
10
53
|
|
11
54
|
* Add metadata lazy accessor to Runnable / Result. (matteeyah)
|
12
|
-
* Only load minitest/unit (aka ancient MiniTest compatibility layer) if ENV["MT_COMPAT"]
|
55
|
+
* Only load minitest/unit (aka ancient MiniTest compatibility layer) if \ENV[\"MT_COMPAT\"]
|
13
56
|
|
14
57
|
* 1 bug fix:
|
15
58
|
|
@@ -20,7 +63,7 @@
|
|
20
63
|
* 3 bug fixes:
|
21
64
|
|
22
65
|
* Avoid extra string allocations when filtering tests. (tenderlove)
|
23
|
-
* Only mention deprecated ENV['N'] if it is an integer string.
|
66
|
+
* Only mention deprecated \ENV[\'N\'] if it is an integer string.
|
24
67
|
* Push up test_order to Minitest::Runnable to fix minitest/hell. (koic)
|
25
68
|
|
26
69
|
=== 5.18.0 / 2023-03-04
|
@@ -214,7 +257,7 @@
|
|
214
257
|
|
215
258
|
* 3 bug fixes:
|
216
259
|
|
217
|
-
* Check
|
260
|
+
* Check \option[:filter] klass before match. Fixes 2.6 warning. (y-yagi)
|
218
261
|
* Fixed Assertions#diff from recalculating if set to nil
|
219
262
|
* Fixed spec section of readme to not use deprecated global expectations. (CheezItMan)
|
220
263
|
|
data/Manifest.txt
CHANGED
data/README.rdoc
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
home :: https://github.com/minitest/minitest
|
4
4
|
bugs :: https://github.com/minitest/minitest/issues
|
5
5
|
rdoc :: https://docs.seattlerb.org/minitest
|
6
|
+
clog :: https://github.com/minitest/minitest/blob/master/History.rdoc
|
6
7
|
vim :: https://github.com/sunaku/vim-ruby-minitest
|
7
8
|
emacs:: https://github.com/arthurnn/minitest-emacs
|
8
9
|
|
data/lib/minitest/assertions.rb
CHANGED
@@ -198,6 +198,11 @@ module Minitest
|
|
198
198
|
assert obj.empty?, msg
|
199
199
|
end
|
200
200
|
|
201
|
+
def _where # :nodoc:
|
202
|
+
where = Minitest.filter_backtrace(caller).first
|
203
|
+
where = where.split(/:in /, 2).first # clean up noise
|
204
|
+
end
|
205
|
+
|
201
206
|
E = "" # :nodoc:
|
202
207
|
|
203
208
|
##
|
@@ -221,10 +226,7 @@ module Minitest
|
|
221
226
|
if Minitest::VERSION =~ /^6/ then
|
222
227
|
refute_nil exp, "Use assert_nil if expecting nil."
|
223
228
|
else
|
224
|
-
|
225
|
-
where = where.split(/:in /, 2).first # clean up noise
|
226
|
-
|
227
|
-
warn "DEPRECATED: Use assert_nil if expecting nil from #{where}. This will fail in Minitest 6."
|
229
|
+
warn "DEPRECATED: Use assert_nil if expecting nil from #{_where}. This will fail in Minitest 6."
|
228
230
|
end
|
229
231
|
end
|
230
232
|
|
@@ -449,12 +451,13 @@ module Minitest
|
|
449
451
|
|
450
452
|
##
|
451
453
|
# Fails unless +obj+ responds to +meth+.
|
454
|
+
# include_all defaults to false to match Object#respond_to?
|
452
455
|
|
453
|
-
def assert_respond_to obj, meth, msg = nil
|
456
|
+
def assert_respond_to obj, meth, msg = nil, include_all: false
|
454
457
|
msg = message(msg) {
|
455
458
|
"Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}"
|
456
459
|
}
|
457
|
-
assert obj.respond_to?(meth), msg
|
460
|
+
assert obj.respond_to?(meth, include_all), msg
|
458
461
|
end
|
459
462
|
|
460
463
|
##
|
@@ -474,9 +477,7 @@ module Minitest
|
|
474
477
|
# Fails unless the call returns a true value
|
475
478
|
|
476
479
|
def assert_send send_ary, m = nil
|
477
|
-
|
478
|
-
where = where.split(/:in /, 2).first # clean up noise
|
479
|
-
warn "DEPRECATED: assert_send. From #{where}"
|
480
|
+
warn "DEPRECATED: assert_send. From #{_where}"
|
480
481
|
|
481
482
|
recv, msg, *args = send_ary
|
482
483
|
m = message(m) {
|
@@ -807,11 +808,12 @@ module Minitest
|
|
807
808
|
|
808
809
|
##
|
809
810
|
# Fails if +obj+ responds to the message +meth+.
|
811
|
+
# include_all defaults to false to match Object#respond_to?
|
810
812
|
|
811
|
-
def refute_respond_to obj, meth, msg = nil
|
813
|
+
def refute_respond_to obj, meth, msg = nil, include_all: false
|
812
814
|
msg = message(msg) { "Expected #{mu_pp(obj)} to not respond to #{meth}" }
|
813
815
|
|
814
|
-
refute obj.respond_to?(meth), msg
|
816
|
+
refute obj.respond_to?(meth, include_all), msg
|
815
817
|
end
|
816
818
|
|
817
819
|
##
|
@@ -830,10 +832,10 @@ module Minitest
|
|
830
832
|
# gets listed at the end of the run but doesn't cause a failure
|
831
833
|
# exit code.
|
832
834
|
|
833
|
-
def skip msg = nil,
|
835
|
+
def skip msg = nil, _ignored = nil
|
834
836
|
msg ||= "Skipped, no message given"
|
835
837
|
@skip = true
|
836
|
-
raise Minitest::Skip, msg
|
838
|
+
raise Minitest::Skip, msg
|
837
839
|
end
|
838
840
|
|
839
841
|
##
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Minitest
|
2
|
+
##
|
3
|
+
# Compresses backtraces.
|
4
|
+
|
5
|
+
module Compress
|
6
|
+
|
7
|
+
##
|
8
|
+
# Takes a backtrace (array of strings) and compresses repeating
|
9
|
+
# cycles in it to make it more readable.
|
10
|
+
|
11
|
+
def compress orig
|
12
|
+
ary = orig
|
13
|
+
|
14
|
+
eswo = ->(ary, n, off) { # each_slice_with_offset
|
15
|
+
if off.zero? then
|
16
|
+
ary.each_slice n
|
17
|
+
else
|
18
|
+
# [ ...off... [...n...] [...n...] ... ]
|
19
|
+
front, back = ary.take(off), ary.drop(off)
|
20
|
+
[front].chain back.each_slice n
|
21
|
+
end
|
22
|
+
}
|
23
|
+
|
24
|
+
3.times do # maybe don't use loop do here?
|
25
|
+
index = ary # [ a b c b c b c d ]
|
26
|
+
.size
|
27
|
+
.times # 0...size
|
28
|
+
.group_by { |i| ary[i] } # { a: [0] b: [1 3 5], c: [2 4 6], d: [7] }
|
29
|
+
|
30
|
+
order = index
|
31
|
+
.reject { |k, v| v.size == 1 } # { b: [1 3 5], c: [2 4 6] }
|
32
|
+
.sort_by { |k, ary| ### sort by max dist + min offset
|
33
|
+
d = ary.each_cons(2).sum { |a, b| b-a }
|
34
|
+
[-d, ary.first]
|
35
|
+
} # b: [1 3 5] c: [2 4 6]
|
36
|
+
|
37
|
+
ranges = order
|
38
|
+
.map { |k, ary| # [[1..2 3..4] [2..3 4..5]]
|
39
|
+
ary
|
40
|
+
.each_cons(2)
|
41
|
+
.map { |a, b| a..b-1 }
|
42
|
+
}
|
43
|
+
|
44
|
+
big_ranges = ranges
|
45
|
+
.flat_map { |a| # [1..2 3..4 2..3 4..5]
|
46
|
+
a.sort_by { |r| [-r.size, r.first] }.first 5
|
47
|
+
}
|
48
|
+
.first(100)
|
49
|
+
|
50
|
+
culprits = big_ranges
|
51
|
+
.map { |r|
|
52
|
+
eswo[ary, r.size, r.begin] # [o1 s1 s1 s2 s2]
|
53
|
+
.chunk_while { |a,b| a == b } # [[o1] [s1 s1] [s2 s2]]
|
54
|
+
.map { |a| [a.size, a.first] } # [[1 o1] [2 s1] [2 s2]]
|
55
|
+
}
|
56
|
+
.select { |chunks|
|
57
|
+
chunks.any? { |a| a.first > 1 } # compressed anything?
|
58
|
+
}
|
59
|
+
|
60
|
+
min = culprits
|
61
|
+
.min_by { |a| a.flatten.size } # most compressed
|
62
|
+
|
63
|
+
break unless min
|
64
|
+
|
65
|
+
ary = min.flat_map { |(n, lines)|
|
66
|
+
if n > 1 then
|
67
|
+
[[n, compress(lines)]] # [o1 [2 s1] [2 s2]]
|
68
|
+
else
|
69
|
+
lines
|
70
|
+
end
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
format = ->(lines) {
|
75
|
+
lines.flat_map { |line|
|
76
|
+
case line
|
77
|
+
when Array then
|
78
|
+
n, lines = line
|
79
|
+
lines = format[lines]
|
80
|
+
[
|
81
|
+
" +->> #{n} cycles of #{lines.size} lines:",
|
82
|
+
*lines.map { |s| " | #{s}" },
|
83
|
+
" +-<<",
|
84
|
+
]
|
85
|
+
else
|
86
|
+
line
|
87
|
+
end
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
format[ary]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/minitest/mock.rb
CHANGED
@@ -10,7 +10,7 @@ module Minitest # :nodoc:
|
|
10
10
|
class Mock
|
11
11
|
alias :__respond_to? :respond_to?
|
12
12
|
|
13
|
-
overridden_methods = %
|
13
|
+
overridden_methods = %i[
|
14
14
|
===
|
15
15
|
class
|
16
16
|
inspect
|
@@ -23,8 +23,10 @@ module Minitest # :nodoc:
|
|
23
23
|
to_s
|
24
24
|
]
|
25
25
|
|
26
|
+
overridden_methods << :singleton_method_added if defined?(::DEBUGGER__)
|
27
|
+
|
26
28
|
instance_methods.each do |m|
|
27
|
-
undef_method m unless overridden_methods.include?(m
|
29
|
+
undef_method m unless overridden_methods.include?(m) || m =~ /^__/
|
28
30
|
end
|
29
31
|
|
30
32
|
overridden_methods.map(&:to_sym).each do |method_id|
|
data/lib/minitest/test_task.rb
CHANGED
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.22.0" # :nodoc:
|
13
13
|
|
14
14
|
@@installed_at_exit ||= false
|
15
15
|
@@after_run = []
|
@@ -134,7 +134,7 @@ module Minitest
|
|
134
134
|
# Minitest.run(args)
|
135
135
|
# Minitest.__run(reporter, options)
|
136
136
|
# Runnable.runnables.each
|
137
|
-
#
|
137
|
+
# runnable_klass.run(reporter, options)
|
138
138
|
# self.runnable_methods.each
|
139
139
|
# self.run_one_method(self, runnable_method, reporter)
|
140
140
|
# Minitest.run_one_method(klass, runnable_method)
|
@@ -150,7 +150,7 @@ module Minitest
|
|
150
150
|
|
151
151
|
reporter = CompositeReporter.new
|
152
152
|
reporter << SummaryReporter.new(options[:io], options)
|
153
|
-
reporter << ProgressReporter.new(options[:io], options)
|
153
|
+
reporter << ProgressReporter.new(options[:io], options) unless options[:quiet]
|
154
154
|
|
155
155
|
self.reporter = reporter # this makes it available to plugins
|
156
156
|
self.init_plugins options
|
@@ -164,11 +164,33 @@ module Minitest
|
|
164
164
|
warn "Interrupted. Exiting..."
|
165
165
|
end
|
166
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
|
+
|
167
172
|
reporter.report
|
168
173
|
|
169
174
|
reporter.passed?
|
170
175
|
end
|
171
176
|
|
177
|
+
def self.empty_run! options # :nodoc:
|
178
|
+
filter = options[:filter]
|
179
|
+
|
180
|
+
warn "Nothing ran for filter: %s" % [filter]
|
181
|
+
|
182
|
+
require "did_you_mean" # soft dependency, punt if it doesn't load
|
183
|
+
|
184
|
+
ms = Runnable.runnables.flat_map(&:runnable_methods)
|
185
|
+
cs = DidYouMean::SpellChecker.new(dictionary: ms).correct filter
|
186
|
+
|
187
|
+
warn DidYouMean::Formatter.message_for cs unless cs.empty?
|
188
|
+
rescue LoadError
|
189
|
+
# do nothing
|
190
|
+
ensure
|
191
|
+
false
|
192
|
+
end
|
193
|
+
|
172
194
|
##
|
173
195
|
# Internal run method. Responsible for telling all Runnable
|
174
196
|
# sub-classes to run.
|
@@ -212,6 +234,10 @@ module Minitest
|
|
212
234
|
options[:verbose] = true
|
213
235
|
end
|
214
236
|
|
237
|
+
opts.on "-q", "--quiet", "Quiet. Show no progress processing files." do
|
238
|
+
options[:quiet] = true
|
239
|
+
end
|
240
|
+
|
215
241
|
opts.on "--show-skips", "Show skipped at the end of run." do
|
216
242
|
options[:show_skips] = true
|
217
243
|
end
|
@@ -334,25 +360,15 @@ module Minitest
|
|
334
360
|
# reporter to record.
|
335
361
|
|
336
362
|
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
|
363
|
+
pos = options[:filter]
|
364
|
+
neg = options[:exclude]
|
347
365
|
|
348
|
-
if
|
349
|
-
|
350
|
-
exclude = Regexp.new $1 if exclude =~ %r%/(.*)/%
|
366
|
+
pos = Regexp.new $1 if pos.is_a?(String) && pos =~ %r%/(.*)/%
|
367
|
+
neg = Regexp.new $1 if neg.is_a?(String) && neg =~ %r%/(.*)/%
|
351
368
|
|
352
|
-
|
353
|
-
|
354
|
-
}
|
355
|
-
end
|
369
|
+
filtered_methods = self.runnable_methods
|
370
|
+
.select { |m| !pos || pos === m || pos === "#{self}##{m}" }
|
371
|
+
.reject { |m| neg && (neg === m || neg === "#{self}##{m}") }
|
356
372
|
|
357
373
|
return if filtered_methods.empty?
|
358
374
|
|
@@ -525,12 +541,14 @@ module Minitest
|
|
525
541
|
not self.failure
|
526
542
|
end
|
527
543
|
|
544
|
+
BASE_DIR = "#{Dir.pwd}/" # :nodoc:
|
545
|
+
|
528
546
|
##
|
529
547
|
# The location identifier of this test. Depends on a method
|
530
548
|
# existing called class_name.
|
531
549
|
|
532
550
|
def location
|
533
|
-
loc = " [#{self.failure.location}]" unless passed? or error?
|
551
|
+
loc = " [#{self.failure.location.delete_prefix BASE_DIR}]" unless passed? or error?
|
534
552
|
"#{self.class_name}##{self.name}#{loc}"
|
535
553
|
end
|
536
554
|
|
@@ -619,7 +637,10 @@ module Minitest
|
|
619
637
|
# you want. Go nuts.
|
620
638
|
|
621
639
|
class AbstractReporter
|
622
|
-
|
640
|
+
|
641
|
+
def initialize # :nodoc:
|
642
|
+
@mutex = Mutex.new
|
643
|
+
end
|
623
644
|
|
624
645
|
##
|
625
646
|
# Starts reporting on the run.
|
@@ -655,6 +676,10 @@ module Minitest
|
|
655
676
|
def passed?
|
656
677
|
true
|
657
678
|
end
|
679
|
+
|
680
|
+
def synchronize(&block) # :nodoc:
|
681
|
+
@mutex.synchronize(&block)
|
682
|
+
end
|
658
683
|
end
|
659
684
|
|
660
685
|
class Reporter < AbstractReporter # :nodoc:
|
@@ -828,7 +853,7 @@ module Minitest
|
|
828
853
|
io.puts "# Running:"
|
829
854
|
io.puts
|
830
855
|
|
831
|
-
self.sync = io.respond_to? :"sync="
|
856
|
+
self.sync = io.respond_to? :"sync="
|
832
857
|
self.old_sync, io.sync = io.sync, true if self.sync
|
833
858
|
end
|
834
859
|
|
@@ -936,6 +961,8 @@ module Minitest
|
|
936
961
|
# Represents run failures.
|
937
962
|
|
938
963
|
class Assertion < Exception
|
964
|
+
RE = /in .(?:assert|refute|flunk|pass|fail|raise|must|wont)/ # :nodoc:
|
965
|
+
|
939
966
|
def error # :nodoc:
|
940
967
|
self
|
941
968
|
end
|
@@ -944,12 +971,11 @@ module Minitest
|
|
944
971
|
# Where was this run before an assertion was raised?
|
945
972
|
|
946
973
|
def location
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
last_before_assertion.sub(/:in .*$/, "")
|
974
|
+
bt = Minitest.filter_backtrace self.backtrace
|
975
|
+
idx = bt.rindex { |s| s.match? RE } || -1 # fall back to first item
|
976
|
+
loc = bt[idx+1] || bt.last || "unknown:-1"
|
977
|
+
|
978
|
+
loc.sub(/:in .*$/, "")
|
953
979
|
end
|
954
980
|
|
955
981
|
def result_code # :nodoc:
|
@@ -974,11 +1000,21 @@ module Minitest
|
|
974
1000
|
# Assertion wrapping an unexpected error that was raised during a run.
|
975
1001
|
|
976
1002
|
class UnexpectedError < Assertion
|
1003
|
+
include Minitest::Compress
|
1004
|
+
|
977
1005
|
# TODO: figure out how to use `cause` instead
|
978
1006
|
attr_accessor :error # :nodoc:
|
979
1007
|
|
980
1008
|
def initialize error # :nodoc:
|
981
1009
|
super "Unexpected exception"
|
1010
|
+
|
1011
|
+
if SystemStackError === error then
|
1012
|
+
bt = error.backtrace
|
1013
|
+
new_bt = compress bt
|
1014
|
+
error = error.exception "#{bt.size} -> #{new_bt.size}"
|
1015
|
+
error.set_backtrace new_bt
|
1016
|
+
end
|
1017
|
+
|
982
1018
|
self.error = error
|
983
1019
|
end
|
984
1020
|
|
@@ -986,8 +1022,11 @@ module Minitest
|
|
986
1022
|
self.error.backtrace
|
987
1023
|
end
|
988
1024
|
|
1025
|
+
BASE_RE = %r%#{Dir.pwd}/% # :nodoc:
|
1026
|
+
|
989
1027
|
def message # :nodoc:
|
990
|
-
bt = Minitest.filter_backtrace(self.backtrace).join
|
1028
|
+
bt = Minitest.filter_backtrace(self.backtrace).join("\n ")
|
1029
|
+
.gsub(BASE_RE, "")
|
991
1030
|
"#{self.error.class}: #{self.error.message}\n #{bt}"
|
992
1031
|
end
|
993
1032
|
|
@@ -1071,6 +1110,12 @@ module Minitest
|
|
1071
1110
|
|
1072
1111
|
MT_RE = %r%lib/minitest% #:nodoc:
|
1073
1112
|
|
1113
|
+
attr_accessor :regexp
|
1114
|
+
|
1115
|
+
def initialize regexp = MT_RE
|
1116
|
+
self.regexp = regexp
|
1117
|
+
end
|
1118
|
+
|
1074
1119
|
##
|
1075
1120
|
# Filter +bt+ to something useful. Returns the whole thing if
|
1076
1121
|
# $DEBUG (ruby) or $MT_DEBUG (env).
|
@@ -1080,9 +1125,9 @@ module Minitest
|
|
1080
1125
|
|
1081
1126
|
return bt.dup if $DEBUG || ENV["MT_DEBUG"]
|
1082
1127
|
|
1083
|
-
new_bt = bt.take_while { |line| line !~
|
1084
|
-
new_bt = bt.select { |line| line !~
|
1085
|
-
new_bt = bt.dup
|
1128
|
+
new_bt = bt.take_while { |line| line.to_s !~ regexp }
|
1129
|
+
new_bt = bt.select { |line| line.to_s !~ regexp } if new_bt.empty?
|
1130
|
+
new_bt = bt.dup if new_bt.empty?
|
1086
1131
|
|
1087
1132
|
new_bt
|
1088
1133
|
end
|
@@ -8,16 +8,17 @@ 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
|
@@ -105,15 +106,17 @@ class MetaMetaMetaTestCase < Minitest::Test
|
|
105
106
|
output.gsub!(/0x[A-Fa-f0-9]+/, "0xXXX")
|
106
107
|
output.gsub!(/ +$/, "")
|
107
108
|
|
109
|
+
file = ->(s) { s.start_with?("/") ? "FULLFILE" : "FILE" }
|
110
|
+
|
108
111
|
if windows? then
|
109
112
|
output.gsub!(/\[(?:[A-Za-z]:)?[^\]:]+:\d+\]/, "[FILE:LINE]")
|
110
113
|
output.gsub!(/^(\s+)(?:[A-Za-z]:)?[^:]+:\d+:in/, '\1FILE:LINE:in')
|
111
114
|
else
|
112
|
-
output.gsub!(/\[[^\]:]
|
113
|
-
output.gsub!(/^(\s+)[^:]
|
115
|
+
output.gsub!(/\[([^\]:]+):\d+\]/) { "[#{file[$1]}:LINE]" }
|
116
|
+
output.gsub!(/^(\s+)([^:]+):\d+:in/) { "#{$1}#{file[$2]}:LINE:in" }
|
114
117
|
end
|
115
118
|
|
116
|
-
output.gsub!(/( at )[^:]+:\d
|
119
|
+
output.gsub!(/( at )[^:]+:\d+/) { "#{$1}[#{file[$2]}:LINE]" } # eval?
|
117
120
|
|
118
121
|
output
|
119
122
|
end
|
@@ -936,6 +936,16 @@ class TestMinitestAssertions < Minitest::Test
|
|
936
936
|
end
|
937
937
|
end
|
938
938
|
|
939
|
+
def test_assert_respond_to__include_all
|
940
|
+
@tc.assert_respond_to @tc, :exit, include_all: true
|
941
|
+
end
|
942
|
+
|
943
|
+
def test_assert_respond_to__include_all_triggered
|
944
|
+
assert_triggered(/Expected .+::DummyTest. to respond to #exit\?/) do
|
945
|
+
@tc.assert_respond_to @tc, :exit?, include_all: true
|
946
|
+
end
|
947
|
+
end
|
948
|
+
|
939
949
|
def test_assert_same
|
940
950
|
@assertion_count = 3
|
941
951
|
|
@@ -1153,18 +1163,14 @@ class TestMinitestAssertions < Minitest::Test
|
|
1153
1163
|
def test_class_asserts_match_refutes
|
1154
1164
|
@assertion_count = 0
|
1155
1165
|
|
1156
|
-
methods = Minitest::Assertions.public_instance_methods
|
1157
|
-
methods.map!(&:to_s) if Symbol === methods.first
|
1166
|
+
methods = Minitest::Assertions.public_instance_methods.map(&:to_s)
|
1158
1167
|
|
1159
1168
|
# These don't have corresponding refutes _on purpose_. They're
|
1160
1169
|
# useless and will never be added, so don't bother.
|
1161
1170
|
ignores = %w[assert_output assert_raises assert_send
|
1162
1171
|
assert_silent assert_throws assert_mock]
|
1163
1172
|
|
1164
|
-
|
1165
|
-
ignores += %w[assert_no_match assert_not_equal assert_not_nil
|
1166
|
-
assert_not_same assert_nothing_raised
|
1167
|
-
assert_nothing_thrown assert_raise]
|
1173
|
+
ignores += %w[assert_allocations] # for minitest-gcstats
|
1168
1174
|
|
1169
1175
|
asserts = methods.grep(/^assert/).sort - ignores
|
1170
1176
|
refutes = methods.grep(/^refute/).sort - ignores
|
@@ -1444,6 +1450,16 @@ class TestMinitestAssertions < Minitest::Test
|
|
1444
1450
|
end
|
1445
1451
|
end
|
1446
1452
|
|
1453
|
+
def test_refute_respond_to__include_all
|
1454
|
+
@tc.refute_respond_to "blah", :missing, include_all: true
|
1455
|
+
end
|
1456
|
+
|
1457
|
+
def test_refute_respond_to__include_all_triggered
|
1458
|
+
assert_triggered(/Expected .*DummyTest.* to not respond to exit./) do
|
1459
|
+
@tc.refute_respond_to @tc, :exit, include_all: true
|
1460
|
+
end
|
1461
|
+
end
|
1462
|
+
|
1447
1463
|
def test_refute_same
|
1448
1464
|
@tc.refute_same 1, 2
|
1449
1465
|
end
|
@@ -48,6 +48,25 @@ class TestMinitestReporter < MetaMetaMetaTestCase
|
|
48
48
|
@et
|
49
49
|
end
|
50
50
|
|
51
|
+
def system_stack_error_test
|
52
|
+
unless defined? @sse then
|
53
|
+
|
54
|
+
ex = SystemStackError.new
|
55
|
+
|
56
|
+
pre = ("a".."c").to_a
|
57
|
+
mid = ("aa".."ad").to_a * 67
|
58
|
+
post = ("d".."f").to_a
|
59
|
+
ary = pre + mid + post
|
60
|
+
|
61
|
+
ex.set_backtrace ary
|
62
|
+
|
63
|
+
@sse = Minitest::Test.new(:woot)
|
64
|
+
@sse.failures << Minitest::UnexpectedError.new(ex)
|
65
|
+
@sse = Minitest::Result.from @sse
|
66
|
+
end
|
67
|
+
@sse
|
68
|
+
end
|
69
|
+
|
51
70
|
def fail_test
|
52
71
|
unless defined? @ft then
|
53
72
|
@ft = Minitest::Test.new(:woot)
|
@@ -314,6 +333,42 @@ class TestMinitestReporter < MetaMetaMetaTestCase
|
|
314
333
|
assert_equal exp, normalize_output(io.string)
|
315
334
|
end
|
316
335
|
|
336
|
+
def test_report_error__sse
|
337
|
+
r.start
|
338
|
+
r.record system_stack_error_test
|
339
|
+
r.report
|
340
|
+
|
341
|
+
exp = clean <<-EOM
|
342
|
+
Run options:
|
343
|
+
|
344
|
+
# Running:
|
345
|
+
|
346
|
+
E
|
347
|
+
|
348
|
+
Finished in 0.00
|
349
|
+
|
350
|
+
1) Error:
|
351
|
+
Minitest::Test#woot:
|
352
|
+
SystemStackError: 274 -> 12
|
353
|
+
a
|
354
|
+
b
|
355
|
+
c
|
356
|
+
+->> 67 cycles of 4 lines:
|
357
|
+
| aa
|
358
|
+
| ab
|
359
|
+
| ac
|
360
|
+
| ad
|
361
|
+
+-<<
|
362
|
+
d
|
363
|
+
e
|
364
|
+
f
|
365
|
+
|
366
|
+
1 runs, 0 assertions, 0 failures, 1 errors, 0 skips
|
367
|
+
EOM
|
368
|
+
|
369
|
+
assert_equal exp, normalize_output(io.string)
|
370
|
+
end
|
371
|
+
|
317
372
|
def test_report_skipped
|
318
373
|
r.start
|
319
374
|
r.record skip_test
|
@@ -338,4 +393,48 @@ class TestMinitestReporter < MetaMetaMetaTestCase
|
|
338
393
|
|
339
394
|
assert_equal exp, normalize_output(io.string)
|
340
395
|
end
|
396
|
+
|
397
|
+
def test_report_failure_uses_backtrace_filter
|
398
|
+
filter = Minitest::BacktraceFilter.new
|
399
|
+
def filter.filter _bt
|
400
|
+
["foo.rb:123:in `foo'"]
|
401
|
+
end
|
402
|
+
|
403
|
+
with_backtrace_filter filter do
|
404
|
+
r.start
|
405
|
+
r.record fail_test
|
406
|
+
r.report
|
407
|
+
end
|
408
|
+
|
409
|
+
exp = "Minitest::Test#woot [foo.rb:123]"
|
410
|
+
|
411
|
+
assert_includes io.string, exp
|
412
|
+
end
|
413
|
+
|
414
|
+
def test_report_failure_uses_backtrace_filter_complex_sorbet
|
415
|
+
backtrace = <<~EOBT
|
416
|
+
/Users/user/.gem/ruby/3.2.2/gems/minitest-5.20.0/lib/minitest/assertions.rb:183:in `assert'
|
417
|
+
example_test.rb:9:in `assert_false'
|
418
|
+
/Users/user/.gem/ruby/3.2.2/gems/sorbet-runtime-0.5.11068/lib/types/private/methods/call_validation.rb:256:in `bind_call'
|
419
|
+
/Users/user/.gem/ruby/3.2.2/gems/sorbet-runtime-0.5.11068/lib/types/private/methods/call_validation.rb:256:in `validate_call'
|
420
|
+
/Users/user/.gem/ruby/3.2.2/gems/sorbet-runtime-0.5.11068/lib/types/private/methods/_methods.rb:275:in `block in _on_method_added'
|
421
|
+
example_test.rb:25:in `test_something'
|
422
|
+
/Users/user/.gem/ruby/3.2.2/gems/minitest-5.20.0/lib/minitest/test.rb:94:in `block (3 levels) in run'
|
423
|
+
/Users/user/.gem/ruby/3.2.2/gems/minitest-5.20.0/lib/minitest/test.rb:191:in `capture_exceptions'
|
424
|
+
/Users/user/.gem/ruby/3.2.2/gems/minitest-5.20.0/lib/minitest/test.rb:89:in `block (2 levels) in run'
|
425
|
+
... so many lines ...
|
426
|
+
EOBT
|
427
|
+
|
428
|
+
filter = Minitest::BacktraceFilter.new %r%lib/minitest|gems/sorbet%
|
429
|
+
|
430
|
+
with_backtrace_filter filter do
|
431
|
+
begin
|
432
|
+
assert_equal 1, 2
|
433
|
+
rescue Minitest::Assertion => e
|
434
|
+
e.set_backtrace backtrace.lines.map(&:chomp)
|
435
|
+
|
436
|
+
assert_match "example_test.rb:25", e.location
|
437
|
+
end
|
438
|
+
end
|
439
|
+
end
|
341
440
|
end
|
@@ -1280,3 +1280,96 @@ class TestMinitestUnitRecording < MetaMetaMetaTestCase
|
|
1280
1280
|
end
|
1281
1281
|
end
|
1282
1282
|
end
|
1283
|
+
|
1284
|
+
class TestUnexpectedError < Minitest::Test
|
1285
|
+
def assert_compress exp, input
|
1286
|
+
e = Minitest::UnexpectedError.new RuntimeError.new
|
1287
|
+
|
1288
|
+
exp = exp.lines.map(&:chomp) if String === exp
|
1289
|
+
act = e.compress input
|
1290
|
+
|
1291
|
+
assert_equal exp, act
|
1292
|
+
end
|
1293
|
+
|
1294
|
+
ACT1 = %w[ a b c b c b c b c d ]
|
1295
|
+
|
1296
|
+
def test_normal
|
1297
|
+
assert_compress <<~EXP, %w[ a b c b c b c b c d ]
|
1298
|
+
a
|
1299
|
+
+->> 4 cycles of 2 lines:
|
1300
|
+
| b
|
1301
|
+
| c
|
1302
|
+
+-<<
|
1303
|
+
d
|
1304
|
+
EXP
|
1305
|
+
end
|
1306
|
+
|
1307
|
+
def test_normal2
|
1308
|
+
assert_compress <<~EXP, %w[ a b c b c b c b c ]
|
1309
|
+
a
|
1310
|
+
+->> 4 cycles of 2 lines:
|
1311
|
+
| b
|
1312
|
+
| c
|
1313
|
+
+-<<
|
1314
|
+
EXP
|
1315
|
+
end
|
1316
|
+
|
1317
|
+
def test_longer_c_than_b
|
1318
|
+
# the extra c in the front makes the overall length longer sorting it first
|
1319
|
+
assert_compress <<~EXP, %w[ c a b c b c b c b c b d ]
|
1320
|
+
c
|
1321
|
+
a
|
1322
|
+
b
|
1323
|
+
+->> 4 cycles of 2 lines:
|
1324
|
+
| c
|
1325
|
+
| b
|
1326
|
+
+-<<
|
1327
|
+
d
|
1328
|
+
EXP
|
1329
|
+
end
|
1330
|
+
|
1331
|
+
def test_1_line_cycles
|
1332
|
+
assert_compress <<~EXP, %w[ c a b c b c b c b c b b b d ]
|
1333
|
+
c
|
1334
|
+
a
|
1335
|
+
+->> 4 cycles of 2 lines:
|
1336
|
+
| b
|
1337
|
+
| c
|
1338
|
+
+-<<
|
1339
|
+
+->> 3 cycles of 1 lines:
|
1340
|
+
| b
|
1341
|
+
+-<<
|
1342
|
+
d
|
1343
|
+
EXP
|
1344
|
+
end
|
1345
|
+
|
1346
|
+
def test_sanity3
|
1347
|
+
pre = ("aa".."am").to_a
|
1348
|
+
mid = ("a".."z").to_a * 67
|
1349
|
+
post = ("aa".."am").to_a
|
1350
|
+
ary = pre + mid + post
|
1351
|
+
|
1352
|
+
exp = pre +
|
1353
|
+
[" +->> 67 cycles of 26 lines:"] +
|
1354
|
+
("a".."z").map { |s| " | #{s}" } +
|
1355
|
+
[" +-<<"] +
|
1356
|
+
post
|
1357
|
+
|
1358
|
+
assert_compress exp, ary
|
1359
|
+
end
|
1360
|
+
|
1361
|
+
def test_absurd_patterns
|
1362
|
+
assert_compress <<~EXP, %w[ a b c b c a b c b c a b c ]
|
1363
|
+
+->> 2 cycles of 5 lines:
|
1364
|
+
| a
|
1365
|
+
| +->> 2 cycles of 2 lines:
|
1366
|
+
| | b
|
1367
|
+
| | c
|
1368
|
+
| +-<<
|
1369
|
+
+-<<
|
1370
|
+
a
|
1371
|
+
b
|
1372
|
+
c
|
1373
|
+
EXP
|
1374
|
+
end
|
1375
|
+
end
|
data.tar.gz.sig
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
gD6P���T!=�q/{�_]r�����2Z¬��ݒـY'8�����Ѵ�D���)��X\��]nZ�x2O��U���et��Z��R
|
2
|
+
|
3
|
+
�s�v0j
|
4
|
+
`�c��#!���%O�D<قF�g�g�
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minitest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.22.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Davis
|
@@ -10,9 +10,9 @@ bindir: bin
|
|
10
10
|
cert_chain:
|
11
11
|
- |
|
12
12
|
-----BEGIN CERTIFICATE-----
|
13
|
-
|
13
|
+
MIIDPjCCAiagAwIBAgIBCDANBgkqhkiG9w0BAQsFADBFMRMwEQYDVQQDDApyeWFu
|
14
14
|
ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB
|
15
|
-
|
15
|
+
GRYDY29tMB4XDTI0MDEwMjIxMjEyM1oXDTI1MDEwMTIxMjEyM1owRTETMBEGA1UE
|
16
16
|
AwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS
|
17
17
|
JomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda
|
18
18
|
b9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx
|
@@ -22,14 +22,14 @@ cert_chain:
|
|
22
22
|
qhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV
|
23
23
|
gBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw
|
24
24
|
HQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBCwUAA4IB
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
AQCygvpmncmkiSs9r/Kceo4bBPDszhTv6iBi4LwMReqnFrpNLMOWJw7xi8x+3eL2
|
26
|
+
XS09ZPNOt2zm70KmFouBMgOysnDY4k2dE8uF6B8JbZOO8QfalW+CoNBliefOTcn2
|
27
|
+
bg5IOP7UoGM5lC174/cbDJrJnRG9bzig5FAP0mvsgA8zgTRXQzIUAZEo92D5K7p4
|
28
|
+
B4/O998ho6BSOgYBI9Yk1ttdCtti6Y+8N9+fZESsjtWMykA+WXWeGUScHqiU+gH8
|
29
|
+
S7043fq9EbQdBr2AXdj92+CDwuTfHI6/Hj5FVBDULufrJaan4xUgL70Hvc6pTTeW
|
30
|
+
deKfBjgVAq7EYHu1AczzlUly
|
31
31
|
-----END CERTIFICATE-----
|
32
|
-
date:
|
32
|
+
date: 2024-02-05 00:00:00.000000000 Z
|
33
33
|
dependencies:
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: rdoc
|
@@ -57,14 +57,14 @@ dependencies:
|
|
57
57
|
requirements:
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '4.
|
60
|
+
version: '4.2'
|
61
61
|
type: :development
|
62
62
|
prerelease: false
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
65
|
- - "~>"
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: '4.
|
67
|
+
version: '4.2'
|
68
68
|
description: |-
|
69
69
|
minitest provides a complete suite of testing facilities supporting
|
70
70
|
TDD, BDD, mocking, and benchmarking.
|
@@ -139,6 +139,7 @@ files:
|
|
139
139
|
- lib/minitest/assertions.rb
|
140
140
|
- lib/minitest/autorun.rb
|
141
141
|
- lib/minitest/benchmark.rb
|
142
|
+
- lib/minitest/compress.rb
|
142
143
|
- lib/minitest/expectations.rb
|
143
144
|
- lib/minitest/hell.rb
|
144
145
|
- lib/minitest/mock.rb
|
@@ -163,6 +164,7 @@ licenses:
|
|
163
164
|
metadata:
|
164
165
|
homepage_uri: https://github.com/minitest/minitest
|
165
166
|
bug_tracker_uri: https://github.com/minitest/minitest/issues
|
167
|
+
changelog_uri: https://github.com/minitest/minitest/blob/master/History.rdoc
|
166
168
|
post_install_message:
|
167
169
|
rdoc_options:
|
168
170
|
- "--main"
|
@@ -183,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
183
185
|
- !ruby/object:Gem::Version
|
184
186
|
version: '0'
|
185
187
|
requirements: []
|
186
|
-
rubygems_version: 3.
|
188
|
+
rubygems_version: 3.5.3
|
187
189
|
signing_key:
|
188
190
|
specification_version: 4
|
189
191
|
summary: minitest provides a complete suite of testing facilities supporting TDD,
|
metadata.gz.sig
CHANGED
Binary file
|