minitest 5.22.3 → 5.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/minitest.rb CHANGED
@@ -9,7 +9,7 @@ require_relative "minitest/compress"
9
9
  # :include: README.rdoc
10
10
 
11
11
  module Minitest
12
- VERSION = "5.22.2" # :nodoc:
12
+ VERSION = "5.25.1" # :nodoc:
13
13
 
14
14
  @@installed_at_exit ||= false
15
15
  @@after_run = []
@@ -67,9 +67,8 @@ module Minitest
67
67
  # Registers Minitest to run at process exit
68
68
 
69
69
  def self.autorun
70
- if Object.const_defined?(:Warning) && Warning.respond_to?(:[]=)
71
- Warning[:deprecated] = true
72
- end
70
+ Warning[:deprecated] = true if
71
+ Object.const_defined?(:Warning) && Warning.respond_to?(:[]=)
73
72
 
74
73
  at_exit {
75
74
  next if $! and not ($!.kind_of? SystemExit and $!.success?)
@@ -98,20 +97,19 @@ module Minitest
98
97
  @@after_run << block
99
98
  end
100
99
 
101
- def self.init_plugins options # :nodoc:
102
- self.extensions.each do |name|
103
- msg = "plugin_#{name}_init"
104
- send msg, options if self.respond_to? msg
105
- end
100
+ ##
101
+ # Register a plugin to be used. Does NOT require / load it.
102
+
103
+ def self.register_plugin name_or_mod
104
+ self.extensions << name_or_mod
105
+ nil
106
106
  end
107
107
 
108
108
  def self.load_plugins # :nodoc:
109
- return unless self.extensions.empty?
109
+ return unless defined? Gem
110
110
 
111
111
  seen = {}
112
112
 
113
- require "rubygems" unless defined? Gem
114
-
115
113
  Gem.find_files("minitest/*_plugin.rb").each do |plugin_path|
116
114
  name = File.basename plugin_path, "_plugin.rb"
117
115
 
@@ -123,6 +121,130 @@ module Minitest
123
121
  end
124
122
  end
125
123
 
124
+ def self.init_plugins options # :nodoc:
125
+ self.extensions.each do |mod_or_meth|
126
+ case mod_or_meth
127
+ when Symbol, String then
128
+ name = mod_or_meth
129
+ msg = "plugin_#{name}_init"
130
+ next unless self.respond_to? msg
131
+ send msg, options
132
+ when Module then
133
+ recv = mod_or_meth
134
+ next unless recv.respond_to? :minitest_plugin_init
135
+ recv.minitest_plugin_init options
136
+ else
137
+ raise ArgumentError, "plugin is %p, but it must be a symbol, string or module" % [mod_or_meth]
138
+ end
139
+ end
140
+ end
141
+
142
+ def self.process_args args = [] # :nodoc:
143
+ options = {
144
+ :io => $stdout,
145
+ }
146
+ orig_args = args.dup
147
+
148
+ OptionParser.new do |opts|
149
+ opts.banner = "minitest options:"
150
+ opts.version = Minitest::VERSION
151
+
152
+ opts.on "-h", "--help", "Display this help." do
153
+ puts opts
154
+ exit
155
+ end
156
+
157
+ opts.on "--no-plugins", "Bypass minitest plugin auto-loading (or set $MT_NO_PLUGINS)."
158
+
159
+ desc = "Sets random seed. Also via env. Eg: SEED=n rake"
160
+ opts.on "-s", "--seed SEED", Integer, desc do |m|
161
+ options[:seed] = m.to_i
162
+ end
163
+
164
+ opts.on "-v", "--verbose", "Verbose. Show progress processing files." do
165
+ options[:verbose] = true
166
+ end
167
+
168
+ opts.on "-q", "--quiet", "Quiet. Show no progress processing files." do
169
+ options[:quiet] = true
170
+ end
171
+
172
+ opts.on "--show-skips", "Show skipped at the end of run." do
173
+ options[:show_skips] = true
174
+ end
175
+
176
+ opts.on "-n", "--name PATTERN", "Filter run on /regexp/ or string." do |a|
177
+ options[:filter] = a
178
+ end
179
+
180
+ opts.on "-e", "--exclude PATTERN", "Exclude /regexp/ or string from run." do |a|
181
+ options[:exclude] = a
182
+ end
183
+
184
+ opts.on "-S", "--skip CODES", String, "Skip reporting of certain types of results (eg E)." do |s|
185
+ options[:skip] = s.chars.to_a
186
+ end
187
+
188
+ ruby27plus = ::Warning.respond_to? :[]=
189
+
190
+ opts.on "-W[error]", String, "Turn Ruby warnings into errors" do |s|
191
+ options[:Werror] = true
192
+ case s
193
+ when "error", "all", nil then
194
+ require "minitest/error_on_warning"
195
+ $VERBOSE = true
196
+ ::Warning[:deprecated] = true if ruby27plus
197
+ else
198
+ ::Warning[s.to_sym] = true if ruby27plus # check validity of category
199
+ end
200
+ end
201
+
202
+ unless extensions.empty?
203
+ opts.separator ""
204
+ opts.separator "Known extensions: #{extensions.join ", "}"
205
+
206
+ extensions.each do |mod_or_meth|
207
+ case mod_or_meth
208
+ when Symbol, String then
209
+ meth = mod_or_meth
210
+ msg = "plugin_#{meth}_options"
211
+ send msg, opts, options if respond_to? msg
212
+ when Module
213
+ recv = mod_or_meth
214
+ next unless recv.respond_to? :minitest_plugin_options
215
+ recv.minitest_plugin_options opts, options
216
+ else
217
+ raise ArgumentError, "plugin is %p, but it must be a symbol, string or module" % [mod_or_meth]
218
+ end
219
+ end
220
+ end
221
+
222
+ begin
223
+ opts.parse! args
224
+ rescue OptionParser::InvalidOption => e
225
+ puts
226
+ puts e
227
+ puts
228
+ puts opts
229
+ exit 1
230
+ end
231
+
232
+ orig_args -= args
233
+ end
234
+
235
+ unless options[:seed] then
236
+ srand
237
+ options[:seed] = (ENV["SEED"] || srand).to_i % 0xFFFF
238
+ orig_args << "--seed" << options[:seed].to_s
239
+ end
240
+
241
+ options[:args] = orig_args.map { |s|
242
+ s.match?(/[\s|&<>$()]/) ? s.inspect : s
243
+ }.join " "
244
+
245
+ options
246
+ end
247
+
126
248
  ##
127
249
  # This is the top-level run method. Everything starts from here. It
128
250
  # tells each Runnable sub-class to run, and each of those are
@@ -132,6 +254,9 @@ module Minitest
132
254
  #
133
255
  # Minitest.autorun
134
256
  # Minitest.run(args)
257
+ # Minitest.load_plugins
258
+ # Minitest.process_args
259
+ # Minitest.init_plugins
135
260
  # Minitest.__run(reporter, options)
136
261
  # Runnable.runnables.each
137
262
  # runnable_klass.run(reporter, options)
@@ -156,7 +281,7 @@ module Minitest
156
281
  self.init_plugins options
157
282
  self.reporter = nil # runnables shouldn't depend on the reporter, ever
158
283
 
159
- self.parallel_executor.start if parallel_executor.respond_to?(:start)
284
+ self.parallel_executor.start if parallel_executor.respond_to? :start
160
285
  reporter.start
161
286
  begin
162
287
  __run reporter, options
@@ -167,10 +292,10 @@ module Minitest
167
292
 
168
293
  # might have been removed/replaced during init_plugins:
169
294
  summary = reporter.reporters.grep(SummaryReporter).first
170
- return empty_run! options if summary && summary.count == 0
171
295
 
172
296
  reporter.report
173
297
 
298
+ return empty_run! options if summary && summary.count == 0
174
299
  reporter.passed?
175
300
  end
176
301
 
@@ -207,88 +332,6 @@ module Minitest
207
332
  parallel.map { |suite| suite.run reporter, options }
208
333
  end
209
334
 
210
- def self.process_args args = [] # :nodoc:
211
- options = {
212
- :io => $stdout,
213
- }
214
- orig_args = args.dup
215
-
216
- OptionParser.new do |opts|
217
- opts.banner = "minitest options:"
218
- opts.version = Minitest::VERSION
219
-
220
- opts.on "-h", "--help", "Display this help." do
221
- puts opts
222
- exit
223
- end
224
-
225
- opts.on "--no-plugins", "Bypass minitest plugin auto-loading (or set $MT_NO_PLUGINS)."
226
-
227
- desc = "Sets random seed. Also via env. Eg: SEED=n rake"
228
- opts.on "-s", "--seed SEED", Integer, desc do |m|
229
- options[:seed] = m.to_i
230
- end
231
-
232
- opts.on "-v", "--verbose", "Verbose. Show progress processing files." do
233
- options[:verbose] = true
234
- end
235
-
236
- opts.on "-q", "--quiet", "Quiet. Show no progress processing files." do
237
- options[:quiet] = true
238
- end
239
-
240
- opts.on "--show-skips", "Show skipped at the end of run." do
241
- options[:show_skips] = true
242
- end
243
-
244
- opts.on "-n", "--name PATTERN", "Filter run on /regexp/ or string." do |a|
245
- options[:filter] = a
246
- end
247
-
248
- opts.on "-e", "--exclude PATTERN", "Exclude /regexp/ or string from run." do |a|
249
- options[:exclude] = a
250
- end
251
-
252
- opts.on "-S", "--skip CODES", String, "Skip reporting of certain types of results (eg E)." do |s|
253
- options[:skip] = s.chars.to_a
254
- end
255
-
256
- unless extensions.empty?
257
- opts.separator ""
258
- opts.separator "Known extensions: #{extensions.join(", ")}"
259
-
260
- extensions.each do |meth|
261
- msg = "plugin_#{meth}_options"
262
- send msg, opts, options if self.respond_to?(msg)
263
- end
264
- end
265
-
266
- begin
267
- opts.parse! args
268
- rescue OptionParser::InvalidOption => e
269
- puts
270
- puts e
271
- puts
272
- puts opts
273
- exit 1
274
- end
275
-
276
- orig_args -= args
277
- end
278
-
279
- unless options[:seed] then
280
- srand
281
- options[:seed] = (ENV["SEED"] || srand).to_i % 0xFFFF
282
- orig_args << "--seed" << options[:seed].to_s
283
- end
284
-
285
- options[:args] = orig_args.map { |s|
286
- s =~ /[\s|&<>$()]/ ? s.inspect : s
287
- }.join " "
288
-
289
- options
290
- end
291
-
292
335
  def self.filter_backtrace bt # :nodoc:
293
336
  result = backtrace_filter.filter bt
294
337
  result = bt.dup if result.empty?
@@ -362,8 +405,8 @@ module Minitest
362
405
  pos = options[:filter]
363
406
  neg = options[:exclude]
364
407
 
365
- pos = Regexp.new $1 if pos.is_a?(String) && pos =~ %r%/(.*)/%
366
- neg = Regexp.new $1 if neg.is_a?(String) && neg =~ %r%/(.*)/%
408
+ pos = Regexp.new $1 if pos.kind_of?(String) && pos =~ %r%/(.*)/%
409
+ neg = Regexp.new $1 if neg.kind_of?(String) && neg =~ %r%/(.*)/%
367
410
 
368
411
  filtered_methods = self.runnable_methods
369
412
  .select { |m| !pos || pos === m || pos === "#{self}##{m}" }
@@ -371,8 +414,22 @@ module Minitest
371
414
 
372
415
  return if filtered_methods.empty?
373
416
 
417
+ t0 = name = nil
418
+
419
+ @_info_handler = lambda do
420
+ unless reporter.passed? then
421
+ warn "Current results:"
422
+ warn reporter.reporters.grep(SummaryReporter).first
423
+ end
424
+
425
+ warn "Current: %s#%s %.2fs" % [self, name, Minitest.clock_time - t0]
426
+ end
427
+
374
428
  with_info_handler reporter do
375
429
  filtered_methods.each do |method_name|
430
+ name = method_name
431
+ t0 = Minitest.clock_time
432
+
376
433
  run_one_method self, method_name, reporter
377
434
  end
378
435
  end
@@ -398,16 +455,7 @@ module Minitest
398
455
  end
399
456
 
400
457
  def self.with_info_handler reporter, &block # :nodoc:
401
- handler = lambda do
402
- unless reporter.passed? then
403
- warn "Current results:"
404
- warn ""
405
- warn reporter.reporters.first
406
- warn ""
407
- end
408
- end
409
-
410
- on_signal ::Minitest.info_signal, handler, &block
458
+ on_signal ::Minitest.info_signal, @_info_handler, &block
411
459
  end
412
460
 
413
461
  SIGNALS = Signal.list # :nodoc:
@@ -445,7 +493,7 @@ module Minitest
445
493
  def marshal_dump # :nodoc:
446
494
  unless @@marshal_dump_warned then
447
495
  warn ["Minitest::Runnable#marshal_dump is deprecated.",
448
- "You might be violating internals. From", caller.first].join " "
496
+ "You might be violating internals. From", caller(1..1).first].join " "
449
497
  @@marshal_dump_warned = true
450
498
  end
451
499
 
@@ -573,7 +621,7 @@ module Minitest
573
621
  # Did this run error?
574
622
 
575
623
  def error?
576
- self.failures.any? { |f| UnexpectedError === f }
624
+ self.failures.any? UnexpectedError
577
625
  end
578
626
  end
579
627
 
@@ -676,7 +724,7 @@ module Minitest
676
724
  true
677
725
  end
678
726
 
679
- def synchronize(&block) # :nodoc:
727
+ def synchronize &block # :nodoc:
680
728
  @mutex.synchronize(&block)
681
729
  end
682
730
  end
@@ -708,11 +756,11 @@ module Minitest
708
756
  # own.
709
757
 
710
758
  class ProgressReporter < Reporter
711
- def prerecord klass, name #:nodoc:
712
- if options[:verbose] then
713
- io.print "%s#%s = " % [klass.name, name]
714
- io.flush
715
- end
759
+ def prerecord klass, name # :nodoc:
760
+ return unless options[:verbose]
761
+
762
+ io.print "%s#%s = " % [klass.name, name]
763
+ io.flush
716
764
  end
717
765
 
718
766
  def record result # :nodoc:
@@ -782,6 +830,11 @@ module Minitest
782
830
 
783
831
  attr_accessor :errors
784
832
 
833
+ ##
834
+ # Total number of tests that warned.
835
+
836
+ attr_accessor :warnings
837
+
785
838
  ##
786
839
  # Total number of tests that where skipped.
787
840
 
@@ -797,6 +850,7 @@ module Minitest
797
850
  self.total_time = nil
798
851
  self.failures = nil
799
852
  self.errors = nil
853
+ self.warnings = nil
800
854
  self.skips = nil
801
855
  end
802
856
 
@@ -825,6 +879,7 @@ module Minitest
825
879
  self.total_time = Minitest.clock_time - start_time
826
880
  self.failures = aggregate[Assertion].size
827
881
  self.errors = aggregate[UnexpectedError].size
882
+ self.warnings = aggregate[UnexpectedWarning].size
828
883
  self.skips = aggregate[Skip].size
829
884
  end
830
885
  end
@@ -839,10 +894,8 @@ module Minitest
839
894
  # own.
840
895
 
841
896
  class SummaryReporter < StatisticsReporter
842
- # :stopdoc:
843
- attr_accessor :sync
844
- attr_accessor :old_sync
845
- # :startdoc:
897
+ attr_accessor :sync # :nodoc:
898
+ attr_accessor :old_sync # :nodoc:
846
899
 
847
900
  def start # :nodoc:
848
901
  super
@@ -890,18 +943,22 @@ module Minitest
890
943
  end
891
944
 
892
945
  def to_s # :nodoc:
893
- aggregated_results(StringIO.new(''.b)).string
946
+ aggregated_results(StringIO.new("".b)).string
894
947
  end
895
948
 
896
949
  def summary # :nodoc:
897
- extra = ""
950
+ extra = []
898
951
 
899
- extra = "\n\nYou have skipped tests. Run with --verbose for details." if
952
+ extra << ", %d warnings" % [warnings] if options[:Werror]
953
+
954
+ extra << "\n\nYou have skipped tests. Run with --verbose for details." if
900
955
  results.any?(&:skipped?) unless
901
- options[:verbose] or options[:show_skips] or ENV["MT_NO_SKIP_MSG"]
956
+ options[:verbose] or
957
+ options[:show_skips] or
958
+ ENV["MT_NO_SKIP_MSG"]
902
959
 
903
960
  "%d runs, %d assertions, %d failures, %d errors, %d skips%s" %
904
- [count, assertions, failures, errors, skips, extra]
961
+ [count, assertions, failures, errors, skips, extra.join]
905
962
  end
906
963
  end
907
964
 
@@ -1034,6 +1091,15 @@ module Minitest
1034
1091
  end
1035
1092
  end
1036
1093
 
1094
+ ##
1095
+ # Assertion raised on warning when running in -Werror mode.
1096
+
1097
+ class UnexpectedWarning < Assertion
1098
+ def result_label # :nodoc:
1099
+ "Warning"
1100
+ end
1101
+ end
1102
+
1037
1103
  ##
1038
1104
  # Provides a simple set of guards that you can use in your tests
1039
1105
  # to skip execution if it is not applicable. These methods are
@@ -1063,7 +1129,7 @@ module Minitest
1063
1129
 
1064
1130
  def maglev? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
1065
1131
  where = Minitest.filter_backtrace(caller).first
1066
- where = where.split(/:in /, 2).first # clean up noise
1132
+ where = where.split(":in ", 2).first # clean up noise
1067
1133
  warn "DEPRECATED: `maglev?` called from #{where}. This will fail in Minitest 6."
1068
1134
  "maglev" == platform
1069
1135
  end
@@ -1072,14 +1138,14 @@ module Minitest
1072
1138
  # Is this running on mri?
1073
1139
 
1074
1140
  def mri? platform = RUBY_DESCRIPTION
1075
- /^ruby/ =~ platform
1141
+ platform.start_with? "ruby"
1076
1142
  end
1077
1143
 
1078
1144
  ##
1079
1145
  # Is this running on macOS?
1080
1146
 
1081
1147
  def osx? platform = RUBY_PLATFORM
1082
- /darwin/ =~ platform
1148
+ platform.include? "darwin"
1083
1149
  end
1084
1150
 
1085
1151
  ##
@@ -1087,7 +1153,7 @@ module Minitest
1087
1153
 
1088
1154
  def rubinius? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
1089
1155
  where = Minitest.filter_backtrace(caller).first
1090
- where = where.split(/:in /, 2).first # clean up noise
1156
+ where = where.split(":in ", 2).first # clean up noise
1091
1157
  warn "DEPRECATED: `rubinius?` called from #{where}. This will fail in Minitest 6."
1092
1158
  "rbx" == platform
1093
1159
  end
@@ -1096,7 +1162,7 @@ module Minitest
1096
1162
  # Is this running on windows?
1097
1163
 
1098
1164
  def windows? platform = RUBY_PLATFORM
1099
- /mswin|mingw/ =~ platform
1165
+ /mswin|mingw/.match? platform
1100
1166
  end
1101
1167
  end
1102
1168
 
@@ -1107,11 +1173,14 @@ module Minitest
1107
1173
 
1108
1174
  class BacktraceFilter
1109
1175
 
1110
- MT_RE = %r%lib/minitest% #:nodoc:
1176
+ MT_RE = %r%lib/minitest|internal:warning% # :nodoc:
1177
+
1178
+ ##
1179
+ # The regular expression to use to filter backtraces. Defaults to +MT_RE+.
1111
1180
 
1112
1181
  attr_accessor :regexp
1113
1182
 
1114
- def initialize regexp = MT_RE
1183
+ def initialize regexp = MT_RE # :nodoc:
1115
1184
  self.regexp = regexp
1116
1185
  end
1117
1186
 
@@ -1124,9 +1193,9 @@ module Minitest
1124
1193
 
1125
1194
  return bt.dup if $DEBUG || ENV["MT_DEBUG"]
1126
1195
 
1127
- new_bt = bt.take_while { |line| line.to_s !~ regexp }
1128
- new_bt = bt.select { |line| line.to_s !~ regexp } if new_bt.empty?
1129
- new_bt = bt.dup if new_bt.empty?
1196
+ new_bt = bt.take_while { |line| !regexp.match? line.to_s }
1197
+ new_bt = bt.select { |line| !regexp.match? line.to_s } if new_bt.empty?
1198
+ new_bt = bt.dup if new_bt.empty?
1130
1199
 
1131
1200
  new_bt
1132
1201
  end
@@ -3,10 +3,6 @@ require "stringio"
3
3
  require "minitest/autorun"
4
4
 
5
5
  class Minitest::Test
6
- def clean s
7
- s.gsub(/^ {6}/, "")
8
- end
9
-
10
6
  def with_empty_backtrace_filter
11
7
  with_backtrace_filter Minitest::BacktraceFilter.new %r%.% do
12
8
  yield
@@ -25,8 +21,20 @@ class Minitest::Test
25
21
  end
26
22
  end
27
23
  end
28
- end
29
24
 
25
+ def error_on_warn?
26
+ defined?(Minitest::ErrorOnWarning)
27
+ end
28
+
29
+ def assert_deprecation re = /DEPRECATED/
30
+ re = // if $-w.nil? # "skip" if running `rake testW0`
31
+ assert_output "", re do
32
+ yield
33
+ end
34
+ rescue Minitest::UnexpectedWarning => e # raised if -Werror was used
35
+ assert_match re, e.message
36
+ end
37
+ end
30
38
 
31
39
  class FakeNamedTest < Minitest::Test
32
40
  @@count = 0
@@ -56,7 +64,7 @@ class MetaMetaMetaTestCase < Minitest::Test
56
64
  def run_tu_with_fresh_reporter flags = %w[--seed 42]
57
65
  options = Minitest.process_args flags
58
66
 
59
- @output = StringIO.new("".encode('UTF-8'))
67
+ @output = StringIO.new(+"")
60
68
 
61
69
  self.reporter = Minitest::CompositeReporter.new
62
70
  reporter << Minitest::SummaryReporter.new(@output, options)
@@ -65,7 +73,7 @@ class MetaMetaMetaTestCase < Minitest::Test
65
73
  with_stderr @output do
66
74
  reporter.start
67
75
 
68
- yield(reporter) if block_given?
76
+ yield reporter if block_given?
69
77
 
70
78
  @tus ||= [@tu]
71
79
  @tus.each do |tu|
@@ -83,8 +91,8 @@ class MetaMetaMetaTestCase < Minitest::Test
83
91
  end
84
92
 
85
93
  def assert_report expected, flags = %w[--seed 42], &block
86
- header = clean <<-EOM
87
- Run options: #{flags.map { |s| s =~ /\|/ ? s.inspect : s }.join " "}
94
+ header = <<~EOM
95
+ Run options: #{flags.map { |s| s.include?("|") ? s.inspect : s }.join " "}
88
96
 
89
97
  # Running:
90
98
 
@@ -119,7 +127,7 @@ class MetaMetaMetaTestCase < Minitest::Test
119
127
  output.gsub!(/in [`']block in (?:([^']+)[#.])?/, "in 'block in")
120
128
  output.gsub!(/in [`'](?:([^']+)[#.])?/, "in '")
121
129
 
122
- output.gsub!(/( at )[^:]+:\d+/) { "#{$1}[#{file[$2]}:LINE]" } # eval?
130
+ output.gsub!(/( at )([^:]+):\d+/) { "#{$1}[#{file[$2]}:LINE]" } # eval?
123
131
 
124
132
  output
125
133
  end