minitest 5.20.0 → 5.27.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 +4 -4
- data/History.rdoc +206 -3
- data/Manifest.txt +3 -0
- data/README.rdoc +30 -17
- data/Rakefile +24 -2
- data/design_rationale.rb +21 -19
- data/lib/hoe/minitest.rb +4 -2
- data/lib/minitest/assertions.rb +92 -100
- data/lib/minitest/autorun.rb +4 -11
- data/lib/minitest/benchmark.rb +8 -11
- data/lib/minitest/compress.rb +94 -0
- data/lib/minitest/error_on_warning.rb +11 -0
- data/lib/minitest/expectations.rb +2 -2
- data/lib/minitest/hell.rb +1 -1
- data/lib/minitest/manual_plugins.rb +16 -0
- data/lib/minitest/mock.rb +44 -44
- data/lib/minitest/parallel.rb +7 -5
- data/lib/minitest/pride.rb +1 -1
- data/lib/minitest/pride_plugin.rb +17 -24
- data/lib/minitest/spec.rb +22 -18
- data/lib/minitest/test.rb +19 -29
- data/lib/minitest/test_task.rb +45 -23
- data/lib/minitest/unit.rb +1 -1
- data/lib/minitest.rb +289 -160
- data/test/minitest/metametameta.rb +32 -18
- data/test/minitest/test_minitest_assertions.rb +173 -197
- data/test/minitest/test_minitest_benchmark.rb +1 -1
- data/test/minitest/test_minitest_mock.rb +156 -89
- data/test/minitest/test_minitest_reporter.rb +120 -24
- data/test/minitest/test_minitest_spec.rb +95 -82
- data/test/minitest/test_minitest_test.rb +212 -120
- data/test/minitest/test_minitest_test_task.rb +18 -7
- data.tar.gz.sig +0 -0
- metadata +36 -22
- metadata.gz.sig +0 -0
data/lib/minitest/assertions.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
1
|
require "rbconfig"
|
|
4
2
|
require "tempfile"
|
|
5
3
|
require "stringio"
|
|
@@ -29,12 +27,12 @@ module Minitest
|
|
|
29
27
|
def self.diff
|
|
30
28
|
return @diff if defined? @diff
|
|
31
29
|
|
|
32
|
-
@diff = if (RbConfig::CONFIG["host_os"] =~ /mswin|mingw/
|
|
33
|
-
system
|
|
30
|
+
@diff = if (RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ and
|
|
31
|
+
system "diff.exe", __FILE__, __FILE__) then
|
|
34
32
|
"diff.exe -u"
|
|
35
|
-
elsif system
|
|
33
|
+
elsif system "gdiff", __FILE__, __FILE__ then
|
|
36
34
|
"gdiff -u" # solaris and kin suck
|
|
37
|
-
elsif system
|
|
35
|
+
elsif system "diff", __FILE__, __FILE__ then
|
|
38
36
|
"diff -u"
|
|
39
37
|
else
|
|
40
38
|
nil
|
|
@@ -59,16 +57,16 @@ module Minitest
|
|
|
59
57
|
def diff exp, act
|
|
60
58
|
result = nil
|
|
61
59
|
|
|
62
|
-
expect, butwas = things_to_diff
|
|
60
|
+
expect, butwas = things_to_diff exp, act
|
|
63
61
|
|
|
64
62
|
return "Expected: #{mu_pp exp}\n Actual: #{mu_pp act}" unless
|
|
65
63
|
expect
|
|
66
64
|
|
|
67
|
-
Tempfile.
|
|
65
|
+
Tempfile.create "expect" do |a|
|
|
68
66
|
a.puts expect
|
|
69
67
|
a.flush
|
|
70
68
|
|
|
71
|
-
Tempfile.
|
|
69
|
+
Tempfile.create "butwas" do |b|
|
|
72
70
|
b.puts butwas
|
|
73
71
|
b.flush
|
|
74
72
|
|
|
@@ -79,10 +77,10 @@ module Minitest
|
|
|
79
77
|
if result.empty? then
|
|
80
78
|
klass = exp.class
|
|
81
79
|
result = [
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
80
|
+
"No visible difference in the #{klass}#inspect output.\n",
|
|
81
|
+
"You should look at the implementation of #== on ",
|
|
82
|
+
"#{klass} or its members.\n",
|
|
83
|
+
expect,
|
|
86
84
|
].join
|
|
87
85
|
end
|
|
88
86
|
end
|
|
@@ -127,20 +125,15 @@ module Minitest
|
|
|
127
125
|
# See Minitest::Test.make_my_diffs_pretty!
|
|
128
126
|
|
|
129
127
|
def mu_pp obj
|
|
130
|
-
s = obj.inspect
|
|
128
|
+
s = obj.inspect.encode Encoding.default_external
|
|
131
129
|
|
|
132
|
-
|
|
133
|
-
|
|
130
|
+
return s unless String === obj &&
|
|
131
|
+
(obj.encoding != Encoding.default_external || !obj.valid_encoding?)
|
|
134
132
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
enc = "# encoding: #{obj.encoding}"
|
|
138
|
-
val = "# valid: #{obj.valid_encoding?}"
|
|
139
|
-
s = "#{enc}\n#{val}\n#{s}"
|
|
140
|
-
end
|
|
141
|
-
end
|
|
133
|
+
enc = "# encoding: #{obj.encoding}"
|
|
134
|
+
val = "# valid: #{obj.valid_encoding?}"
|
|
142
135
|
|
|
143
|
-
s
|
|
136
|
+
[enc, val, s].join "\n"
|
|
144
137
|
end
|
|
145
138
|
|
|
146
139
|
##
|
|
@@ -153,8 +146,8 @@ module Minitest
|
|
|
153
146
|
str = mu_pp obj
|
|
154
147
|
|
|
155
148
|
# both '\n' & '\\n' (_after_ mu_pp (aka inspect))
|
|
156
|
-
single =
|
|
157
|
-
double =
|
|
149
|
+
single = str.match?(/(?<!\\|^)\\n/)
|
|
150
|
+
double = str.match?(/(?<=\\|^)\\n/)
|
|
158
151
|
|
|
159
152
|
process =
|
|
160
153
|
if single ^ double then
|
|
@@ -167,9 +160,9 @@ module Minitest
|
|
|
167
160
|
:itself # leave it alone
|
|
168
161
|
end
|
|
169
162
|
|
|
170
|
-
str
|
|
171
|
-
gsub(/\\?\\n/, &process)
|
|
172
|
-
gsub(/:0x[a-fA-F0-9]{4,}/m, ":0xXXXXXX") # anonymize hex values
|
|
163
|
+
str
|
|
164
|
+
.gsub(/\\?\\n/, &process)
|
|
165
|
+
.gsub(/:0x[a-fA-F0-9]{4,}/m, ":0xXXXXXX") # anonymize hex values
|
|
173
166
|
end
|
|
174
167
|
|
|
175
168
|
##
|
|
@@ -193,11 +186,22 @@ module Minitest
|
|
|
193
186
|
# Fails unless +obj+ is empty.
|
|
194
187
|
|
|
195
188
|
def assert_empty obj, msg = nil
|
|
196
|
-
msg = message(msg) { "Expected #{mu_pp
|
|
189
|
+
msg = message(msg) { "Expected #{mu_pp obj} to be empty" }
|
|
197
190
|
assert_respond_to obj, :empty?
|
|
198
191
|
assert obj.empty?, msg
|
|
199
192
|
end
|
|
200
193
|
|
|
194
|
+
def _where # :nodoc:
|
|
195
|
+
Minitest.filter_backtrace(caller).first
|
|
196
|
+
.split(":in ", 2).first # clean up noise
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def _caller_uplevel # :nodoc:
|
|
200
|
+
backtrace = caller
|
|
201
|
+
real_caller = Minitest.filter_backtrace(caller).first
|
|
202
|
+
backtrace.index(real_caller)
|
|
203
|
+
end
|
|
204
|
+
|
|
201
205
|
E = "" # :nodoc:
|
|
202
206
|
|
|
203
207
|
##
|
|
@@ -218,13 +222,10 @@ module Minitest
|
|
|
218
222
|
result = assert exp == act, msg
|
|
219
223
|
|
|
220
224
|
if nil == exp then
|
|
221
|
-
if Minitest::VERSION
|
|
225
|
+
if Minitest::VERSION >= "6" then
|
|
222
226
|
refute_nil exp, "Use assert_nil if expecting nil."
|
|
223
227
|
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."
|
|
228
|
+
warn "DEPRECATED: Use assert_nil if expecting nil. This will fail in Minitest 6.", uplevel: _caller_uplevel
|
|
228
229
|
end
|
|
229
230
|
end
|
|
230
231
|
|
|
@@ -258,7 +259,7 @@ module Minitest
|
|
|
258
259
|
|
|
259
260
|
def assert_includes collection, obj, msg = nil
|
|
260
261
|
msg = message(msg) {
|
|
261
|
-
"Expected #{mu_pp
|
|
262
|
+
"Expected #{mu_pp collection} to include #{mu_pp obj}"
|
|
262
263
|
}
|
|
263
264
|
assert_respond_to collection, :include?
|
|
264
265
|
assert collection.include?(obj), msg
|
|
@@ -269,7 +270,7 @@ module Minitest
|
|
|
269
270
|
|
|
270
271
|
def assert_instance_of cls, obj, msg = nil
|
|
271
272
|
msg = message(msg) {
|
|
272
|
-
"Expected #{mu_pp
|
|
273
|
+
"Expected #{mu_pp obj} to be an instance of #{cls}, not #{obj.class}"
|
|
273
274
|
}
|
|
274
275
|
|
|
275
276
|
assert obj.instance_of?(cls), msg
|
|
@@ -280,7 +281,8 @@ module Minitest
|
|
|
280
281
|
|
|
281
282
|
def assert_kind_of cls, obj, msg = nil
|
|
282
283
|
msg = message(msg) {
|
|
283
|
-
"Expected #{mu_pp
|
|
284
|
+
"Expected #{mu_pp obj} to be a kind of #{cls}, not #{obj.class}"
|
|
285
|
+
}
|
|
284
286
|
|
|
285
287
|
assert obj.kind_of?(cls), msg
|
|
286
288
|
end
|
|
@@ -290,7 +292,7 @@ module Minitest
|
|
|
290
292
|
|
|
291
293
|
def assert_match matcher, obj, msg = nil
|
|
292
294
|
msg = message(msg) { "Expected #{mu_pp matcher} to match #{mu_pp obj}" }
|
|
293
|
-
assert_respond_to matcher,
|
|
295
|
+
assert_respond_to matcher, :=~
|
|
294
296
|
matcher = Regexp.new Regexp.escape matcher if String === matcher
|
|
295
297
|
assert matcher =~ obj, msg
|
|
296
298
|
|
|
@@ -301,7 +303,7 @@ module Minitest
|
|
|
301
303
|
# Fails unless +obj+ is nil
|
|
302
304
|
|
|
303
305
|
def assert_nil obj, msg = nil
|
|
304
|
-
msg = message(msg) { "Expected #{mu_pp
|
|
306
|
+
msg = message(msg) { "Expected #{mu_pp obj} to be nil" }
|
|
305
307
|
assert obj.nil?, msg
|
|
306
308
|
end
|
|
307
309
|
|
|
@@ -312,7 +314,7 @@ module Minitest
|
|
|
312
314
|
|
|
313
315
|
def assert_operator o1, op, o2 = UNDEFINED, msg = nil
|
|
314
316
|
return assert_predicate o1, op, msg if UNDEFINED == o2
|
|
315
|
-
msg = message(msg) { "Expected #{mu_pp
|
|
317
|
+
msg = message(msg) { "Expected #{mu_pp o1} to be #{op} #{mu_pp o2}" }
|
|
316
318
|
assert o1.__send__(op, o2), msg
|
|
317
319
|
end
|
|
318
320
|
|
|
@@ -372,15 +374,12 @@ module Minitest
|
|
|
372
374
|
# error.
|
|
373
375
|
|
|
374
376
|
def assert_pattern
|
|
375
|
-
raise NotImplementedError, "only available in Ruby 3.0+" unless RUBY_VERSION >= "3.0"
|
|
376
377
|
flunk "assert_pattern requires a block to capture errors." unless block_given?
|
|
377
378
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
flunk e.message
|
|
383
|
-
end
|
|
379
|
+
yield
|
|
380
|
+
pass
|
|
381
|
+
rescue NoMatchingPatternError => e
|
|
382
|
+
flunk e.message
|
|
384
383
|
end
|
|
385
384
|
|
|
386
385
|
##
|
|
@@ -393,7 +392,7 @@ module Minitest
|
|
|
393
392
|
# str.must_be :empty?
|
|
394
393
|
|
|
395
394
|
def assert_predicate o1, op, msg = nil
|
|
396
|
-
msg = message(msg) { "Expected #{mu_pp
|
|
395
|
+
msg = message(msg) { "Expected #{mu_pp o1} to be #{op}" }
|
|
397
396
|
assert o1.__send__(op), msg
|
|
398
397
|
end
|
|
399
398
|
|
|
@@ -438,23 +437,24 @@ module Minitest
|
|
|
438
437
|
raise
|
|
439
438
|
rescue Exception => e
|
|
440
439
|
flunk proc {
|
|
441
|
-
exception_details(e, "#{msg}#{mu_pp
|
|
440
|
+
exception_details(e, "#{msg}#{mu_pp exp} exception expected, not")
|
|
442
441
|
}
|
|
443
442
|
end
|
|
444
443
|
|
|
445
444
|
exp = exp.first if exp.size == 1
|
|
446
445
|
|
|
447
|
-
flunk "#{msg}#{mu_pp
|
|
446
|
+
flunk "#{msg}#{mu_pp exp} expected but nothing was raised."
|
|
448
447
|
end
|
|
449
448
|
|
|
450
449
|
##
|
|
451
450
|
# Fails unless +obj+ responds to +meth+.
|
|
451
|
+
# include_all defaults to false to match Object#respond_to?
|
|
452
452
|
|
|
453
|
-
def assert_respond_to obj, meth, msg = nil
|
|
453
|
+
def assert_respond_to obj, meth, msg = nil, include_all: false
|
|
454
454
|
msg = message(msg) {
|
|
455
|
-
"Expected #{mu_pp
|
|
455
|
+
"Expected #{mu_pp obj} (#{obj.class}) to respond to ##{meth}"
|
|
456
456
|
}
|
|
457
|
-
assert obj.respond_to?(meth), msg
|
|
457
|
+
assert obj.respond_to?(meth, include_all), msg
|
|
458
458
|
end
|
|
459
459
|
|
|
460
460
|
##
|
|
@@ -474,13 +474,12 @@ module Minitest
|
|
|
474
474
|
# Fails unless the call returns a true value
|
|
475
475
|
|
|
476
476
|
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}"
|
|
477
|
+
warn "DEPRECATED: assert_send.", uplevel: _caller_uplevel
|
|
480
478
|
|
|
481
479
|
recv, msg, *args = send_ary
|
|
482
480
|
m = message(m) {
|
|
483
|
-
"Expected #{mu_pp
|
|
481
|
+
"Expected #{mu_pp recv}.#{msg}(*#{mu_pp args}) to return true"
|
|
482
|
+
}
|
|
484
483
|
assert recv.__send__(msg, *args), m
|
|
485
484
|
end
|
|
486
485
|
|
|
@@ -499,19 +498,14 @@ module Minitest
|
|
|
499
498
|
# Fails unless the block throws +sym+
|
|
500
499
|
|
|
501
500
|
def assert_throws sym, msg = nil
|
|
502
|
-
default = "Expected #{mu_pp
|
|
501
|
+
default = "Expected #{mu_pp sym} to have been thrown"
|
|
503
502
|
caught = true
|
|
504
|
-
value = catch
|
|
503
|
+
value = catch sym do
|
|
505
504
|
begin
|
|
506
505
|
yield
|
|
507
|
-
rescue
|
|
508
|
-
|
|
509
|
-
rescue ArgumentError => e # 1.9 exception
|
|
510
|
-
raise e unless e.message.include?("uncaught throw")
|
|
506
|
+
rescue ArgumentError => e # 1.9+ exception
|
|
507
|
+
raise e unless e.message.include? "uncaught throw"
|
|
511
508
|
default += ", not #{e.message.split(/ /).last}"
|
|
512
|
-
rescue NameError => e # 1.8 exception
|
|
513
|
-
raise e unless e.name == sym
|
|
514
|
-
default += ", not #{e.name.inspect}"
|
|
515
509
|
end
|
|
516
510
|
caught = false
|
|
517
511
|
end
|
|
@@ -606,12 +600,12 @@ module Minitest
|
|
|
606
600
|
|
|
607
601
|
def exception_details e, msg
|
|
608
602
|
[
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
603
|
+
msg,
|
|
604
|
+
"Class: <#{e.class}>",
|
|
605
|
+
"Message: <#{e.message.inspect}>",
|
|
606
|
+
"---Backtrace---",
|
|
607
|
+
Minitest.filter_backtrace(e.backtrace),
|
|
608
|
+
"---------------",
|
|
615
609
|
].join "\n"
|
|
616
610
|
end
|
|
617
611
|
|
|
@@ -620,7 +614,7 @@ module Minitest
|
|
|
620
614
|
# you to put time-bombs in your tests if you need to keep
|
|
621
615
|
# something around until a later date lest you forget about it.
|
|
622
616
|
|
|
623
|
-
def fail_after y,m,d,msg
|
|
617
|
+
def fail_after y, m, d, msg
|
|
624
618
|
flunk msg if Time.now > Time.local(y, m, d)
|
|
625
619
|
end
|
|
626
620
|
|
|
@@ -654,7 +648,7 @@ module Minitest
|
|
|
654
648
|
# Fails if +test+ is truthy.
|
|
655
649
|
|
|
656
650
|
def refute test, msg = nil
|
|
657
|
-
msg ||= message { "Expected #{mu_pp
|
|
651
|
+
msg ||= message { "Expected #{mu_pp test} to not be truthy" }
|
|
658
652
|
assert !test, msg
|
|
659
653
|
end
|
|
660
654
|
|
|
@@ -662,7 +656,7 @@ module Minitest
|
|
|
662
656
|
# Fails if +obj+ is empty.
|
|
663
657
|
|
|
664
658
|
def refute_empty obj, msg = nil
|
|
665
|
-
msg = message(msg) { "Expected #{mu_pp
|
|
659
|
+
msg = message(msg) { "Expected #{mu_pp obj} to not be empty" }
|
|
666
660
|
assert_respond_to obj, :empty?
|
|
667
661
|
refute obj.empty?, msg
|
|
668
662
|
end
|
|
@@ -674,7 +668,7 @@ module Minitest
|
|
|
674
668
|
|
|
675
669
|
def refute_equal exp, act, msg = nil
|
|
676
670
|
msg = message(msg) {
|
|
677
|
-
"Expected #{mu_pp
|
|
671
|
+
"Expected #{mu_pp act} to not be equal to #{mu_pp exp}"
|
|
678
672
|
}
|
|
679
673
|
refute exp == act, msg
|
|
680
674
|
end
|
|
@@ -696,8 +690,8 @@ module Minitest
|
|
|
696
690
|
# For comparing Floats. Fails if +exp+ and +act+ have a relative error
|
|
697
691
|
# less than +epsilon+.
|
|
698
692
|
|
|
699
|
-
def refute_in_epsilon
|
|
700
|
-
refute_in_delta
|
|
693
|
+
def refute_in_epsilon exp, act, epsilon = 0.001, msg = nil
|
|
694
|
+
refute_in_delta exp, act, [exp.abs, act.abs].min * epsilon, msg
|
|
701
695
|
end
|
|
702
696
|
|
|
703
697
|
##
|
|
@@ -705,7 +699,7 @@ module Minitest
|
|
|
705
699
|
|
|
706
700
|
def refute_includes collection, obj, msg = nil
|
|
707
701
|
msg = message(msg) {
|
|
708
|
-
"Expected #{mu_pp
|
|
702
|
+
"Expected #{mu_pp collection} to not include #{mu_pp obj}"
|
|
709
703
|
}
|
|
710
704
|
assert_respond_to collection, :include?
|
|
711
705
|
refute collection.include?(obj), msg
|
|
@@ -716,7 +710,7 @@ module Minitest
|
|
|
716
710
|
|
|
717
711
|
def refute_instance_of cls, obj, msg = nil
|
|
718
712
|
msg = message(msg) {
|
|
719
|
-
"Expected #{mu_pp
|
|
713
|
+
"Expected #{mu_pp obj} to not be an instance of #{cls}"
|
|
720
714
|
}
|
|
721
715
|
refute obj.instance_of?(cls), msg
|
|
722
716
|
end
|
|
@@ -725,7 +719,7 @@ module Minitest
|
|
|
725
719
|
# Fails if +obj+ is a kind of +cls+.
|
|
726
720
|
|
|
727
721
|
def refute_kind_of cls, obj, msg = nil
|
|
728
|
-
msg = message(msg) { "Expected #{mu_pp
|
|
722
|
+
msg = message(msg) { "Expected #{mu_pp obj} to not be a kind of #{cls}" }
|
|
729
723
|
refute obj.kind_of?(cls), msg
|
|
730
724
|
end
|
|
731
725
|
|
|
@@ -734,7 +728,7 @@ module Minitest
|
|
|
734
728
|
|
|
735
729
|
def refute_match matcher, obj, msg = nil
|
|
736
730
|
msg = message(msg) { "Expected #{mu_pp matcher} to not match #{mu_pp obj}" }
|
|
737
|
-
assert_respond_to matcher,
|
|
731
|
+
assert_respond_to matcher, :=~
|
|
738
732
|
matcher = Regexp.new Regexp.escape matcher if String === matcher
|
|
739
733
|
refute matcher =~ obj, msg
|
|
740
734
|
end
|
|
@@ -743,7 +737,7 @@ module Minitest
|
|
|
743
737
|
# Fails if +obj+ is nil.
|
|
744
738
|
|
|
745
739
|
def refute_nil obj, msg = nil
|
|
746
|
-
msg = message(msg) { "Expected #{mu_pp
|
|
740
|
+
msg = message(msg) { "Expected #{mu_pp obj} to not be nil" }
|
|
747
741
|
refute obj.nil?, msg
|
|
748
742
|
end
|
|
749
743
|
|
|
@@ -760,15 +754,12 @@ module Minitest
|
|
|
760
754
|
# other exceptions will be raised as normal and generate a test error.
|
|
761
755
|
|
|
762
756
|
def refute_pattern
|
|
763
|
-
raise NotImplementedError, "only available in Ruby 3.0+" unless RUBY_VERSION >= "3.0"
|
|
764
757
|
flunk "refute_pattern requires a block to capture errors." unless block_given?
|
|
765
758
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
pass
|
|
771
|
-
end
|
|
759
|
+
yield
|
|
760
|
+
flunk "NoMatchingPatternError expected, but nothing was raised."
|
|
761
|
+
rescue NoMatchingPatternError
|
|
762
|
+
pass
|
|
772
763
|
end
|
|
773
764
|
|
|
774
765
|
##
|
|
@@ -779,7 +770,7 @@ module Minitest
|
|
|
779
770
|
|
|
780
771
|
def refute_operator o1, op, o2 = UNDEFINED, msg = nil
|
|
781
772
|
return refute_predicate o1, op, msg if UNDEFINED == o2
|
|
782
|
-
msg = message(msg) { "Expected #{mu_pp
|
|
773
|
+
msg = message(msg) { "Expected #{mu_pp o1} to not be #{op} #{mu_pp o2}" }
|
|
783
774
|
refute o1.__send__(op, o2), msg
|
|
784
775
|
end
|
|
785
776
|
|
|
@@ -801,17 +792,18 @@ module Minitest
|
|
|
801
792
|
# str.wont_be :empty?
|
|
802
793
|
|
|
803
794
|
def refute_predicate o1, op, msg = nil
|
|
804
|
-
msg = message(msg) { "Expected #{mu_pp
|
|
795
|
+
msg = message(msg) { "Expected #{mu_pp o1} to not be #{op}" }
|
|
805
796
|
refute o1.__send__(op), msg
|
|
806
797
|
end
|
|
807
798
|
|
|
808
799
|
##
|
|
809
800
|
# Fails if +obj+ responds to the message +meth+.
|
|
801
|
+
# include_all defaults to false to match Object#respond_to?
|
|
810
802
|
|
|
811
|
-
def refute_respond_to obj, meth, msg = nil
|
|
812
|
-
msg = message(msg) { "Expected #{mu_pp
|
|
803
|
+
def refute_respond_to obj, meth, msg = nil, include_all: false
|
|
804
|
+
msg = message(msg) { "Expected #{mu_pp obj} to not respond to #{meth}" }
|
|
813
805
|
|
|
814
|
-
refute obj.respond_to?(meth), msg
|
|
806
|
+
refute obj.respond_to?(meth, include_all), msg
|
|
815
807
|
end
|
|
816
808
|
|
|
817
809
|
##
|
|
@@ -830,10 +822,10 @@ module Minitest
|
|
|
830
822
|
# gets listed at the end of the run but doesn't cause a failure
|
|
831
823
|
# exit code.
|
|
832
824
|
|
|
833
|
-
def skip msg = nil,
|
|
825
|
+
def skip msg = nil, _ignored = nil
|
|
834
826
|
msg ||= "Skipped, no message given"
|
|
835
827
|
@skip = true
|
|
836
|
-
raise Minitest::Skip, msg
|
|
828
|
+
raise Minitest::Skip, msg
|
|
837
829
|
end
|
|
838
830
|
|
|
839
831
|
##
|
|
@@ -842,9 +834,9 @@ module Minitest
|
|
|
842
834
|
# date, but still holds you accountable and prevents you from
|
|
843
835
|
# forgetting it.
|
|
844
836
|
|
|
845
|
-
def skip_until y,m,d,msg
|
|
837
|
+
def skip_until y, m, d, msg
|
|
846
838
|
skip msg if Time.now < Time.local(y, m, d)
|
|
847
|
-
where = caller.first.rpartition(
|
|
839
|
+
where = caller(1..1).first.rpartition(":in").reject(&:empty?).first
|
|
848
840
|
warn "Stale skip_until %p at %s" % [msg, where]
|
|
849
841
|
end
|
|
850
842
|
|
data/lib/minitest/autorun.rb
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
# do nothing
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
require "minitest"
|
|
9
|
-
require "minitest/spec"
|
|
10
|
-
require "minitest/mock"
|
|
11
|
-
require "minitest/hell" if ENV["MT_HELL"]
|
|
1
|
+
require_relative "../minitest"
|
|
2
|
+
require_relative "spec"
|
|
3
|
+
require_relative "mock"
|
|
4
|
+
require_relative "hell" if ENV["MT_HELL"]
|
|
12
5
|
|
|
13
6
|
Minitest.autorun
|
data/lib/minitest/benchmark.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
require_relative "test"
|
|
2
|
+
require_relative "spec"
|
|
3
3
|
|
|
4
4
|
module Minitest
|
|
5
5
|
##
|
|
@@ -47,8 +47,6 @@ module Minitest
|
|
|
47
47
|
|
|
48
48
|
def self.bench_linear min, max, step = 10
|
|
49
49
|
(min..max).step(step).to_a
|
|
50
|
-
rescue LocalJumpError # 1.8.6
|
|
51
|
-
r = []; (min..max).step(step) { |n| r << n }; r
|
|
52
50
|
end
|
|
53
51
|
|
|
54
52
|
##
|
|
@@ -83,7 +81,7 @@ module Minitest
|
|
|
83
81
|
def assert_performance validation, &work
|
|
84
82
|
range = self.class.bench_range
|
|
85
83
|
|
|
86
|
-
io.print
|
|
84
|
+
io.print self.name
|
|
87
85
|
|
|
88
86
|
times = []
|
|
89
87
|
|
|
@@ -236,7 +234,7 @@ module Minitest
|
|
|
236
234
|
|
|
237
235
|
def fit_exponential xs, ys
|
|
238
236
|
n = xs.size
|
|
239
|
-
xys = xs.zip
|
|
237
|
+
xys = xs.zip ys
|
|
240
238
|
sxlny = sigma(xys) { |x, y| x * Math.log(y) }
|
|
241
239
|
slny = sigma(xys) { |_, y| Math.log(y) }
|
|
242
240
|
sx2 = sigma(xys) { |x, _| x * x }
|
|
@@ -258,7 +256,7 @@ module Minitest
|
|
|
258
256
|
|
|
259
257
|
def fit_logarithmic xs, ys
|
|
260
258
|
n = xs.size
|
|
261
|
-
xys = xs.zip
|
|
259
|
+
xys = xs.zip ys
|
|
262
260
|
slnx2 = sigma(xys) { |x, _| Math.log(x) ** 2 }
|
|
263
261
|
slnx = sigma(xys) { |x, _| Math.log(x) }
|
|
264
262
|
sylnx = sigma(xys) { |x, y| y * Math.log(x) }
|
|
@@ -280,7 +278,7 @@ module Minitest
|
|
|
280
278
|
|
|
281
279
|
def fit_linear xs, ys
|
|
282
280
|
n = xs.size
|
|
283
|
-
xys = xs.zip
|
|
281
|
+
xys = xs.zip ys
|
|
284
282
|
sx = sigma xs
|
|
285
283
|
sy = sigma ys
|
|
286
284
|
sx2 = sigma(xs) { |x| x ** 2 }
|
|
@@ -302,7 +300,7 @@ module Minitest
|
|
|
302
300
|
|
|
303
301
|
def fit_power xs, ys
|
|
304
302
|
n = xs.size
|
|
305
|
-
xys = xs.zip
|
|
303
|
+
xys = xs.zip ys
|
|
306
304
|
slnxlny = sigma(xys) { |x, y| Math.log(x) * Math.log(y) }
|
|
307
305
|
slnx = sigma(xs) { |x | Math.log(x) }
|
|
308
306
|
slny = sigma(ys) { | y| Math.log(y) }
|
|
@@ -323,7 +321,7 @@ module Minitest
|
|
|
323
321
|
|
|
324
322
|
def sigma enum, &block
|
|
325
323
|
enum = enum.map(&block) if block
|
|
326
|
-
enum.
|
|
324
|
+
enum.sum
|
|
327
325
|
end
|
|
328
326
|
|
|
329
327
|
##
|
|
@@ -419,7 +417,6 @@ module Minitest
|
|
|
419
417
|
end
|
|
420
418
|
end
|
|
421
419
|
|
|
422
|
-
|
|
423
420
|
##
|
|
424
421
|
# Create a benchmark that verifies that the performance is logarithmic.
|
|
425
422
|
#
|
|
@@ -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 = ->(a, n, off) { # each_slice_with_offset
|
|
15
|
+
if off.zero? then
|
|
16
|
+
a.each_slice n
|
|
17
|
+
else
|
|
18
|
+
# [ ...off... [...n...] [...n...] ... ]
|
|
19
|
+
front, back = a.take(off), a.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, a1| ### sort by max dist + min offset
|
|
33
|
+
d = a1.each_cons(2).sum { |a2, b| b-a2 }
|
|
34
|
+
[-d, a1.first]
|
|
35
|
+
} # b: [1 3 5] c: [2 4 6]
|
|
36
|
+
|
|
37
|
+
ranges = order
|
|
38
|
+
.map { |k, a1| # [[1..2 3..4] [2..3 4..5]]
|
|
39
|
+
a1
|
|
40
|
+
.each_cons(2)
|
|
41
|
+
.map { |a2, b| a2..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
|