minitest 5.26.0 → 6.0.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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/History.rdoc +111 -0
  4. data/Manifest.txt +13 -4
  5. data/README.rdoc +18 -98
  6. data/Rakefile +7 -1
  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 +34 -66
  11. data/lib/minitest/autorun.rb +3 -4
  12. data/lib/minitest/benchmark.rb +3 -3
  13. data/lib/minitest/bisect.rb +306 -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 +425 -0
  20. data/lib/minitest/pride.rb +2 -2
  21. data/lib/minitest/pride_plugin.rb +1 -1
  22. data/lib/minitest/server.rb +45 -0
  23. data/lib/minitest/server_plugin.rb +84 -0
  24. data/lib/minitest/spec.rb +5 -33
  25. data/lib/minitest/sprint.rb +104 -0
  26. data/lib/minitest/sprint_plugin.rb +39 -0
  27. data/lib/minitest/test.rb +7 -13
  28. data/lib/minitest/test_task.rb +18 -16
  29. data/lib/minitest.rb +91 -101
  30. data/test/minitest/metametameta.rb +1 -1
  31. data/test/minitest/test_bisect.rb +235 -0
  32. data/test/minitest/test_find_minimal_combination.rb +138 -0
  33. data/test/minitest/test_minitest_assertions.rb +48 -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 +52 -118
  37. data/test/minitest/test_minitest_test.rb +21 -100
  38. data/test/minitest/test_path_expander.rb +229 -0
  39. data/test/minitest/test_server.rb +149 -0
  40. data.tar.gz.sig +2 -2
  41. metadata +56 -23
  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.26.0" # :nodoc:
13
+ VERSION = "6.0.1" # :nodoc:
14
14
 
15
15
  @@installed_at_exit ||= false
16
16
  @@after_run = []
@@ -33,8 +33,7 @@ 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
38
  self.parallel_executor = Parallel::Executor.new n_threads if n_threads > 1
40
39
 
@@ -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,38 @@ 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."
198
+
199
+ opts.on "-i", "--include PATTERN", "Include /regexp/ or string for run." do |a|
200
+ options[:include] = a
179
201
  end
180
202
 
181
203
  opts.on "-e", "--exclude PATTERN", "Exclude /regexp/ or string from run." do |a|
182
204
  options[:exclude] = a
183
205
  end
184
206
 
207
+ # part of my unofficial embedded gem "makeoptparseworkwell"
208
+ def opts.topdict(name) = (name.length > 1 ? top.long : top.short)
209
+ def opts.alias(from, to) = (dict = topdict(from) ; dict[to] = dict[from])
210
+
211
+ # these will work but won't show up in --help output:
212
+ opts.alias "include", "name"
213
+ opts.alias "i", "n"
214
+ opts.alias "e", "x"
215
+
185
216
  opts.on "-S", "--skip CODES", String, "Skip reporting of certain types of results (eg E)." do |s|
186
217
  options[:skip] = s.chars.to_a
187
218
  end
188
219
 
189
- ruby27plus = ::Warning.respond_to? :[]=
190
-
191
220
  opts.on "-W[error]", String, "Turn Ruby warnings into errors" do |s|
192
221
  options[:Werror] = true
193
222
  case s
194
223
  when "error", "all", nil then
195
- require "minitest/error_on_warning"
224
+ require_relative "minitest/error_on_warning"
196
225
  $VERBOSE = true
197
- ::Warning[:deprecated] = true if ruby27plus
226
+ ::Warning[:deprecated] = true
198
227
  else
199
- ::Warning[s.to_sym] = true if ruby27plus # check validity of category
228
+ ::Warning[s.to_sym] = true # check validity of category
200
229
  end
201
230
  end
202
231
 
@@ -253,23 +282,20 @@ module Minitest
253
282
  #
254
283
  # The overall structure of a run looks like this:
255
284
  #
285
+ # [Minitest.load_plugins] optional, called by user, or require what you want
256
286
  # Minitest.autorun
257
287
  # Minitest.run(args)
258
- # Minitest.load_plugins
259
288
  # Minitest.process_args
260
289
  # Minitest.init_plugins
261
- # Minitest.__run(reporter, options)
290
+ # Minitest.run_all_suites(reporter, options)
262
291
  # Runnable.runnables.each |runnable_klass|
263
- # runnable_klass.run(reporter, options)
264
- # filtered_methods = runnable_methods.select {...}.reject {...}
292
+ # runnable_klass.run_suite(reporter, options)
293
+ # filtered_methods = runnable_klass.filter_runnable_methods options
265
294
  # filtered_methods.each |runnable_method|
266
- # runnable_klass.run_one_method(self, runnable_method, reporter)
267
- # Minitest.run_one_method(runnable_klass, runnable_method)
268
- # runnable_klass.new(runnable_method).run
295
+ # runnable_klass.run(self, runnable_method, reporter)
296
+ # runnable_klass.new(runnable_method).run
269
297
 
270
298
  def self.run args = []
271
- self.load_plugins unless args.delete("--no-plugins") || ENV["MT_NO_PLUGINS"]
272
-
273
299
  options = process_args args
274
300
 
275
301
  Minitest.seed = options[:seed]
@@ -286,7 +312,7 @@ module Minitest
286
312
  self.parallel_executor.start if parallel_executor.respond_to? :start
287
313
  reporter.start
288
314
  begin
289
- __run reporter, options
315
+ run_all_suites reporter, options
290
316
  finished = true
291
317
  rescue Interrupt
292
318
  warn "Interrupted. Exiting..."
@@ -303,7 +329,7 @@ module Minitest
303
329
  end
304
330
 
305
331
  def self.empty_run! options # :nodoc:
306
- filter = options[:filter]
332
+ filter = options[:include]
307
333
  return true unless filter # no filter, but nothing ran == success
308
334
 
309
335
  warn "Nothing ran for filter: %s" % [filter]
@@ -322,17 +348,17 @@ module Minitest
322
348
  # Internal run method. Responsible for telling all Runnable
323
349
  # sub-classes to run.
324
350
 
325
- def self.__run reporter, options
351
+ def self.run_all_suites reporter, options
326
352
  suites = Runnable.runnables.shuffle
327
- parallel, serial = suites.partition { |s| s.test_order == :parallel }
353
+ parallel, serial = suites.partition { |s| s.run_order == :parallel }
328
354
 
329
355
  # If we run the parallel tests before the serial tests, the parallel tests
330
356
  # could run in parallel with the serial tests. This would be bad because
331
357
  # the serial tests won't lock around Reporter#record. Run the serial tests
332
358
  # first, so that after they complete, the parallel tests will lock when
333
359
  # recording results.
334
- serial.map { |suite| suite.run reporter, options } +
335
- parallel.map { |suite| suite.run reporter, options }
360
+ serial.map { |suite| suite.run_suite reporter, options } +
361
+ parallel.map { |suite| suite.run_suite reporter, options }
336
362
  end
337
363
 
338
364
  def self.filter_backtrace bt # :nodoc:
@@ -400,20 +426,30 @@ module Minitest
400
426
  reset
401
427
 
402
428
  ##
403
- # Responsible for running all runnable methods in a given class,
404
- # each in its own instance. Each instance is passed to the
405
- # reporter to record.
429
+ # Returns an array of filtered +runnable_methods+. Uses
430
+ # options[:include] (--include arguments) and options[:exclude]
431
+ # (--exclude arguments) values to filter.
406
432
 
407
- def self.run reporter, options = {}
408
- pos = options[:filter]
433
+ def self.filter_runnable_methods options={}
434
+ pos = options[:include]
409
435
  neg = options[:exclude]
410
436
 
411
437
  pos = Regexp.new $1 if pos.kind_of?(String) && pos =~ %r%/(.*)/%
412
438
  neg = Regexp.new $1 if neg.kind_of?(String) && neg =~ %r%/(.*)/%
413
439
 
414
- filtered_methods = self.runnable_methods
440
+ # at most 1-2% slower than a 1-pass version, stop optimizing this
441
+ self.runnable_methods
415
442
  .select { |m| !pos || pos === m || pos === "#{self}##{m}" }
416
443
  .reject { |m| neg && (neg === m || neg === "#{self}##{m}") }
444
+ end
445
+
446
+ ##
447
+ # Responsible for running all runnable methods in a given class,
448
+ # each in its own instance. Each instance is passed to the
449
+ # reporter to record.
450
+
451
+ def Runnable.run_suite reporter, options = {}
452
+ filtered_methods = filter_runnable_methods options
417
453
 
418
454
  return if filtered_methods.empty?
419
455
 
@@ -428,12 +464,12 @@ module Minitest
428
464
  warn "Current: %s#%s %.2fs" % [self, name, Minitest.clock_time - t0]
429
465
  end
430
466
 
431
- with_info_handler reporter do
467
+ with_info_handler do
432
468
  filtered_methods.each do |method_name|
433
469
  name = method_name
434
470
  t0 = Minitest.clock_time
435
471
 
436
- run_one_method self, method_name, reporter
472
+ run self, method_name, reporter
437
473
  end
438
474
  end
439
475
  end
@@ -444,20 +480,20 @@ module Minitest
444
480
  # that subclasses can specialize the running of an individual
445
481
  # test. See Minitest::ParallelTest::ClassMethods for an example.
446
482
 
447
- def self.run_one_method klass, method_name, reporter
483
+ def Runnable.run klass, method_name, reporter
448
484
  reporter.prerecord klass, method_name
449
- reporter.record Minitest.run_one_method(klass, method_name)
485
+ reporter.record klass.new(method_name).run
450
486
  end
451
487
 
452
488
  ##
453
489
  # Defines the order to run tests (:random by default). Override
454
490
  # this or use a convenience method to change it for your tests.
455
491
 
456
- def self.test_order
492
+ def self.run_order
457
493
  :random
458
494
  end
459
495
 
460
- def self.with_info_handler reporter, &block # :nodoc:
496
+ def self.with_info_handler _reporter=nil, &block # :nodoc:
461
497
  on_signal ::Minitest.info_signal, @_info_handler, &block
462
498
  end
463
499
 
@@ -491,22 +527,6 @@ module Minitest
491
527
  @@runnables
492
528
  end
493
529
 
494
- @@marshal_dump_warned = false
495
-
496
- def marshal_dump # :nodoc:
497
- unless @@marshal_dump_warned then
498
- warn ["Minitest::Runnable#marshal_dump is deprecated.",
499
- "You might be violating internals. From", caller(1..1).first].join " "
500
- @@marshal_dump_warned = true
501
- end
502
-
503
- [self.name, self.failures, self.assertions, self.time]
504
- end
505
-
506
- def marshal_load ary # :nodoc:
507
- self.name, self.failures, self.assertions, self.time = ary
508
- end
509
-
510
530
  def failure # :nodoc:
511
531
  self.failures.first
512
532
  end
@@ -574,7 +594,7 @@ module Minitest
574
594
  def skipped?
575
595
  raise NotImplementedError, "subclass responsibility"
576
596
  end
577
- end
597
+ end # Runnable
578
598
 
579
599
  ##
580
600
  # Shared code for anything that can get passed to a Reporter. See
@@ -626,7 +646,7 @@ module Minitest
626
646
  def error?
627
647
  self.failures.any? UnexpectedError
628
648
  end
629
- end
649
+ end # Reportable
630
650
 
631
651
  ##
632
652
  # This represents a test result in a clean way that can be
@@ -638,9 +658,6 @@ module Minitest
638
658
  class Result < Runnable
639
659
  include Minitest::Reportable
640
660
 
641
- undef_method :marshal_dump
642
- undef_method :marshal_load
643
-
644
661
  ##
645
662
  # The class name of the test result.
646
663
 
@@ -680,7 +697,7 @@ module Minitest
680
697
  "#{failure.result_label}:\n#{self.location}:\n#{failure.message}\n"
681
698
  }.join "\n"
682
699
  end
683
- end
700
+ end # Result
684
701
 
685
702
  ##
686
703
  # Defines the API for Reporters. Subclass this and override whatever
@@ -730,7 +747,7 @@ module Minitest
730
747
  def synchronize &block # :nodoc:
731
748
  @mutex.synchronize(&block)
732
749
  end
733
- end
750
+ end # AbstractReportera
734
751
 
735
752
  class Reporter < AbstractReporter # :nodoc:
736
753
  ##
@@ -885,7 +902,7 @@ module Minitest
885
902
  self.warnings = aggregate[UnexpectedWarning].size
886
903
  self.skips = aggregate[Skip].size
887
904
  end
888
- end
905
+ end # StatisticsReporter
889
906
 
890
907
  ##
891
908
  # A reporter that prints the header, summary, and failure details at
@@ -963,7 +980,7 @@ module Minitest
963
980
  "%d runs, %d assertions, %d failures, %d errors, %d skips%s" %
964
981
  [count, assertions, failures, errors, skips, extra.join]
965
982
  end
966
- end
983
+ end # SummaryReporter
967
984
 
968
985
  ##
969
986
  # Dispatch to multiple reporters as one.
@@ -1000,8 +1017,7 @@ module Minitest
1000
1017
 
1001
1018
  def prerecord klass, name # :nodoc:
1002
1019
  self.reporters.each do |reporter|
1003
- # TODO: remove conditional for minitest 6
1004
- reporter.prerecord klass, name if reporter.respond_to? :prerecord
1020
+ reporter.prerecord klass, name
1005
1021
  end
1006
1022
  end
1007
1023
 
@@ -1014,7 +1030,7 @@ module Minitest
1014
1030
  def report # :nodoc:
1015
1031
  self.reporters.each(&:report)
1016
1032
  end
1017
- end
1033
+ end # CompositeReporter
1018
1034
 
1019
1035
  ##
1020
1036
  # Represents run failures.
@@ -1127,16 +1143,6 @@ module Minitest
1127
1143
  "java" == platform
1128
1144
  end
1129
1145
 
1130
- ##
1131
- # Is this running on maglev?
1132
-
1133
- def maglev? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
1134
- where = Minitest.filter_backtrace(caller).first
1135
- where = where.split(":in ", 2).first # clean up noise
1136
- warn "DEPRECATED: `maglev?` called from #{where}. This will fail in Minitest 6."
1137
- "maglev" == platform
1138
- end
1139
-
1140
1146
  ##
1141
1147
  # Is this running on mri?
1142
1148
 
@@ -1151,16 +1157,6 @@ module Minitest
1151
1157
  platform.include? "darwin"
1152
1158
  end
1153
1159
 
1154
- ##
1155
- # Is this running on rubinius?
1156
-
1157
- def rubinius? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
1158
- where = Minitest.filter_backtrace(caller).first
1159
- where = where.split(":in ", 2).first # clean up noise
1160
- warn "DEPRECATED: `rubinius?` called from #{where}. This will fail in Minitest 6."
1161
- "rbx" == platform
1162
- end
1163
-
1164
1160
  ##
1165
1161
  # Is this running on windows?
1166
1162
 
@@ -1206,12 +1202,6 @@ module Minitest
1206
1202
 
1207
1203
  self.backtrace_filter = BacktraceFilter.new
1208
1204
 
1209
- def self.run_one_method klass, method_name # :nodoc:
1210
- result = klass.new(method_name).run
1211
- raise "#{klass}#run _must_ return a Result" unless Result === result
1212
- result
1213
- end
1214
-
1215
1205
  # :stopdoc:
1216
1206
 
1217
1207
  if defined? Process::CLOCK_MONOTONIC # :nodoc:
@@ -1234,4 +1224,4 @@ module Minitest
1234
1224
  # :startdoc:
1235
1225
  end
1236
1226
 
1237
- require "minitest/test"
1227
+ require_relative "minitest/test"
@@ -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
@@ -0,0 +1,235 @@
1
+ require "minitest/autorun"
2
+ require "minitest/bisect"
3
+
4
+ module TestMinitest; end
5
+
6
+ class TestMinitest::TestBisect < Minitest::Test
7
+ attr_accessor :bisect
8
+
9
+ def setup
10
+ self.bisect = Minitest::Bisect.new
11
+ bisect.reset
12
+ end
13
+
14
+ def test_class_run
15
+ skip "Need to write test_class_run"
16
+ end
17
+
18
+ def test_bisect_files
19
+ skip "Need to write test_bisect_files"
20
+ end
21
+
22
+ def test_bisect_methods
23
+ skip "Need to write test_bisect_methods"
24
+ end
25
+
26
+ def test_build_files_cmd
27
+ files = %w[a.rb b.rb c.rb]
28
+ rb = %w[-Ilib:test]
29
+ mt = %w[--seed 42]
30
+
31
+ ruby = Minitest::Bisect::RUBY
32
+ body = "require \"./a.rb\" ; require \"./b.rb\" ; require \"./c.rb\""
33
+
34
+ exp = "#{ruby} -Ilib:test -e '#{body}' -- --seed 42"
35
+ act = bisect.build_files_cmd(files, rb, mt)
36
+
37
+ assert_equal exp, act
38
+ end
39
+
40
+ def test_build_methods_cmd
41
+ cmd = "cmd"
42
+ assert_equal "cmd", bisect.build_methods_cmd(cmd)
43
+ end
44
+
45
+ def test_build_methods_cmd_verify
46
+ cmd = "cmd"
47
+ cul = []
48
+ bad = %w[A#test_1 B#test_2]
49
+
50
+ exp = "cmd -n \"/^(?:A#(?:test_1)|B#(?:test_2))$/\""
51
+
52
+ assert_equal exp, bisect.build_methods_cmd(cmd, cul, bad)
53
+ end
54
+
55
+ def test_build_methods_cmd_verify_same
56
+ cmd = "cmd"
57
+ cul = []
58
+ bad = %w[C#test_5 C#test_6]
59
+
60
+ exp = "cmd -n \"/^(?:C#(?:test_5|test_6))$/\""
61
+
62
+ assert_equal exp, bisect.build_methods_cmd(cmd, cul, bad)
63
+ end
64
+
65
+ def test_build_methods_cmd_full
66
+ cmd = "cmd"
67
+ cul = %w[A#test_1 A#test_2 B#test_3 B#test_4]
68
+ bad = %w[C#test_5 C#test_6]
69
+
70
+ a = "A#(?:test_1|test_2)"
71
+ b = "B#(?:test_3|test_4)"
72
+ c = "C#(?:test_5|test_6)"
73
+ exp = "cmd -n \"/^(?:#{a}|#{b}|#{c})$/\""
74
+
75
+ assert_equal exp, bisect.build_methods_cmd(cmd, cul, bad)
76
+ end
77
+
78
+ def test_build_re
79
+ bad = %w[A#test_1 B#test_2]
80
+
81
+ exp = "/^(?:A#(?:test_1)|B#(?:test_2))$/"
82
+
83
+ assert_equal exp, bisect.build_re(bad)
84
+ end
85
+
86
+ def test_build_re_same
87
+ bad = %w[C#test_5 C#test_6]
88
+
89
+ exp = "/^(?:C#(?:test_5|test_6))$/"
90
+
91
+ assert_equal exp, bisect.build_re(bad)
92
+ end
93
+
94
+ def test_build_re_class_escaping
95
+ bad = ["{}#[]"]
96
+
97
+ exp = "/^(?:\\{\\}#(?:\\[\\]))$/"
98
+
99
+ assert_equal exp, bisect.build_re(bad)
100
+ end
101
+
102
+ def test_build_re_method_escaping
103
+ bad = ["Some Class#It shouldn't care what the name is"]
104
+
105
+ exp = "/^(?:Some Class#(?:It shouldn\\'t care what the name is))$/"
106
+
107
+ assert_equal exp, bisect.build_re(bad)
108
+ end
109
+
110
+ def test_map_failures
111
+ bisect.failures =
112
+ {
113
+ "file.rb" => { "Class" => %w[test_method1 test_method2] },
114
+ "blah.rb" => { "Apple" => %w[test_method3 test_method4] },
115
+ }
116
+
117
+ exp = %w[
118
+ Apple#test_method3
119
+ Apple#test_method4
120
+ Class#test_method1
121
+ Class#test_method2
122
+ ]
123
+
124
+ assert_equal exp, bisect.map_failures
125
+ end
126
+
127
+ def test_minitest_result
128
+ bisect.minitest_result "file.rb", "TestClass", "test_method", [], 1, 1
129
+
130
+ assert_equal false, bisect.tainted
131
+ assert_empty bisect.failures
132
+ assert_equal ["TestClass#test_method"], bisect.culprits
133
+ end
134
+
135
+ def test_minitest_result_skip
136
+ fail = Minitest::Skip.new("woot")
137
+
138
+ bisect.minitest_result "file.rb", "TestClass", "test_method", [fail], 1, 1
139
+
140
+ assert_equal false, bisect.tainted
141
+ assert_empty bisect.failures
142
+ assert_equal ["TestClass#test_method"], bisect.culprits
143
+ end
144
+
145
+ def test_minitest_result_fail
146
+ fail = Minitest::Assertion.new "msg"
147
+
148
+ bisect.minitest_result "file.rb", "TestClass", "test_method", [fail], 1, 1
149
+
150
+ exp = {"file.rb" => {"TestClass" => ["test_method"] }}
151
+
152
+ assert_equal true, bisect.tainted
153
+ assert_equal exp, bisect.failures
154
+ assert_empty bisect.culprits
155
+ end
156
+
157
+ def test_minitest_result_error
158
+ fail = Minitest::UnexpectedError.new RuntimeError.new("woot")
159
+
160
+ bisect.minitest_result "file.rb", "TestClass", "test_method", [fail], 1, 1
161
+
162
+ exp = {"file.rb" => {"TestClass" => ["test_method"] }}
163
+
164
+ assert_equal true, bisect.tainted
165
+ assert_equal exp, bisect.failures
166
+ assert_empty bisect.culprits
167
+ end
168
+
169
+ def test_minitest_start
170
+ bisect.failures["file.rb"]["Class"] << "test_bad1"
171
+
172
+ bisect.minitest_start
173
+
174
+ assert_empty bisect.failures
175
+ end
176
+
177
+ def test_reset
178
+ bisect.seen_bad = true
179
+ bisect.tainted = true
180
+ bisect.failures["file.rb"]["Class"] << "test_bad1"
181
+ bisect.culprits << "A#test_1" << "B#test_2"
182
+
183
+ bisect.reset
184
+
185
+ assert_equal false, bisect.seen_bad
186
+ assert_equal false, bisect.tainted
187
+ assert_empty bisect.failures
188
+ assert_equal %w[A#test_1 B#test_2], bisect.culprits
189
+ end
190
+
191
+ def test_run
192
+ skip "Need to write test_run"
193
+ end
194
+
195
+ def test_time_it
196
+ exp = /\Ado stuff: in 0.\d\d sec\n\z/
197
+
198
+ assert_output exp, "" do
199
+ bisect.time_it "do stuff:", "echo you should not see me"
200
+ end
201
+ end
202
+ end
203
+
204
+ class TestMinitest::TestBisect::TestPathExpander < Minitest::Test
205
+ def test_sanity
206
+ args = %w[1 -Iblah 2 -d 3 -w 4 5 6]
207
+
208
+ mtbpe = Minitest::Bisect::PathExpander
209
+ expander = mtbpe.new args
210
+
211
+ assert_equal %w[-Itest:lib], expander.rb_flags
212
+ assert_same mtbpe::TEST_GLOB, expander.glob
213
+ end
214
+
215
+ def test_process_flags
216
+ args = %w[1 -Iblah 2 -d 3 -w 4 5 6]
217
+
218
+ expander = Minitest::Bisect::PathExpander.new args
219
+
220
+ exp_files = %w[1 2 3 4 5 6]
221
+ exp_flags = %w[-Itest:lib -Iblah -d -w]
222
+
223
+ files = expander.process_flags(args)
224
+
225
+ assert_equal files, exp_files
226
+
227
+ # process_flags only filters and does not mutate args
228
+ assert_same args, expander.args
229
+ refute_equal args, exp_files
230
+ refute_equal files, args
231
+
232
+ # separates rb_flags out for separate handling
233
+ assert_equal exp_flags, expander.rb_flags
234
+ end
235
+ end