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.
@@ -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("diff.exe", __FILE__, __FILE__)) then
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("gdiff", __FILE__, __FILE__)
33
+ elsif system "gdiff", __FILE__, __FILE__ then
36
34
  "gdiff -u" # solaris and kin suck
37
- elsif system("diff", __FILE__, __FILE__)
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(exp, act)
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.open("expect") do |a|
65
+ Tempfile.create "expect" do |a|
68
66
  a.puts expect
69
67
  a.flush
70
68
 
71
- Tempfile.open("butwas") do |b|
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
- "No visible difference in the #{klass}#inspect output.\n",
83
- "You should look at the implementation of #== on ",
84
- "#{klass} or its members.\n",
85
- expect,
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
- if defined? Encoding then
133
- s = s.encode Encoding.default_external
130
+ return s unless String === obj &&
131
+ (obj.encoding != Encoding.default_external || !obj.valid_encoding?)
134
132
 
135
- if String === obj && (obj.encoding != Encoding.default_external ||
136
- !obj.valid_encoding?) then
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 = !!str.match(/(?<!\\|^)\\n/)
157
- double = !!str.match(/(?<=\\|^)\\n/)
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(obj)} to be empty" }
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 =~ /^6/ then
225
+ if Minitest::VERSION >= "6" then
222
226
  refute_nil exp, "Use assert_nil if expecting nil."
223
227
  else
224
- where = Minitest.filter_backtrace(caller).first
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(collection)} to include #{mu_pp(obj)}"
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(obj)} to be an instance of #{cls}, not #{obj.class}"
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(obj)} to be a kind of #{cls}, not #{obj.class}" }
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(obj)} to be nil" }
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(o1)} to be #{op} #{mu_pp(o2)}" }
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
- begin # TODO: remove after ruby 2.6 dropped
379
- yield
380
- pass
381
- rescue NoMatchingPatternError => e
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(o1)} to be #{op}" }
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(exp)} exception expected, not")
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(exp)} expected but nothing was raised."
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(obj)} (#{obj.class}) to respond to ##{meth}"
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
- where = Minitest.filter_backtrace(caller).first
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(recv)}.#{msg}(*#{mu_pp(args)}) to return true" }
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(sym)} to have been thrown"
501
+ default = "Expected #{mu_pp sym} to have been thrown"
503
502
  caught = true
504
- value = catch(sym) do
503
+ value = catch sym do
505
504
  begin
506
505
  yield
507
- rescue ThreadError => e # wtf?!? 1.8 + threads == suck
508
- default += ", not \:#{e.message[/uncaught throw \`(\w+?)\'/, 1]}"
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
- "#{msg}",
610
- "Class: <#{e.class}>",
611
- "Message: <#{e.message.inspect}>",
612
- "---Backtrace---",
613
- "#{Minitest.filter_backtrace(e.backtrace).join("\n")}",
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(test)} to not be truthy" }
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(obj)} to not be empty" }
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(act)} to not be equal to #{mu_pp(exp)}"
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 a, b, epsilon = 0.001, msg = nil
700
- refute_in_delta a, b, a * epsilon, msg
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(collection)} to not include #{mu_pp(obj)}"
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(obj)} to not be an instance of #{cls}"
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(obj)} to not be a kind of #{cls}" }
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(obj)} to not be nil" }
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
- begin
767
- yield
768
- flunk("NoMatchingPatternError expected, but nothing was raised.")
769
- rescue NoMatchingPatternError
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(o1)} to not be #{op} #{mu_pp(o2)}" }
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(o1)} to not be #{op}" }
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(obj)} to not respond to #{meth}" }
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, bt = caller
825
+ def skip msg = nil, _ignored = nil
834
826
  msg ||= "Skipped, no message given"
835
827
  @skip = true
836
- raise Minitest::Skip, msg, bt
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(':in').reject(&:empty?).first
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
 
@@ -1,13 +1,6 @@
1
- begin
2
- require "rubygems"
3
- gem "minitest"
4
- rescue Gem::LoadError
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
@@ -1,5 +1,5 @@
1
- require "minitest/test"
2
- require "minitest/spec"
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 "#{self.name}"
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(ys)
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(ys)
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(ys)
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(ys)
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.inject { |sum, n| sum + n }
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
@@ -0,0 +1,11 @@
1
+ module Minitest
2
+
3
+ module ErrorOnWarning # :nodoc:
4
+ def warn message, category: nil
5
+ message = "[#{category}] #{message}" if category
6
+ raise UnexpectedWarning, message
7
+ end
8
+ end
9
+
10
+ ::Warning.singleton_class.prepend ErrorOnWarning
11
+ end