minitest 5.25.5 → 6.0.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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -4
  3. data/History.rdoc +156 -0
  4. data/Manifest.txt +13 -4
  5. data/README.rdoc +21 -100
  6. data/Rakefile +10 -2
  7. data/bin/minitest +5 -0
  8. data/design_rationale.rb +21 -19
  9. data/lib/hoe/minitest.rb +2 -1
  10. data/lib/minitest/assertions.rb +39 -73
  11. data/lib/minitest/autorun.rb +3 -4
  12. data/lib/minitest/benchmark.rb +3 -3
  13. data/lib/minitest/bisect.rb +304 -0
  14. data/lib/minitest/complete.rb +56 -0
  15. data/lib/minitest/find_minimal_combination.rb +127 -0
  16. data/lib/minitest/hell.rb +1 -1
  17. data/lib/minitest/manual_plugins.rb +4 -16
  18. data/lib/minitest/parallel.rb +5 -3
  19. data/lib/minitest/path_expander.rb +432 -0
  20. data/lib/minitest/pride.rb +2 -2
  21. data/lib/minitest/pride_plugin.rb +1 -1
  22. data/lib/minitest/server.rb +49 -0
  23. data/lib/minitest/server_plugin.rb +88 -0
  24. data/lib/minitest/spec.rb +11 -37
  25. data/lib/minitest/sprint.rb +105 -0
  26. data/lib/minitest/sprint_plugin.rb +39 -0
  27. data/lib/minitest/test.rb +8 -13
  28. data/lib/minitest/test_task.rb +44 -20
  29. data/lib/minitest.rb +104 -107
  30. data/test/minitest/metametameta.rb +1 -1
  31. data/test/minitest/test_bisect.rb +249 -0
  32. data/test/minitest/test_find_minimal_combination.rb +138 -0
  33. data/test/minitest/test_minitest_assertions.rb +54 -105
  34. data/test/minitest/test_minitest_benchmark.rb +14 -0
  35. data/test/minitest/test_minitest_reporter.rb +6 -5
  36. data/test/minitest/test_minitest_spec.rb +60 -128
  37. data/test/minitest/test_minitest_test.rb +22 -101
  38. data/test/minitest/test_path_expander.rb +229 -0
  39. data/test/minitest/test_server.rb +146 -0
  40. data.tar.gz.sig +0 -0
  41. metadata +92 -33
  42. metadata.gz.sig +0 -0
  43. data/.autotest +0 -34
  44. data/lib/minitest/mock.rb +0 -347
  45. data/lib/minitest/unit.rb +0 -42
  46. data/test/minitest/test_minitest_mock.rb +0 -1218
data/lib/minitest.rb CHANGED
@@ -10,7 +10,7 @@ require_relative "minitest/compress"
10
10
  # runtime. See +Minitest.run+ for more information.
11
11
 
12
12
  module Minitest
13
- VERSION = "5.25.5" # :nodoc:
13
+ VERSION = "6.0.4" # :nodoc:
14
14
 
15
15
  @@installed_at_exit ||= false
16
16
  @@after_run = []
@@ -33,10 +33,9 @@ module Minitest
33
33
 
34
34
  cattr_accessor :parallel_executor
35
35
 
36
- warn "DEPRECATED: use MT_CPU instead of N for parallel test runs" if ENV["N"] && ENV["N"].to_i > 0
37
- n_threads = (ENV["MT_CPU"] || ENV["N"] || Etc.nprocessors).to_i
36
+ n_threads = (ENV["MT_CPU"] || Etc.nprocessors).to_i
38
37
 
39
- self.parallel_executor = Parallel::Executor.new n_threads
38
+ self.parallel_executor = Parallel::Executor.new n_threads if n_threads > 1
40
39
 
41
40
  ##
42
41
  # Filter object for backtraces.
@@ -68,8 +67,7 @@ module Minitest
68
67
  # Registers Minitest to run at process exit
69
68
 
70
69
  def self.autorun
71
- Warning[:deprecated] = true if
72
- Object.const_defined?(:Warning) && Warning.respond_to?(:[]=)
70
+ Warning[:deprecated] = true
73
71
 
74
72
  at_exit {
75
73
  next if $! and not ($!.kind_of? SystemExit and $!.success?)
@@ -98,6 +96,17 @@ module Minitest
98
96
  @@after_run << block
99
97
  end
100
98
 
99
+ ##
100
+ # Manually load plugins by name.
101
+
102
+ def self.load *names
103
+ names.each do |name|
104
+ require "minitest/#{name}_plugin"
105
+
106
+ self.extensions << name.to_s
107
+ end
108
+ end
109
+
101
110
  ##
102
111
  # Register a plugin to be used. Does NOT require / load it.
103
112
 
@@ -146,27 +155,38 @@ module Minitest
146
155
  }
147
156
  orig_args = args.dup
148
157
 
158
+ warn "--no-plugins is a no-op" if args.delete "--no-plugins" # TODO: remove me! when?
159
+
149
160
  OptionParser.new do |opts|
150
- opts.banner = "minitest options:"
161
+ opts.program_name = "minitest"
151
162
  opts.version = Minitest::VERSION
152
163
 
164
+ opts.banner = [
165
+ "Usage: minitest [paths] [options]",
166
+ "ruby path/to/test.rb [options]",
167
+ "rake test [A=options] (see Minitest::TestTask for more options)\n\n",
168
+ ].join "\n or: "
169
+
153
170
  opts.on "-h", "--help", "Display this help." do
154
171
  puts opts
155
- exit
172
+ exit! true
156
173
  end
157
174
 
158
- opts.on "--no-plugins", "Bypass minitest plugin auto-loading (or set $MT_NO_PLUGINS)."
175
+ opts.on "-V", "--version", "Display the version." do
176
+ puts "#{opts.program_name} #{Minitest::VERSION}"
177
+ exit! true
178
+ end
159
179
 
160
- desc = "Sets random seed. Also via env. Eg: SEED=n rake"
180
+ desc = "Sets random seed. Also via env, eg: SEED=42"
161
181
  opts.on "-s", "--seed SEED", Integer, desc do |m|
162
- options[:seed] = m.to_i
182
+ options[:seed] = m
163
183
  end
164
184
 
165
- opts.on "-v", "--verbose", "Verbose. Show progress processing files." do
185
+ opts.on "-v", "--verbose", "Verbose. Print each name as they run." do
166
186
  options[:verbose] = true
167
187
  end
168
188
 
169
- opts.on "-q", "--quiet", "Quiet. Show no progress processing files." do
189
+ opts.on "-q", "--quiet", "Quiet. Show no dots while processing files." do
170
190
  options[:quiet] = true
171
191
  end
172
192
 
@@ -174,29 +194,39 @@ module Minitest
174
194
  options[:show_skips] = true
175
195
  end
176
196
 
177
- opts.on "-n", "--name PATTERN", "Filter run on /regexp/ or string." do |a|
178
- options[:filter] = a
197
+ opts.on "-b", "--bisect", "Run minitest in bisect-mode to isolate flaky tests." if
198
+ File.basename($0).match?(/minitest/)
199
+
200
+ opts.on "-i", "--include PATTERN", "Include /regexp/ or string for run." do |a|
201
+ options[:include] = a
179
202
  end
180
203
 
181
204
  opts.on "-e", "--exclude PATTERN", "Exclude /regexp/ or string from run." do |a|
182
205
  options[:exclude] = a
183
206
  end
184
207
 
208
+ # part of my unofficial embedded gem "makeoptparseworkwell"
209
+ def opts.topdict(name) = (name.length > 1 ? top.long : top.short)
210
+ def opts.alias(from, to) = (dict = topdict(from) ; dict[to] = dict[from])
211
+
212
+ # these will work but won't show up in --help output:
213
+ opts.alias "include", "name"
214
+ opts.alias "i", "n"
215
+ opts.alias "e", "x"
216
+
185
217
  opts.on "-S", "--skip CODES", String, "Skip reporting of certain types of results (eg E)." do |s|
186
218
  options[:skip] = s.chars.to_a
187
219
  end
188
220
 
189
- ruby27plus = ::Warning.respond_to? :[]=
190
-
191
221
  opts.on "-W[error]", String, "Turn Ruby warnings into errors" do |s|
192
222
  options[:Werror] = true
193
223
  case s
194
224
  when "error", "all", nil then
195
- require "minitest/error_on_warning"
225
+ require_relative "minitest/error_on_warning"
196
226
  $VERBOSE = true
197
- ::Warning[:deprecated] = true if ruby27plus
227
+ ::Warning[:deprecated] = true
198
228
  else
199
- ::Warning[s.to_sym] = true if ruby27plus # check validity of category
229
+ ::Warning[s.to_sym] = true # check validity of category
200
230
  end
201
231
  end
202
232
 
@@ -253,22 +283,20 @@ module Minitest
253
283
  #
254
284
  # The overall structure of a run looks like this:
255
285
  #
286
+ # [Minitest.load_plugins] optional, called by user, or require what you want
256
287
  # Minitest.autorun
257
288
  # Minitest.run(args)
258
- # Minitest.load_plugins
259
289
  # Minitest.process_args
260
290
  # Minitest.init_plugins
261
- # Minitest.__run(reporter, options)
262
- # Runnable.runnables.each
263
- # runnable_klass.run(reporter, options)
264
- # self.runnable_methods.each
265
- # self.run_one_method(self, runnable_method, reporter)
266
- # Minitest.run_one_method(klass, runnable_method)
267
- # klass.new(runnable_method).run
291
+ # Minitest.run_all_suites(reporter, options)
292
+ # Runnable.runnables.each |runnable_klass|
293
+ # runnable_klass.run_suite(reporter, options)
294
+ # filtered_methods = runnable_klass.filter_runnable_methods options
295
+ # filtered_methods.each |runnable_method|
296
+ # runnable_klass.run(self, runnable_method, reporter)
297
+ # runnable_klass.new(runnable_method).run
268
298
 
269
299
  def self.run args = []
270
- self.load_plugins unless args.delete("--no-plugins") || ENV["MT_NO_PLUGINS"]
271
-
272
300
  options = process_args args
273
301
 
274
302
  Minitest.seed = options[:seed]
@@ -285,23 +313,24 @@ module Minitest
285
313
  self.parallel_executor.start if parallel_executor.respond_to? :start
286
314
  reporter.start
287
315
  begin
288
- __run reporter, options
316
+ run_all_suites reporter, options
317
+ finished = true
289
318
  rescue Interrupt
290
319
  warn "Interrupted. Exiting..."
291
320
  end
292
- self.parallel_executor.shutdown
321
+ self.parallel_executor.shutdown if parallel_executor.respond_to? :shutdown
293
322
 
294
323
  # might have been removed/replaced during init_plugins:
295
324
  summary = reporter.reporters.grep(SummaryReporter).first
296
325
 
297
326
  reporter.report
298
327
 
299
- return empty_run! options if summary && summary.count == 0
300
- reporter.passed?
328
+ return empty_run! options if finished && summary && summary.count == 0
329
+ finished and reporter.passed?
301
330
  end
302
331
 
303
332
  def self.empty_run! options # :nodoc:
304
- filter = options[:filter]
333
+ filter = options[:include]
305
334
  return true unless filter # no filter, but nothing ran == success
306
335
 
307
336
  warn "Nothing ran for filter: %s" % [filter]
@@ -320,17 +349,17 @@ module Minitest
320
349
  # Internal run method. Responsible for telling all Runnable
321
350
  # sub-classes to run.
322
351
 
323
- def self.__run reporter, options
352
+ def self.run_all_suites reporter, options
324
353
  suites = Runnable.runnables.shuffle
325
- parallel, serial = suites.partition { |s| s.test_order == :parallel }
354
+ parallel, serial = suites.partition { |s| s.run_order == :parallel }
326
355
 
327
356
  # If we run the parallel tests before the serial tests, the parallel tests
328
357
  # could run in parallel with the serial tests. This would be bad because
329
358
  # the serial tests won't lock around Reporter#record. Run the serial tests
330
359
  # first, so that after they complete, the parallel tests will lock when
331
360
  # recording results.
332
- serial.map { |suite| suite.run reporter, options } +
333
- parallel.map { |suite| suite.run reporter, options }
361
+ serial.map { |suite| suite.run_suite reporter, options } +
362
+ parallel.map { |suite| suite.run_suite reporter, options }
334
363
  end
335
364
 
336
365
  def self.filter_backtrace bt # :nodoc:
@@ -398,20 +427,30 @@ module Minitest
398
427
  reset
399
428
 
400
429
  ##
401
- # Responsible for running all runnable methods in a given class,
402
- # each in its own instance. Each instance is passed to the
403
- # reporter to record.
430
+ # Returns an array of filtered +runnable_methods+. Uses
431
+ # options[:include] (--include arguments) and options[:exclude]
432
+ # (--exclude arguments) values to filter.
404
433
 
405
- def self.run reporter, options = {}
406
- pos = options[:filter]
434
+ def self.filter_runnable_methods options={}
435
+ pos = options[:include]
407
436
  neg = options[:exclude]
408
437
 
409
438
  pos = Regexp.new $1 if pos.kind_of?(String) && pos =~ %r%/(.*)/%
410
439
  neg = Regexp.new $1 if neg.kind_of?(String) && neg =~ %r%/(.*)/%
411
440
 
412
- filtered_methods = self.runnable_methods
441
+ # at most 1-2% slower than a 1-pass version, stop optimizing this
442
+ self.runnable_methods
413
443
  .select { |m| !pos || pos === m || pos === "#{self}##{m}" }
414
444
  .reject { |m| neg && (neg === m || neg === "#{self}##{m}") }
445
+ end
446
+
447
+ ##
448
+ # Responsible for running all runnable methods in a given class,
449
+ # each in its own instance. Each instance is passed to the
450
+ # reporter to record.
451
+
452
+ def Runnable.run_suite reporter, options = {}
453
+ filtered_methods = filter_runnable_methods options
415
454
 
416
455
  return if filtered_methods.empty?
417
456
 
@@ -426,12 +465,12 @@ module Minitest
426
465
  warn "Current: %s#%s %.2fs" % [self, name, Minitest.clock_time - t0]
427
466
  end
428
467
 
429
- with_info_handler reporter do
468
+ with_info_handler do
430
469
  filtered_methods.each do |method_name|
431
470
  name = method_name
432
471
  t0 = Minitest.clock_time
433
472
 
434
- run_one_method self, method_name, reporter
473
+ run self, method_name, reporter
435
474
  end
436
475
  end
437
476
  end
@@ -442,20 +481,20 @@ module Minitest
442
481
  # that subclasses can specialize the running of an individual
443
482
  # test. See Minitest::ParallelTest::ClassMethods for an example.
444
483
 
445
- def self.run_one_method klass, method_name, reporter
484
+ def Runnable.run klass, method_name, reporter
446
485
  reporter.prerecord klass, method_name
447
- reporter.record Minitest.run_one_method(klass, method_name)
486
+ reporter.record klass.new(method_name).run
448
487
  end
449
488
 
450
489
  ##
451
490
  # Defines the order to run tests (:random by default). Override
452
491
  # this or use a convenience method to change it for your tests.
453
492
 
454
- def self.test_order
493
+ def self.run_order
455
494
  :random
456
495
  end
457
496
 
458
- def self.with_info_handler reporter, &block # :nodoc:
497
+ def self.with_info_handler _reporter=nil, &block # :nodoc:
459
498
  on_signal ::Minitest.info_signal, @_info_handler, &block
460
499
  end
461
500
 
@@ -489,22 +528,6 @@ module Minitest
489
528
  @@runnables
490
529
  end
491
530
 
492
- @@marshal_dump_warned = false
493
-
494
- def marshal_dump # :nodoc:
495
- unless @@marshal_dump_warned then
496
- warn ["Minitest::Runnable#marshal_dump is deprecated.",
497
- "You might be violating internals. From", caller(1..1).first].join " "
498
- @@marshal_dump_warned = true
499
- end
500
-
501
- [self.name, self.failures, self.assertions, self.time]
502
- end
503
-
504
- def marshal_load ary # :nodoc:
505
- self.name, self.failures, self.assertions, self.time = ary
506
- end
507
-
508
531
  def failure # :nodoc:
509
532
  self.failures.first
510
533
  end
@@ -572,7 +595,7 @@ module Minitest
572
595
  def skipped?
573
596
  raise NotImplementedError, "subclass responsibility"
574
597
  end
575
- end
598
+ end # Runnable
576
599
 
577
600
  ##
578
601
  # Shared code for anything that can get passed to a Reporter. See
@@ -624,7 +647,7 @@ module Minitest
624
647
  def error?
625
648
  self.failures.any? UnexpectedError
626
649
  end
627
- end
650
+ end # Reportable
628
651
 
629
652
  ##
630
653
  # This represents a test result in a clean way that can be
@@ -636,9 +659,6 @@ module Minitest
636
659
  class Result < Runnable
637
660
  include Minitest::Reportable
638
661
 
639
- undef_method :marshal_dump
640
- undef_method :marshal_load
641
-
642
662
  ##
643
663
  # The class name of the test result.
644
664
 
@@ -678,7 +698,7 @@ module Minitest
678
698
  "#{failure.result_label}:\n#{self.location}:\n#{failure.message}\n"
679
699
  }.join "\n"
680
700
  end
681
- end
701
+ end # Result
682
702
 
683
703
  ##
684
704
  # Defines the API for Reporters. Subclass this and override whatever
@@ -728,7 +748,7 @@ module Minitest
728
748
  def synchronize &block # :nodoc:
729
749
  @mutex.synchronize(&block)
730
750
  end
731
- end
751
+ end # AbstractReportera
732
752
 
733
753
  class Reporter < AbstractReporter # :nodoc:
734
754
  ##
@@ -883,7 +903,7 @@ module Minitest
883
903
  self.warnings = aggregate[UnexpectedWarning].size
884
904
  self.skips = aggregate[Skip].size
885
905
  end
886
- end
906
+ end # StatisticsReporter
887
907
 
888
908
  ##
889
909
  # A reporter that prints the header, summary, and failure details at
@@ -961,7 +981,7 @@ module Minitest
961
981
  "%d runs, %d assertions, %d failures, %d errors, %d skips%s" %
962
982
  [count, assertions, failures, errors, skips, extra.join]
963
983
  end
964
- end
984
+ end # SummaryReporter
965
985
 
966
986
  ##
967
987
  # Dispatch to multiple reporters as one.
@@ -998,8 +1018,7 @@ module Minitest
998
1018
 
999
1019
  def prerecord klass, name # :nodoc:
1000
1020
  self.reporters.each do |reporter|
1001
- # TODO: remove conditional for minitest 6
1002
- reporter.prerecord klass, name if reporter.respond_to? :prerecord
1021
+ reporter.prerecord klass, name
1003
1022
  end
1004
1023
  end
1005
1024
 
@@ -1012,7 +1031,7 @@ module Minitest
1012
1031
  def report # :nodoc:
1013
1032
  self.reporters.each(&:report)
1014
1033
  end
1015
- end
1034
+ end # CompositeReporter
1016
1035
 
1017
1036
  ##
1018
1037
  # Represents run failures.
@@ -1079,7 +1098,7 @@ module Minitest
1079
1098
  self.error.backtrace
1080
1099
  end
1081
1100
 
1082
- BASE_RE = %r%#{Dir.pwd}/% # :nodoc:
1101
+ BASE_RE = %r%#{Regexp.escape Dir.pwd}/% # :nodoc:
1083
1102
 
1084
1103
  def message # :nodoc:
1085
1104
  bt = Minitest.filter_backtrace(self.backtrace).join("\n ")
@@ -1125,16 +1144,6 @@ module Minitest
1125
1144
  "java" == platform
1126
1145
  end
1127
1146
 
1128
- ##
1129
- # Is this running on maglev?
1130
-
1131
- def maglev? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
1132
- where = Minitest.filter_backtrace(caller).first
1133
- where = where.split(":in ", 2).first # clean up noise
1134
- warn "DEPRECATED: `maglev?` called from #{where}. This will fail in Minitest 6."
1135
- "maglev" == platform
1136
- end
1137
-
1138
1147
  ##
1139
1148
  # Is this running on mri?
1140
1149
 
@@ -1149,16 +1158,6 @@ module Minitest
1149
1158
  platform.include? "darwin"
1150
1159
  end
1151
1160
 
1152
- ##
1153
- # Is this running on rubinius?
1154
-
1155
- def rubinius? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
1156
- where = Minitest.filter_backtrace(caller).first
1157
- where = where.split(":in ", 2).first # clean up noise
1158
- warn "DEPRECATED: `rubinius?` called from #{where}. This will fail in Minitest 6."
1159
- "rbx" == platform
1160
- end
1161
-
1162
1161
  ##
1163
1162
  # Is this running on windows?
1164
1163
 
@@ -1204,12 +1203,6 @@ module Minitest
1204
1203
 
1205
1204
  self.backtrace_filter = BacktraceFilter.new
1206
1205
 
1207
- def self.run_one_method klass, method_name # :nodoc:
1208
- result = klass.new(method_name).run
1209
- raise "#{klass}#run _must_ return a Result" unless Result === result
1210
- result
1211
- end
1212
-
1213
1206
  # :stopdoc:
1214
1207
 
1215
1208
  if defined? Process::CLOCK_MONOTONIC # :nodoc:
@@ -1232,4 +1225,8 @@ module Minitest
1232
1225
  # :startdoc:
1233
1226
  end
1234
1227
 
1235
- require "minitest/test"
1228
+ require_relative "minitest/test"
1229
+ if ENV["MINITEST_SERVER"] then
1230
+ require_relative "minitest/server_plugin"
1231
+ Minitest.register_plugin :server
1232
+ end
@@ -79,7 +79,7 @@ class MetaMetaMetaTestCase < Minitest::Test
79
79
  @tus.each do |tu|
80
80
  Minitest::Runnable.runnables.delete tu
81
81
 
82
- tu.run reporter, options
82
+ tu.run_suite reporter, options
83
83
  end
84
84
 
85
85
  reporter.report