minitest 5.22.3 → 5.25.4

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