minitest 5.19.0 → 5.21.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 90d1006243ab84a197a234948e0256bba3cbecbfb1d5d62d55b44ed5422d7eed
4
- data.tar.gz: 2b526508669eab5c8578c2075fe8a8a83f1434a609c09667888020142e9326b7
3
+ metadata.gz: ab5059d07c7a9fccdf48a857873a8bb8ee83a4658cbcf058a60d40081f088566
4
+ data.tar.gz: c951b2d9a6e2fa9877b87da3fb648bbcd1adb9f1fac23996335d435aa0822a73
5
5
  SHA512:
6
- metadata.gz: 6614896f10af7da66d1327f6ba5e0565458df8567d5687dddf02ee91dc3ece9332d7ffb706c9a3b093deaaec13f8ddf8f017d5f90ba8d18975bb6ebcb8a313d0
7
- data.tar.gz: eff4fefb8a32661c3e0fdf80a7b3c4cfc81f6e9dcd160a40aef3e49e6d82cf1c5b6bff92fc0faaf8dab6334049c11f54e18d95a745c82e8aecfb3533ed7b3194
6
+ metadata.gz: 7f70fa661966bfee20ad47816cb0013fa116bb496bb7684cfb180310e948bdb430b4b4279dde1d5a2bfec13fc337f7c11b4d66d8505ab5f78a5f79c48ea1c87f
7
+ data.tar.gz: e40637bc164f3b9ecd6928f5169203fafac15741dba032665a39deda4b4b48a4589fb7a429a6d4eeefa39f31f6ef967d79b0673dd4b4692185447e460c60c970
checksums.yaml.gz.sig CHANGED
Binary file
data/History.rdoc CHANGED
@@ -1,9 +1,35 @@
1
+ === 5.21.0 / 2024-01-11
2
+
3
+ * 10 minor enhancements:
4
+
5
+ * Add include_all kw arg to assert_respond_to and refute_respond_to.
6
+ * Added --quiet flag to skip ProgressReporter (prints the dots). Minor speedup.
7
+ * Added Minitest::Compress#compress and added it to UnexpectedError.
8
+ * Added ability to initialize BacktraceFilter w/ custom regexp.
9
+ * Filter failure backtraces using backtrace_filter before calculating location. (thomasmarshall)
10
+ * Make BacktraceFilter#filter compatible with locations (still compares strings).
11
+ * Optimized Assertion#location ~30%.
12
+ * Output relative paths for all failures/errors/backtraces.
13
+ * Refactored location information in assertions, now using locations.
14
+ * Removed thread and mutex_m dependencies. (hsbt, eregon)
15
+
16
+ * 2 bug fixes:
17
+
18
+ * Drop undocumented bt arg in #skip. Dunno why that ever happened, prolly for testing?
19
+ * Fix mock to work with ruby debugger enabled. (keithlayne)
20
+
21
+ === 5.20.0 / 2023-09-06
22
+
23
+ * 1 minor enhancement:
24
+
25
+ * Optionally allow autorun exit hook to remain active in forked child. (casperisfine)
26
+
1
27
  === 5.19.0 / 2023-07-26
2
28
 
3
29
  * 2 minor enhancements:
4
30
 
5
31
  * Add metadata lazy accessor to Runnable / Result. (matteeyah)
6
- * Only load minitest/unit (aka ancient MiniTest compatibility layer) if ENV["MT_COMPAT"]
32
+ * Only load minitest/unit (aka ancient MiniTest compatibility layer) if \ENV[\"MT_COMPAT\"]
7
33
 
8
34
  * 1 bug fix:
9
35
 
@@ -14,7 +40,7 @@
14
40
  * 3 bug fixes:
15
41
 
16
42
  * Avoid extra string allocations when filtering tests. (tenderlove)
17
- * Only mention deprecated ENV['N'] if it is an integer string.
43
+ * Only mention deprecated \ENV[\'N\'] if it is an integer string.
18
44
  * Push up test_order to Minitest::Runnable to fix minitest/hell. (koic)
19
45
 
20
46
  === 5.18.0 / 2023-03-04
@@ -208,7 +234,7 @@
208
234
 
209
235
  * 3 bug fixes:
210
236
 
211
- * Check `option[:filter]` klass before match. Fixes 2.6 warning. (y-yagi)
237
+ * Check \option[:filter] klass before match. Fixes 2.6 warning. (y-yagi)
212
238
  * Fixed Assertions#diff from recalculating if set to nil
213
239
  * Fixed spec section of readme to not use deprecated global expectations. (CheezItMan)
214
240
 
data/Manifest.txt CHANGED
@@ -9,6 +9,7 @@ lib/minitest.rb
9
9
  lib/minitest/assertions.rb
10
10
  lib/minitest/autorun.rb
11
11
  lib/minitest/benchmark.rb
12
+ lib/minitest/compress.rb
12
13
  lib/minitest/expectations.rb
13
14
  lib/minitest/hell.rb
14
15
  lib/minitest/mock.rb
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
 
@@ -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_locations).first
203
+ [where.path, where.lineno].join ":"
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
- 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."
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
- where = Minitest.filter_backtrace(caller).first
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, bt = caller
835
+ def skip msg = nil, _ignored = nil
834
836
  msg ||= "Skipped, no message given"
835
837
  @skip = true
836
- raise Minitest::Skip, msg, bt
838
+ raise Minitest::Skip, msg
837
839
  end
838
840
 
839
841
  ##
@@ -0,0 +1,81 @@
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
+ [
68
+ " +->> #{n} cycles of #{lines.size} lines:",
69
+ *lines.map { |s| " | #{s}" },
70
+ " +-<<",
71
+ ]
72
+ else
73
+ lines
74
+ end
75
+ }
76
+ end
77
+
78
+ ary
79
+ end
80
+ end
81
+ 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 = %w[
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.to_s) || 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/spec.rb CHANGED
@@ -13,8 +13,8 @@ class Module # :nodoc:
13
13
  # warn "%-22p -> %p %p" % [meth, new_name, dont_flip]
14
14
  self.class_eval <<-EOM, __FILE__, __LINE__ + 1
15
15
  def #{new_name} *args
16
- where = Minitest.filter_backtrace(caller).first
17
- where = where.split(/:in /, 2).first # clean up noise
16
+ where = Minitest.filter_backtrace(caller_locations).first
17
+ where = [where.path, where.lineno].join ":"
18
18
  Kernel.warn "DEPRECATED: global use of #{new_name} from #\{where}. Use #{target_obj}.#{new_name} instead. This will fail in Minitest 6."
19
19
  Minitest::Expectation.new(self, Minitest::Spec.current).#{new_name}(*args)
20
20
  end
@@ -288,7 +288,6 @@ end
288
288
 
289
289
  class Integer # :nodoc:
290
290
  def threads_do(jobs) # :nodoc:
291
- require "thread"
292
291
  q = Work.new jobs
293
292
 
294
293
  self.times.map {
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.19.0" # :nodoc:
12
+ VERSION = "5.21.0" # :nodoc:
13
13
 
14
14
  @@installed_at_exit ||= false
15
15
  @@after_run = []
@@ -60,6 +60,9 @@ module Minitest
60
60
  cattr_accessor :info_signal
61
61
  self.info_signal = "INFO"
62
62
 
63
+ cattr_accessor :allow_fork
64
+ self.allow_fork = false
65
+
63
66
  ##
64
67
  # Registers Minitest to run at process exit
65
68
 
@@ -75,7 +78,7 @@ module Minitest
75
78
 
76
79
  pid = Process.pid
77
80
  at_exit {
78
- next if Process.pid != pid
81
+ next if !Minitest.allow_fork && Process.pid != pid
79
82
  @@after_run.reverse_each(&:call)
80
83
  exit exit_code || false
81
84
  }
@@ -147,7 +150,7 @@ module Minitest
147
150
 
148
151
  reporter = CompositeReporter.new
149
152
  reporter << SummaryReporter.new(options[:io], options)
150
- reporter << ProgressReporter.new(options[:io], options)
153
+ reporter << ProgressReporter.new(options[:io], options) unless options[:quiet]
151
154
 
152
155
  self.reporter = reporter # this makes it available to plugins
153
156
  self.init_plugins options
@@ -209,6 +212,10 @@ module Minitest
209
212
  options[:verbose] = true
210
213
  end
211
214
 
215
+ opts.on "-q", "--quiet", "Quiet. Show no progress processing files." do
216
+ options[:quiet] = true
217
+ end
218
+
212
219
  opts.on "--show-skips", "Show skipped at the end of run." do
213
220
  options[:show_skips] = true
214
221
  end
@@ -522,12 +529,14 @@ module Minitest
522
529
  not self.failure
523
530
  end
524
531
 
532
+ BASE_DIR = "#{Dir.pwd}/" # :nodoc:
533
+
525
534
  ##
526
535
  # The location identifier of this test. Depends on a method
527
536
  # existing called class_name.
528
537
 
529
538
  def location
530
- loc = " [#{self.failure.location}]" unless passed? or error?
539
+ loc = " [#{self.failure.location.delete_prefix BASE_DIR}]" unless passed? or error?
531
540
  "#{self.class_name}##{self.name}#{loc}"
532
541
  end
533
542
 
@@ -616,7 +625,10 @@ module Minitest
616
625
  # you want. Go nuts.
617
626
 
618
627
  class AbstractReporter
619
- include Mutex_m
628
+
629
+ def initialize # :nodoc:
630
+ @mutex = Mutex.new
631
+ end
620
632
 
621
633
  ##
622
634
  # Starts reporting on the run.
@@ -652,6 +664,10 @@ module Minitest
652
664
  def passed?
653
665
  true
654
666
  end
667
+
668
+ def synchronize(&block) # :nodoc:
669
+ @mutex.synchronize(&block)
670
+ end
655
671
  end
656
672
 
657
673
  class Reporter < AbstractReporter # :nodoc:
@@ -825,7 +841,7 @@ module Minitest
825
841
  io.puts "# Running:"
826
842
  io.puts
827
843
 
828
- self.sync = io.respond_to? :"sync=" # stupid emacs
844
+ self.sync = io.respond_to? :"sync="
829
845
  self.old_sync, io.sync = io.sync, true if self.sync
830
846
  end
831
847
 
@@ -933,6 +949,8 @@ module Minitest
933
949
  # Represents run failures.
934
950
 
935
951
  class Assertion < Exception
952
+ RE = /in .(?:assert|refute|flunk|pass|fail|raise|must|wont)/ # :nodoc:
953
+
936
954
  def error # :nodoc:
937
955
  self
938
956
  end
@@ -941,12 +959,10 @@ module Minitest
941
959
  # Where was this run before an assertion was raised?
942
960
 
943
961
  def location
944
- last_before_assertion = ""
945
- self.backtrace.reverse_each do |s|
946
- break if s =~ /in .(assert|refute|flunk|pass|fail|raise|must|wont)/
947
- last_before_assertion = s
948
- end
949
- last_before_assertion.sub(/:in .*$/, "")
962
+ bt = Minitest.filter_backtrace self.backtrace
963
+ idx = bt.rindex { |s| s.match? RE } || -1 # fall back to first item
964
+
965
+ bt[idx+1].sub(/:in .*$/, "")
950
966
  end
951
967
 
952
968
  def result_code # :nodoc:
@@ -971,11 +987,21 @@ module Minitest
971
987
  # Assertion wrapping an unexpected error that was raised during a run.
972
988
 
973
989
  class UnexpectedError < Assertion
990
+ include Minitest::Compress
991
+
974
992
  # TODO: figure out how to use `cause` instead
975
993
  attr_accessor :error # :nodoc:
976
994
 
977
995
  def initialize error # :nodoc:
978
996
  super "Unexpected exception"
997
+
998
+ if SystemStackError === error then
999
+ bt = error.backtrace
1000
+ new_bt = compress bt
1001
+ error = error.exception "#{bt.size} -> #{new_bt.size}"
1002
+ error.set_backtrace new_bt
1003
+ end
1004
+
979
1005
  self.error = error
980
1006
  end
981
1007
 
@@ -983,8 +1009,11 @@ module Minitest
983
1009
  self.error.backtrace
984
1010
  end
985
1011
 
1012
+ BASE_RE = %r%#{Dir.pwd}/% # :nodoc:
1013
+
986
1014
  def message # :nodoc:
987
- bt = Minitest.filter_backtrace(self.backtrace).join "\n "
1015
+ bt = Minitest.filter_backtrace(self.backtrace).join("\n ")
1016
+ .gsub(BASE_RE, "")
988
1017
  "#{self.error.class}: #{self.error.message}\n #{bt}"
989
1018
  end
990
1019
 
@@ -1068,6 +1097,12 @@ module Minitest
1068
1097
 
1069
1098
  MT_RE = %r%lib/minitest% #:nodoc:
1070
1099
 
1100
+ attr_accessor :regexp
1101
+
1102
+ def initialize regexp = MT_RE
1103
+ self.regexp = regexp
1104
+ end
1105
+
1071
1106
  ##
1072
1107
  # Filter +bt+ to something useful. Returns the whole thing if
1073
1108
  # $DEBUG (ruby) or $MT_DEBUG (env).
@@ -1077,9 +1112,9 @@ module Minitest
1077
1112
 
1078
1113
  return bt.dup if $DEBUG || ENV["MT_DEBUG"]
1079
1114
 
1080
- new_bt = bt.take_while { |line| line !~ MT_RE }
1081
- new_bt = bt.select { |line| line !~ MT_RE } if new_bt.empty?
1082
- new_bt = bt.dup if new_bt.empty?
1115
+ new_bt = bt.take_while { |line| line.to_s !~ regexp }
1116
+ new_bt = bt.select { |line| line.to_s !~ regexp } if new_bt.empty?
1117
+ new_bt = bt.dup if new_bt.empty?
1083
1118
 
1084
1119
  new_bt
1085
1120
  end
@@ -8,16 +8,17 @@ class Minitest::Test
8
8
  end
9
9
 
10
10
  def with_empty_backtrace_filter
11
- original = Minitest.backtrace_filter
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 = obj
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!(/\[[^\]:]+:\d+\]/, "[FILE:LINE]")
113
- output.gsub!(/^(\s+)[^:]+:\d+:in/, '\1FILE:LINE:in')
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+/, '\1[FILE:LINE]')
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
- # These are test/unit methods. I'm not actually sure why they're still here
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
@@ -1089,17 +1089,27 @@ class TestMinitestUnitTestCase < Minitest::Test
1089
1089
 
1090
1090
  def test_autorun_does_not_affect_fork_success_status
1091
1091
  @assertion_count = 0
1092
- skip "windows doesn't have skip" unless Process.respond_to?(:fork)
1092
+ skip "windows doesn't have fork" unless Process.respond_to?(:fork)
1093
1093
  Process.waitpid(fork {})
1094
1094
  assert_equal true, $?.success?
1095
1095
  end
1096
1096
 
1097
1097
  def test_autorun_does_not_affect_fork_exit_status
1098
1098
  @assertion_count = 0
1099
- skip "windows doesn't have skip" unless Process.respond_to?(:fork)
1099
+ skip "windows doesn't have fork" unless Process.respond_to?(:fork)
1100
1100
  Process.waitpid(fork { exit 42 })
1101
1101
  assert_equal 42, $?.exitstatus
1102
1102
  end
1103
+
1104
+ def test_autorun_optionally_can_affect_fork_exit_status
1105
+ @assertion_count = 0
1106
+ skip "windows doesn't have fork" unless Process.respond_to?(:fork)
1107
+ Minitest.allow_fork = true
1108
+ Process.waitpid(fork { exit 42 })
1109
+ refute_equal 42, $?.exitstatus
1110
+ ensure
1111
+ Minitest.allow_fork = false
1112
+ end
1103
1113
  end
1104
1114
 
1105
1115
  class TestMinitestGuard < Minitest::Test
@@ -1270,3 +1280,98 @@ class TestMinitestUnitRecording < MetaMetaMetaTestCase
1270
1280
  end
1271
1281
  end
1272
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
+ skip "NOOOO!!! but I don't care enough right now."
1363
+
1364
+ assert_compress <<~EXP, %w[ a b c b c a b c b c a b c ]
1365
+ +->> 2 cycles of 5 lines:
1366
+ | a
1367
+ | +->> 2 cycles of 2 lines:
1368
+ | | b
1369
+ | | c
1370
+ | +-<<
1371
+ +-<<
1372
+ a
1373
+ b
1374
+ c
1375
+ EXP
1376
+ end
1377
+ 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.19.0
4
+ version: 5.21.0
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
- MIIDPjCCAiagAwIBAgIBBzANBgkqhkiG9w0BAQsFADBFMRMwEQYDVQQDDApyeWFu
13
+ MIIDPjCCAiagAwIBAgIBCDANBgkqhkiG9w0BAQsFADBFMRMwEQYDVQQDDApyeWFu
14
14
  ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB
15
- GRYDY29tMB4XDTIzMDEwMTA3NTExN1oXDTI0MDEwMTA3NTExN1owRTETMBEGA1UE
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
- AQAkg3y+PBnBAPWdxxITm5sPHqdWQgSyCpRA20o4LTuWr8BWhSXBkfQNa7cY6fOn
26
- xyM34VPzBFbExv6XOGDfOMFBVaYTHuN9peC/5/umL7kLl+nflXzL2QA7K6LYj5Bg
27
- sM574Onr0dZDM6Vn69bzQ7rBIFDfK/OhlPzqKZad4nsdcsVH8ODCiT+ATMIZyz5K
28
- WCnNtqlyiWXI8tdTpahDgcUwfcN/oN7v4K8iU5IbLJX6HQ5DKgmKjfb6XyMth16k
29
- ROfWo9Uyp8ba/j9eVG14KkYRaLydAY1MNQk2yd3R5CGfeOpD1kttxjoypoUJ2dOG
30
- nsNBRuQJ1UfiCG97a6DNm+Fr
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: 2023-07-26 00:00:00.000000000 Z
32
+ date: 2024-01-11 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.0'
60
+ version: '4.1'
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.0'
67
+ version: '4.1'
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.4.10
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