minitest 5.20.0 → 5.25.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.open "expect" do |a|
68
66
  a.puts expect
69
67
  a.flush
70
68
 
71
- Tempfile.open("butwas") do |b|
69
+ Tempfile.open "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,16 @@ 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
+
201
199
  E = "" # :nodoc:
202
200
 
203
201
  ##
@@ -218,13 +216,10 @@ module Minitest
218
216
  result = assert exp == act, msg
219
217
 
220
218
  if nil == exp then
221
- if Minitest::VERSION =~ /^6/ then
219
+ if Minitest::VERSION >= "6" then
222
220
  refute_nil exp, "Use assert_nil if expecting nil."
223
221
  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."
222
+ warn "DEPRECATED: Use assert_nil if expecting nil from #{_where}. This will fail in Minitest 6."
228
223
  end
229
224
  end
230
225
 
@@ -258,7 +253,7 @@ module Minitest
258
253
 
259
254
  def assert_includes collection, obj, msg = nil
260
255
  msg = message(msg) {
261
- "Expected #{mu_pp(collection)} to include #{mu_pp(obj)}"
256
+ "Expected #{mu_pp collection} to include #{mu_pp obj}"
262
257
  }
263
258
  assert_respond_to collection, :include?
264
259
  assert collection.include?(obj), msg
@@ -269,7 +264,7 @@ module Minitest
269
264
 
270
265
  def assert_instance_of cls, obj, msg = nil
271
266
  msg = message(msg) {
272
- "Expected #{mu_pp(obj)} to be an instance of #{cls}, not #{obj.class}"
267
+ "Expected #{mu_pp obj} to be an instance of #{cls}, not #{obj.class}"
273
268
  }
274
269
 
275
270
  assert obj.instance_of?(cls), msg
@@ -280,7 +275,8 @@ module Minitest
280
275
 
281
276
  def assert_kind_of cls, obj, msg = nil
282
277
  msg = message(msg) {
283
- "Expected #{mu_pp(obj)} to be a kind of #{cls}, not #{obj.class}" }
278
+ "Expected #{mu_pp obj} to be a kind of #{cls}, not #{obj.class}"
279
+ }
284
280
 
285
281
  assert obj.kind_of?(cls), msg
286
282
  end
@@ -290,7 +286,7 @@ module Minitest
290
286
 
291
287
  def assert_match matcher, obj, msg = nil
292
288
  msg = message(msg) { "Expected #{mu_pp matcher} to match #{mu_pp obj}" }
293
- assert_respond_to matcher, :"=~"
289
+ assert_respond_to matcher, :=~
294
290
  matcher = Regexp.new Regexp.escape matcher if String === matcher
295
291
  assert matcher =~ obj, msg
296
292
 
@@ -301,7 +297,7 @@ module Minitest
301
297
  # Fails unless +obj+ is nil
302
298
 
303
299
  def assert_nil obj, msg = nil
304
- msg = message(msg) { "Expected #{mu_pp(obj)} to be nil" }
300
+ msg = message(msg) { "Expected #{mu_pp obj} to be nil" }
305
301
  assert obj.nil?, msg
306
302
  end
307
303
 
@@ -312,7 +308,7 @@ module Minitest
312
308
 
313
309
  def assert_operator o1, op, o2 = UNDEFINED, msg = nil
314
310
  return assert_predicate o1, op, msg if UNDEFINED == o2
315
- msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op} #{mu_pp(o2)}" }
311
+ msg = message(msg) { "Expected #{mu_pp o1} to be #{op} #{mu_pp o2}" }
316
312
  assert o1.__send__(op, o2), msg
317
313
  end
318
314
 
@@ -393,7 +389,7 @@ module Minitest
393
389
  # str.must_be :empty?
394
390
 
395
391
  def assert_predicate o1, op, msg = nil
396
- msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op}" }
392
+ msg = message(msg) { "Expected #{mu_pp o1} to be #{op}" }
397
393
  assert o1.__send__(op), msg
398
394
  end
399
395
 
@@ -438,23 +434,24 @@ module Minitest
438
434
  raise
439
435
  rescue Exception => e
440
436
  flunk proc {
441
- exception_details(e, "#{msg}#{mu_pp(exp)} exception expected, not")
437
+ exception_details(e, "#{msg}#{mu_pp exp} exception expected, not")
442
438
  }
443
439
  end
444
440
 
445
441
  exp = exp.first if exp.size == 1
446
442
 
447
- flunk "#{msg}#{mu_pp(exp)} expected but nothing was raised."
443
+ flunk "#{msg}#{mu_pp exp} expected but nothing was raised."
448
444
  end
449
445
 
450
446
  ##
451
447
  # Fails unless +obj+ responds to +meth+.
448
+ # include_all defaults to false to match Object#respond_to?
452
449
 
453
- def assert_respond_to obj, meth, msg = nil
450
+ def assert_respond_to obj, meth, msg = nil, include_all: false
454
451
  msg = message(msg) {
455
- "Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}"
452
+ "Expected #{mu_pp obj} (#{obj.class}) to respond to ##{meth}"
456
453
  }
457
- assert obj.respond_to?(meth), msg
454
+ assert obj.respond_to?(meth, include_all), msg
458
455
  end
459
456
 
460
457
  ##
@@ -474,13 +471,12 @@ module Minitest
474
471
  # Fails unless the call returns a true value
475
472
 
476
473
  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}"
474
+ warn "DEPRECATED: assert_send. From #{_where}"
480
475
 
481
476
  recv, msg, *args = send_ary
482
477
  m = message(m) {
483
- "Expected #{mu_pp(recv)}.#{msg}(*#{mu_pp(args)}) to return true" }
478
+ "Expected #{mu_pp recv}.#{msg}(*#{mu_pp args}) to return true"
479
+ }
484
480
  assert recv.__send__(msg, *args), m
485
481
  end
486
482
 
@@ -499,15 +495,15 @@ module Minitest
499
495
  # Fails unless the block throws +sym+
500
496
 
501
497
  def assert_throws sym, msg = nil
502
- default = "Expected #{mu_pp(sym)} to have been thrown"
498
+ default = "Expected #{mu_pp sym} to have been thrown"
503
499
  caught = true
504
- value = catch(sym) do
500
+ value = catch sym do
505
501
  begin
506
502
  yield
507
503
  rescue ThreadError => e # wtf?!? 1.8 + threads == suck
508
- default += ", not \:#{e.message[/uncaught throw \`(\w+?)\'/, 1]}"
504
+ default += ", not :#{e.message[/uncaught throw \`(\w+?)\'/, 1]}"
509
505
  rescue ArgumentError => e # 1.9 exception
510
- raise e unless e.message.include?("uncaught throw")
506
+ raise e unless e.message.include? "uncaught throw"
511
507
  default += ", not #{e.message.split(/ /).last}"
512
508
  rescue NameError => e # 1.8 exception
513
509
  raise e unless e.name == sym
@@ -606,12 +602,12 @@ module Minitest
606
602
 
607
603
  def exception_details e, msg
608
604
  [
609
- "#{msg}",
610
- "Class: <#{e.class}>",
611
- "Message: <#{e.message.inspect}>",
612
- "---Backtrace---",
613
- "#{Minitest.filter_backtrace(e.backtrace).join("\n")}",
614
- "---------------",
605
+ msg,
606
+ "Class: <#{e.class}>",
607
+ "Message: <#{e.message.inspect}>",
608
+ "---Backtrace---",
609
+ Minitest.filter_backtrace(e.backtrace),
610
+ "---------------",
615
611
  ].join "\n"
616
612
  end
617
613
 
@@ -620,7 +616,7 @@ module Minitest
620
616
  # you to put time-bombs in your tests if you need to keep
621
617
  # something around until a later date lest you forget about it.
622
618
 
623
- def fail_after y,m,d,msg
619
+ def fail_after y, m, d, msg
624
620
  flunk msg if Time.now > Time.local(y, m, d)
625
621
  end
626
622
 
@@ -654,7 +650,7 @@ module Minitest
654
650
  # Fails if +test+ is truthy.
655
651
 
656
652
  def refute test, msg = nil
657
- msg ||= message { "Expected #{mu_pp(test)} to not be truthy" }
653
+ msg ||= message { "Expected #{mu_pp test} to not be truthy" }
658
654
  assert !test, msg
659
655
  end
660
656
 
@@ -662,7 +658,7 @@ module Minitest
662
658
  # Fails if +obj+ is empty.
663
659
 
664
660
  def refute_empty obj, msg = nil
665
- msg = message(msg) { "Expected #{mu_pp(obj)} to not be empty" }
661
+ msg = message(msg) { "Expected #{mu_pp obj} to not be empty" }
666
662
  assert_respond_to obj, :empty?
667
663
  refute obj.empty?, msg
668
664
  end
@@ -674,7 +670,7 @@ module Minitest
674
670
 
675
671
  def refute_equal exp, act, msg = nil
676
672
  msg = message(msg) {
677
- "Expected #{mu_pp(act)} to not be equal to #{mu_pp(exp)}"
673
+ "Expected #{mu_pp act} to not be equal to #{mu_pp exp}"
678
674
  }
679
675
  refute exp == act, msg
680
676
  end
@@ -705,7 +701,7 @@ module Minitest
705
701
 
706
702
  def refute_includes collection, obj, msg = nil
707
703
  msg = message(msg) {
708
- "Expected #{mu_pp(collection)} to not include #{mu_pp(obj)}"
704
+ "Expected #{mu_pp collection} to not include #{mu_pp obj}"
709
705
  }
710
706
  assert_respond_to collection, :include?
711
707
  refute collection.include?(obj), msg
@@ -716,7 +712,7 @@ module Minitest
716
712
 
717
713
  def refute_instance_of cls, obj, msg = nil
718
714
  msg = message(msg) {
719
- "Expected #{mu_pp(obj)} to not be an instance of #{cls}"
715
+ "Expected #{mu_pp obj} to not be an instance of #{cls}"
720
716
  }
721
717
  refute obj.instance_of?(cls), msg
722
718
  end
@@ -725,7 +721,7 @@ module Minitest
725
721
  # Fails if +obj+ is a kind of +cls+.
726
722
 
727
723
  def refute_kind_of cls, obj, msg = nil
728
- msg = message(msg) { "Expected #{mu_pp(obj)} to not be a kind of #{cls}" }
724
+ msg = message(msg) { "Expected #{mu_pp obj} to not be a kind of #{cls}" }
729
725
  refute obj.kind_of?(cls), msg
730
726
  end
731
727
 
@@ -734,7 +730,7 @@ module Minitest
734
730
 
735
731
  def refute_match matcher, obj, msg = nil
736
732
  msg = message(msg) { "Expected #{mu_pp matcher} to not match #{mu_pp obj}" }
737
- assert_respond_to matcher, :"=~"
733
+ assert_respond_to matcher, :=~
738
734
  matcher = Regexp.new Regexp.escape matcher if String === matcher
739
735
  refute matcher =~ obj, msg
740
736
  end
@@ -743,7 +739,7 @@ module Minitest
743
739
  # Fails if +obj+ is nil.
744
740
 
745
741
  def refute_nil obj, msg = nil
746
- msg = message(msg) { "Expected #{mu_pp(obj)} to not be nil" }
742
+ msg = message(msg) { "Expected #{mu_pp obj} to not be nil" }
747
743
  refute obj.nil?, msg
748
744
  end
749
745
 
@@ -765,7 +761,7 @@ module Minitest
765
761
 
766
762
  begin
767
763
  yield
768
- flunk("NoMatchingPatternError expected, but nothing was raised.")
764
+ flunk "NoMatchingPatternError expected, but nothing was raised."
769
765
  rescue NoMatchingPatternError
770
766
  pass
771
767
  end
@@ -779,7 +775,7 @@ module Minitest
779
775
 
780
776
  def refute_operator o1, op, o2 = UNDEFINED, msg = nil
781
777
  return refute_predicate o1, op, msg if UNDEFINED == o2
782
- msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op} #{mu_pp(o2)}" }
778
+ msg = message(msg) { "Expected #{mu_pp o1} to not be #{op} #{mu_pp o2}" }
783
779
  refute o1.__send__(op, o2), msg
784
780
  end
785
781
 
@@ -801,17 +797,18 @@ module Minitest
801
797
  # str.wont_be :empty?
802
798
 
803
799
  def refute_predicate o1, op, msg = nil
804
- msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op}" }
800
+ msg = message(msg) { "Expected #{mu_pp o1} to not be #{op}" }
805
801
  refute o1.__send__(op), msg
806
802
  end
807
803
 
808
804
  ##
809
805
  # Fails if +obj+ responds to the message +meth+.
806
+ # include_all defaults to false to match Object#respond_to?
810
807
 
811
- def refute_respond_to obj, meth, msg = nil
812
- msg = message(msg) { "Expected #{mu_pp(obj)} to not respond to #{meth}" }
808
+ def refute_respond_to obj, meth, msg = nil, include_all: false
809
+ msg = message(msg) { "Expected #{mu_pp obj} to not respond to #{meth}" }
813
810
 
814
- refute obj.respond_to?(meth), msg
811
+ refute obj.respond_to?(meth, include_all), msg
815
812
  end
816
813
 
817
814
  ##
@@ -830,10 +827,10 @@ module Minitest
830
827
  # gets listed at the end of the run but doesn't cause a failure
831
828
  # exit code.
832
829
 
833
- def skip msg = nil, bt = caller
830
+ def skip msg = nil, _ignored = nil
834
831
  msg ||= "Skipped, no message given"
835
832
  @skip = true
836
- raise Minitest::Skip, msg, bt
833
+ raise Minitest::Skip, msg
837
834
  end
838
835
 
839
836
  ##
@@ -842,9 +839,9 @@ module Minitest
842
839
  # date, but still holds you accountable and prevents you from
843
840
  # forgetting it.
844
841
 
845
- def skip_until y,m,d,msg
842
+ def skip_until y, m, d, msg
846
843
  skip msg if Time.now < Time.local(y, m, d)
847
- where = caller.first.rpartition(':in').reject(&:empty?).first
844
+ where = caller(1..1).first.rpartition(":in").reject(&:empty?).first
848
845
  warn "Stale skip_until %p at %s" % [msg, where]
849
846
  end
850
847
 
@@ -1,10 +1,3 @@
1
- begin
2
- require "rubygems"
3
- gem "minitest"
4
- rescue Gem::LoadError
5
- # do nothing
6
- end
7
-
8
1
  require "minitest"
9
2
  require "minitest/spec"
10
3
  require "minitest/mock"
@@ -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
@@ -0,0 +1,16 @@
1
+ require "minitest"
2
+
3
+ ARGV << "--no-plugins"
4
+
5
+ module Minitest
6
+ ##
7
+ # Manually load plugins by name.
8
+
9
+ def self.load *names
10
+ names.each do |name|
11
+ require "minitest/#{name}_plugin"
12
+
13
+ self.extensions << name.to_s
14
+ end
15
+ end
16
+ end