minitest 5.20.0 → 5.22.1
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 +53 -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 +82 -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 +0 -0
- 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: 4e826dd27ec8fd1c38cb81a0323e2f16463119c10a4f15838c32d539a8ff2940
|
4
|
+
data.tar.gz: f6d5799c7399ceafdd07825931b705d66503828c2269df50d60241a012495982
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4483bded8417061d3552c03c4a13422e280c7c71ecb3e37e346c29d0b910205794bb5e84ff5c3ccfb0daf27f399ac3cf669f1d508608338c1ac6029efe32549
|
7
|
+
data.tar.gz: 891b15d02dee4a0bf11d76963f887db4daca5840653aa7d89eaa47a6356fd14737bb25f613af5e7695c54ead3382c328837618b1ffd6fbee1fa4d7f4a7625c67
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/History.rdoc
CHANGED
@@ -1,3 +1,53 @@
|
|
1
|
+
=== 5.22.1 / 2024-02-06
|
2
|
+
|
3
|
+
* 1 bug fix:
|
4
|
+
|
5
|
+
* Don't exit non-zero if no tests ran and no filter (aka, the test file is empty).
|
6
|
+
(I'm starting to think the exit 1 thing for @tenderlove was a mistake...)
|
7
|
+
|
8
|
+
=== 5.22.0 / 2024-02-05
|
9
|
+
|
10
|
+
* 1 minor enhancement:
|
11
|
+
|
12
|
+
* Added "did you mean" output if your --name filter matches nothing. (tenderlove)
|
13
|
+
|
14
|
+
* 2 bug fixes:
|
15
|
+
|
16
|
+
* Big cleanup of test filtering. Much prettier / more functional.
|
17
|
+
* Fix situation where Assertion#location can't find the location. (pftg)
|
18
|
+
|
19
|
+
=== 5.21.2 / 2024-01-17
|
20
|
+
|
21
|
+
* 1 bug fix:
|
22
|
+
|
23
|
+
* Fixed bug in Minitest::Compress#compress formatting w/ nested patterns. Now recurses properly.
|
24
|
+
|
25
|
+
=== 5.21.1 / 2024-01-11
|
26
|
+
|
27
|
+
* 1 bug fix:
|
28
|
+
|
29
|
+
* Rails' default backtrace filter can't currently work with caller_locations, so reverting back to caller.
|
30
|
+
|
31
|
+
=== 5.21.0 / 2024-01-11
|
32
|
+
|
33
|
+
* 10 minor enhancements:
|
34
|
+
|
35
|
+
* Add include_all kw arg to assert_respond_to and refute_respond_to.
|
36
|
+
* Added --quiet flag to skip ProgressReporter (prints the dots). Minor speedup.
|
37
|
+
* Added Minitest::Compress#compress and added it to UnexpectedError.
|
38
|
+
* Added ability to initialize BacktraceFilter w/ custom regexp.
|
39
|
+
* Filter failure backtraces using backtrace_filter before calculating location. (thomasmarshall)
|
40
|
+
* Make BacktraceFilter#filter compatible with locations (still compares strings).
|
41
|
+
* Optimized Assertion#location ~30%.
|
42
|
+
* Output relative paths for all failures/errors/backtraces.
|
43
|
+
* Refactored location information in assertions, now using locations.
|
44
|
+
* Removed thread and mutex_m dependencies. (hsbt, eregon)
|
45
|
+
|
46
|
+
* 2 bug fixes:
|
47
|
+
|
48
|
+
* Drop undocumented bt arg in #skip. Dunno why that ever happened, prolly for testing?
|
49
|
+
* Fix mock to work with ruby debugger enabled. (keithlayne)
|
50
|
+
|
1
51
|
=== 5.20.0 / 2023-09-06
|
2
52
|
|
3
53
|
* 1 minor enhancement:
|
@@ -9,7 +59,7 @@
|
|
9
59
|
* 2 minor enhancements:
|
10
60
|
|
11
61
|
* Add metadata lazy accessor to Runnable / Result. (matteeyah)
|
12
|
-
* Only load minitest/unit (aka ancient MiniTest compatibility layer) if ENV["MT_COMPAT"]
|
62
|
+
* Only load minitest/unit (aka ancient MiniTest compatibility layer) if \ENV[\"MT_COMPAT\"]
|
13
63
|
|
14
64
|
* 1 bug fix:
|
15
65
|
|
@@ -20,7 +70,7 @@
|
|
20
70
|
* 3 bug fixes:
|
21
71
|
|
22
72
|
* Avoid extra string allocations when filtering tests. (tenderlove)
|
23
|
-
* Only mention deprecated ENV['N'] if it is an integer string.
|
73
|
+
* Only mention deprecated \ENV[\'N\'] if it is an integer string.
|
24
74
|
* Push up test_order to Minitest::Runnable to fix minitest/hell. (koic)
|
25
75
|
|
26
76
|
=== 5.18.0 / 2023-03-04
|
@@ -214,7 +264,7 @@
|
|
214
264
|
|
215
265
|
* 3 bug fixes:
|
216
266
|
|
217
|
-
* Check
|
267
|
+
* Check \option[:filter] klass before match. Fixes 2.6 warning. (y-yagi)
|
218
268
|
* Fixed Assertions#diff from recalculating if set to nil
|
219
269
|
* Fixed spec section of readme to not use deprecated global expectations. (CheezItMan)
|
220
270
|
|
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.1" # :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,34 @@ 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
|
+
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
|
+
ensure
|
192
|
+
return false
|
193
|
+
end
|
194
|
+
|
172
195
|
##
|
173
196
|
# Internal run method. Responsible for telling all Runnable
|
174
197
|
# sub-classes to run.
|
@@ -212,6 +235,10 @@ module Minitest
|
|
212
235
|
options[:verbose] = true
|
213
236
|
end
|
214
237
|
|
238
|
+
opts.on "-q", "--quiet", "Quiet. Show no progress processing files." do
|
239
|
+
options[:quiet] = true
|
240
|
+
end
|
241
|
+
|
215
242
|
opts.on "--show-skips", "Show skipped at the end of run." do
|
216
243
|
options[:show_skips] = true
|
217
244
|
end
|
@@ -334,25 +361,15 @@ module Minitest
|
|
334
361
|
# reporter to record.
|
335
362
|
|
336
363
|
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
|
364
|
+
pos = options[:filter]
|
365
|
+
neg = options[:exclude]
|
347
366
|
|
348
|
-
if
|
349
|
-
|
350
|
-
exclude = Regexp.new $1 if exclude =~ %r%/(.*)/%
|
367
|
+
pos = Regexp.new $1 if pos.is_a?(String) && pos =~ %r%/(.*)/%
|
368
|
+
neg = Regexp.new $1 if neg.is_a?(String) && neg =~ %r%/(.*)/%
|
351
369
|
|
352
|
-
|
353
|
-
|
354
|
-
}
|
355
|
-
end
|
370
|
+
filtered_methods = self.runnable_methods
|
371
|
+
.select { |m| !pos || pos === m || pos === "#{self}##{m}" }
|
372
|
+
.reject { |m| neg && (neg === m || neg === "#{self}##{m}") }
|
356
373
|
|
357
374
|
return if filtered_methods.empty?
|
358
375
|
|
@@ -525,12 +542,14 @@ module Minitest
|
|
525
542
|
not self.failure
|
526
543
|
end
|
527
544
|
|
545
|
+
BASE_DIR = "#{Dir.pwd}/" # :nodoc:
|
546
|
+
|
528
547
|
##
|
529
548
|
# The location identifier of this test. Depends on a method
|
530
549
|
# existing called class_name.
|
531
550
|
|
532
551
|
def location
|
533
|
-
loc = " [#{self.failure.location}]" unless passed? or error?
|
552
|
+
loc = " [#{self.failure.location.delete_prefix BASE_DIR}]" unless passed? or error?
|
534
553
|
"#{self.class_name}##{self.name}#{loc}"
|
535
554
|
end
|
536
555
|
|
@@ -619,7 +638,10 @@ module Minitest
|
|
619
638
|
# you want. Go nuts.
|
620
639
|
|
621
640
|
class AbstractReporter
|
622
|
-
|
641
|
+
|
642
|
+
def initialize # :nodoc:
|
643
|
+
@mutex = Mutex.new
|
644
|
+
end
|
623
645
|
|
624
646
|
##
|
625
647
|
# Starts reporting on the run.
|
@@ -655,6 +677,10 @@ module Minitest
|
|
655
677
|
def passed?
|
656
678
|
true
|
657
679
|
end
|
680
|
+
|
681
|
+
def synchronize(&block) # :nodoc:
|
682
|
+
@mutex.synchronize(&block)
|
683
|
+
end
|
658
684
|
end
|
659
685
|
|
660
686
|
class Reporter < AbstractReporter # :nodoc:
|
@@ -828,7 +854,7 @@ module Minitest
|
|
828
854
|
io.puts "# Running:"
|
829
855
|
io.puts
|
830
856
|
|
831
|
-
self.sync = io.respond_to? :"sync="
|
857
|
+
self.sync = io.respond_to? :"sync="
|
832
858
|
self.old_sync, io.sync = io.sync, true if self.sync
|
833
859
|
end
|
834
860
|
|
@@ -936,6 +962,8 @@ module Minitest
|
|
936
962
|
# Represents run failures.
|
937
963
|
|
938
964
|
class Assertion < Exception
|
965
|
+
RE = /in .(?:assert|refute|flunk|pass|fail|raise|must|wont)/ # :nodoc:
|
966
|
+
|
939
967
|
def error # :nodoc:
|
940
968
|
self
|
941
969
|
end
|
@@ -944,12 +972,11 @@ module Minitest
|
|
944
972
|
# Where was this run before an assertion was raised?
|
945
973
|
|
946
974
|
def location
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
last_before_assertion.sub(/:in .*$/, "")
|
975
|
+
bt = Minitest.filter_backtrace self.backtrace
|
976
|
+
idx = bt.rindex { |s| s.match? RE } || -1 # fall back to first item
|
977
|
+
loc = bt[idx+1] || bt.last || "unknown:-1"
|
978
|
+
|
979
|
+
loc.sub(/:in .*$/, "")
|
953
980
|
end
|
954
981
|
|
955
982
|
def result_code # :nodoc:
|
@@ -974,11 +1001,21 @@ module Minitest
|
|
974
1001
|
# Assertion wrapping an unexpected error that was raised during a run.
|
975
1002
|
|
976
1003
|
class UnexpectedError < Assertion
|
1004
|
+
include Minitest::Compress
|
1005
|
+
|
977
1006
|
# TODO: figure out how to use `cause` instead
|
978
1007
|
attr_accessor :error # :nodoc:
|
979
1008
|
|
980
1009
|
def initialize error # :nodoc:
|
981
1010
|
super "Unexpected exception"
|
1011
|
+
|
1012
|
+
if SystemStackError === error then
|
1013
|
+
bt = error.backtrace
|
1014
|
+
new_bt = compress bt
|
1015
|
+
error = error.exception "#{bt.size} -> #{new_bt.size}"
|
1016
|
+
error.set_backtrace new_bt
|
1017
|
+
end
|
1018
|
+
|
982
1019
|
self.error = error
|
983
1020
|
end
|
984
1021
|
|
@@ -986,8 +1023,11 @@ module Minitest
|
|
986
1023
|
self.error.backtrace
|
987
1024
|
end
|
988
1025
|
|
1026
|
+
BASE_RE = %r%#{Dir.pwd}/% # :nodoc:
|
1027
|
+
|
989
1028
|
def message # :nodoc:
|
990
|
-
bt = Minitest.filter_backtrace(self.backtrace).join
|
1029
|
+
bt = Minitest.filter_backtrace(self.backtrace).join("\n ")
|
1030
|
+
.gsub(BASE_RE, "")
|
991
1031
|
"#{self.error.class}: #{self.error.message}\n #{bt}"
|
992
1032
|
end
|
993
1033
|
|
@@ -1071,6 +1111,12 @@ module Minitest
|
|
1071
1111
|
|
1072
1112
|
MT_RE = %r%lib/minitest% #:nodoc:
|
1073
1113
|
|
1114
|
+
attr_accessor :regexp
|
1115
|
+
|
1116
|
+
def initialize regexp = MT_RE
|
1117
|
+
self.regexp = regexp
|
1118
|
+
end
|
1119
|
+
|
1074
1120
|
##
|
1075
1121
|
# Filter +bt+ to something useful. Returns the whole thing if
|
1076
1122
|
# $DEBUG (ruby) or $MT_DEBUG (env).
|
@@ -1080,9 +1126,9 @@ module Minitest
|
|
1080
1126
|
|
1081
1127
|
return bt.dup if $DEBUG || ENV["MT_DEBUG"]
|
1082
1128
|
|
1083
|
-
new_bt = bt.take_while { |line| line !~
|
1084
|
-
new_bt = bt.select { |line| line !~
|
1085
|
-
new_bt = bt.dup
|
1129
|
+
new_bt = bt.take_while { |line| line.to_s !~ regexp }
|
1130
|
+
new_bt = bt.select { |line| line.to_s !~ regexp } if new_bt.empty?
|
1131
|
+
new_bt = bt.dup if new_bt.empty?
|
1086
1132
|
|
1087
1133
|
new_bt
|
1088
1134
|
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
Binary file
|
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.1
|
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-07 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
|