minitest 5.20.0 → 5.22.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 +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
|