minitest 5.25.5 → 6.0.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -4
  3. data/History.rdoc +116 -0
  4. data/Manifest.txt +13 -4
  5. data/README.rdoc +18 -98
  6. data/Rakefile +7 -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 +37 -74
  11. data/lib/minitest/autorun.rb +3 -4
  12. data/lib/minitest/benchmark.rb +2 -2
  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 +418 -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 +11 -37
  25. data/lib/minitest/sprint.rb +104 -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 +32 -17
  29. data/lib/minitest.rb +94 -107
  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 +51 -108
  34. data/test/minitest/test_minitest_reporter.rb +6 -5
  35. data/test/minitest/test_minitest_spec.rb +60 -128
  36. data/test/minitest/test_minitest_test.rb +22 -101
  37. data/test/minitest/test_path_expander.rb +229 -0
  38. data/test/minitest/test_server.rb +149 -0
  39. data.tar.gz.sig +0 -0
  40. metadata +54 -21
  41. metadata.gz.sig +0 -0
  42. data/.autotest +0 -34
  43. data/lib/minitest/mock.rb +0 -347
  44. data/lib/minitest/unit.rb +0 -42
  45. 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.0" # :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,33 @@ 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: rake test [A=options] (see Minitest::TestTask for more options)",
166
+ "minitest [paths] [options] (with minitest-sprint gem)",
167
+ "ruby path/to/test.rb [options]\n\n",
168
+ ].join "\n or: "
169
+
153
170
  opts.on "-h", "--help", "Display this help." do
154
171
  puts opts
155
172
  exit
156
173
  end
157
174
 
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"
175
+ desc = "Sets random seed. Also via env, eg: SEED=42"
161
176
  opts.on "-s", "--seed SEED", Integer, desc do |m|
162
- options[:seed] = m.to_i
177
+ options[:seed] = m
163
178
  end
164
179
 
165
- opts.on "-v", "--verbose", "Verbose. Show progress processing files." do
180
+ opts.on "-v", "--verbose", "Verbose. Print each name as they run." do
166
181
  options[:verbose] = true
167
182
  end
168
183
 
169
- opts.on "-q", "--quiet", "Quiet. Show no progress processing files." do
184
+ opts.on "-q", "--quiet", "Quiet. Show no dots while processing files." do
170
185
  options[:quiet] = true
171
186
  end
172
187
 
@@ -174,29 +189,38 @@ module Minitest
174
189
  options[:show_skips] = true
175
190
  end
176
191
 
177
- opts.on "-n", "--name PATTERN", "Filter run on /regexp/ or string." do |a|
178
- options[:filter] = a
192
+ opts.on "-b", "--bisect", "Run minitest in bisect-mode to isolate flaky tests."
193
+
194
+ opts.on "-i", "--include PATTERN", "Include /regexp/ or string for run." do |a|
195
+ options[:include] = a
179
196
  end
180
197
 
181
198
  opts.on "-e", "--exclude PATTERN", "Exclude /regexp/ or string from run." do |a|
182
199
  options[:exclude] = a
183
200
  end
184
201
 
202
+ # part of my unofficial embedded gem "makeoptparseworkwell"
203
+ def opts.topdict(name) = (name.length > 1 ? top.long : top.short)
204
+ def opts.alias(from, to) = (dict = topdict(from) ; dict[to] = dict[from])
205
+
206
+ # these will work but won't show up in --help output:
207
+ opts.alias "include", "name"
208
+ opts.alias "i", "n"
209
+ opts.alias "e", "x"
210
+
185
211
  opts.on "-S", "--skip CODES", String, "Skip reporting of certain types of results (eg E)." do |s|
186
212
  options[:skip] = s.chars.to_a
187
213
  end
188
214
 
189
- ruby27plus = ::Warning.respond_to? :[]=
190
-
191
215
  opts.on "-W[error]", String, "Turn Ruby warnings into errors" do |s|
192
216
  options[:Werror] = true
193
217
  case s
194
218
  when "error", "all", nil then
195
- require "minitest/error_on_warning"
219
+ require_relative "minitest/error_on_warning"
196
220
  $VERBOSE = true
197
- ::Warning[:deprecated] = true if ruby27plus
221
+ ::Warning[:deprecated] = true
198
222
  else
199
- ::Warning[s.to_sym] = true if ruby27plus # check validity of category
223
+ ::Warning[s.to_sym] = true # check validity of category
200
224
  end
201
225
  end
202
226
 
@@ -253,22 +277,20 @@ module Minitest
253
277
  #
254
278
  # The overall structure of a run looks like this:
255
279
  #
280
+ # [Minitest.load_plugins] optional, called by user, or require what you want
256
281
  # Minitest.autorun
257
282
  # Minitest.run(args)
258
- # Minitest.load_plugins
259
283
  # Minitest.process_args
260
284
  # 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
285
+ # Minitest.run_all_suites(reporter, options)
286
+ # Runnable.runnables.each |runnable_klass|
287
+ # runnable_klass.run_suite(reporter, options)
288
+ # filtered_methods = runnable_klass.filter_runnable_methods options
289
+ # filtered_methods.each |runnable_method|
290
+ # runnable_klass.run(self, runnable_method, reporter)
291
+ # runnable_klass.new(runnable_method).run
268
292
 
269
293
  def self.run args = []
270
- self.load_plugins unless args.delete("--no-plugins") || ENV["MT_NO_PLUGINS"]
271
-
272
294
  options = process_args args
273
295
 
274
296
  Minitest.seed = options[:seed]
@@ -285,23 +307,24 @@ module Minitest
285
307
  self.parallel_executor.start if parallel_executor.respond_to? :start
286
308
  reporter.start
287
309
  begin
288
- __run reporter, options
310
+ run_all_suites reporter, options
311
+ finished = true
289
312
  rescue Interrupt
290
313
  warn "Interrupted. Exiting..."
291
314
  end
292
- self.parallel_executor.shutdown
315
+ self.parallel_executor.shutdown if parallel_executor.respond_to? :shutdown
293
316
 
294
317
  # might have been removed/replaced during init_plugins:
295
318
  summary = reporter.reporters.grep(SummaryReporter).first
296
319
 
297
320
  reporter.report
298
321
 
299
- return empty_run! options if summary && summary.count == 0
300
- reporter.passed?
322
+ return empty_run! options if finished && summary && summary.count == 0
323
+ finished and reporter.passed?
301
324
  end
302
325
 
303
326
  def self.empty_run! options # :nodoc:
304
- filter = options[:filter]
327
+ filter = options[:include]
305
328
  return true unless filter # no filter, but nothing ran == success
306
329
 
307
330
  warn "Nothing ran for filter: %s" % [filter]
@@ -320,17 +343,17 @@ module Minitest
320
343
  # Internal run method. Responsible for telling all Runnable
321
344
  # sub-classes to run.
322
345
 
323
- def self.__run reporter, options
346
+ def self.run_all_suites reporter, options
324
347
  suites = Runnable.runnables.shuffle
325
- parallel, serial = suites.partition { |s| s.test_order == :parallel }
348
+ parallel, serial = suites.partition { |s| s.run_order == :parallel }
326
349
 
327
350
  # If we run the parallel tests before the serial tests, the parallel tests
328
351
  # could run in parallel with the serial tests. This would be bad because
329
352
  # the serial tests won't lock around Reporter#record. Run the serial tests
330
353
  # first, so that after they complete, the parallel tests will lock when
331
354
  # recording results.
332
- serial.map { |suite| suite.run reporter, options } +
333
- parallel.map { |suite| suite.run reporter, options }
355
+ serial.map { |suite| suite.run_suite reporter, options } +
356
+ parallel.map { |suite| suite.run_suite reporter, options }
334
357
  end
335
358
 
336
359
  def self.filter_backtrace bt # :nodoc:
@@ -398,20 +421,30 @@ module Minitest
398
421
  reset
399
422
 
400
423
  ##
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.
424
+ # Returns an array of filtered +runnable_methods+. Uses
425
+ # options[:include] (--include arguments) and options[:exclude]
426
+ # (--exclude arguments) values to filter.
404
427
 
405
- def self.run reporter, options = {}
406
- pos = options[:filter]
428
+ def self.filter_runnable_methods options={}
429
+ pos = options[:include]
407
430
  neg = options[:exclude]
408
431
 
409
432
  pos = Regexp.new $1 if pos.kind_of?(String) && pos =~ %r%/(.*)/%
410
433
  neg = Regexp.new $1 if neg.kind_of?(String) && neg =~ %r%/(.*)/%
411
434
 
412
- filtered_methods = self.runnable_methods
435
+ # at most 1-2% slower than a 1-pass version, stop optimizing this
436
+ self.runnable_methods
413
437
  .select { |m| !pos || pos === m || pos === "#{self}##{m}" }
414
438
  .reject { |m| neg && (neg === m || neg === "#{self}##{m}") }
439
+ end
440
+
441
+ ##
442
+ # Responsible for running all runnable methods in a given class,
443
+ # each in its own instance. Each instance is passed to the
444
+ # reporter to record.
445
+
446
+ def Runnable.run_suite reporter, options = {}
447
+ filtered_methods = filter_runnable_methods options
415
448
 
416
449
  return if filtered_methods.empty?
417
450
 
@@ -426,12 +459,12 @@ module Minitest
426
459
  warn "Current: %s#%s %.2fs" % [self, name, Minitest.clock_time - t0]
427
460
  end
428
461
 
429
- with_info_handler reporter do
462
+ with_info_handler do
430
463
  filtered_methods.each do |method_name|
431
464
  name = method_name
432
465
  t0 = Minitest.clock_time
433
466
 
434
- run_one_method self, method_name, reporter
467
+ run self, method_name, reporter
435
468
  end
436
469
  end
437
470
  end
@@ -442,20 +475,20 @@ module Minitest
442
475
  # that subclasses can specialize the running of an individual
443
476
  # test. See Minitest::ParallelTest::ClassMethods for an example.
444
477
 
445
- def self.run_one_method klass, method_name, reporter
478
+ def Runnable.run klass, method_name, reporter
446
479
  reporter.prerecord klass, method_name
447
- reporter.record Minitest.run_one_method(klass, method_name)
480
+ reporter.record klass.new(method_name).run
448
481
  end
449
482
 
450
483
  ##
451
484
  # Defines the order to run tests (:random by default). Override
452
485
  # this or use a convenience method to change it for your tests.
453
486
 
454
- def self.test_order
487
+ def self.run_order
455
488
  :random
456
489
  end
457
490
 
458
- def self.with_info_handler reporter, &block # :nodoc:
491
+ def self.with_info_handler _reporter=nil, &block # :nodoc:
459
492
  on_signal ::Minitest.info_signal, @_info_handler, &block
460
493
  end
461
494
 
@@ -489,22 +522,6 @@ module Minitest
489
522
  @@runnables
490
523
  end
491
524
 
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
525
  def failure # :nodoc:
509
526
  self.failures.first
510
527
  end
@@ -572,7 +589,7 @@ module Minitest
572
589
  def skipped?
573
590
  raise NotImplementedError, "subclass responsibility"
574
591
  end
575
- end
592
+ end # Runnable
576
593
 
577
594
  ##
578
595
  # Shared code for anything that can get passed to a Reporter. See
@@ -624,7 +641,7 @@ module Minitest
624
641
  def error?
625
642
  self.failures.any? UnexpectedError
626
643
  end
627
- end
644
+ end # Reportable
628
645
 
629
646
  ##
630
647
  # This represents a test result in a clean way that can be
@@ -636,9 +653,6 @@ module Minitest
636
653
  class Result < Runnable
637
654
  include Minitest::Reportable
638
655
 
639
- undef_method :marshal_dump
640
- undef_method :marshal_load
641
-
642
656
  ##
643
657
  # The class name of the test result.
644
658
 
@@ -678,7 +692,7 @@ module Minitest
678
692
  "#{failure.result_label}:\n#{self.location}:\n#{failure.message}\n"
679
693
  }.join "\n"
680
694
  end
681
- end
695
+ end # Result
682
696
 
683
697
  ##
684
698
  # Defines the API for Reporters. Subclass this and override whatever
@@ -728,7 +742,7 @@ module Minitest
728
742
  def synchronize &block # :nodoc:
729
743
  @mutex.synchronize(&block)
730
744
  end
731
- end
745
+ end # AbstractReportera
732
746
 
733
747
  class Reporter < AbstractReporter # :nodoc:
734
748
  ##
@@ -883,7 +897,7 @@ module Minitest
883
897
  self.warnings = aggregate[UnexpectedWarning].size
884
898
  self.skips = aggregate[Skip].size
885
899
  end
886
- end
900
+ end # StatisticsReporter
887
901
 
888
902
  ##
889
903
  # A reporter that prints the header, summary, and failure details at
@@ -961,7 +975,7 @@ module Minitest
961
975
  "%d runs, %d assertions, %d failures, %d errors, %d skips%s" %
962
976
  [count, assertions, failures, errors, skips, extra.join]
963
977
  end
964
- end
978
+ end # SummaryReporter
965
979
 
966
980
  ##
967
981
  # Dispatch to multiple reporters as one.
@@ -998,8 +1012,7 @@ module Minitest
998
1012
 
999
1013
  def prerecord klass, name # :nodoc:
1000
1014
  self.reporters.each do |reporter|
1001
- # TODO: remove conditional for minitest 6
1002
- reporter.prerecord klass, name if reporter.respond_to? :prerecord
1015
+ reporter.prerecord klass, name
1003
1016
  end
1004
1017
  end
1005
1018
 
@@ -1012,7 +1025,7 @@ module Minitest
1012
1025
  def report # :nodoc:
1013
1026
  self.reporters.each(&:report)
1014
1027
  end
1015
- end
1028
+ end # CompositeReporter
1016
1029
 
1017
1030
  ##
1018
1031
  # Represents run failures.
@@ -1079,7 +1092,7 @@ module Minitest
1079
1092
  self.error.backtrace
1080
1093
  end
1081
1094
 
1082
- BASE_RE = %r%#{Dir.pwd}/% # :nodoc:
1095
+ BASE_RE = %r%#{Regexp.escape Dir.pwd}/% # :nodoc:
1083
1096
 
1084
1097
  def message # :nodoc:
1085
1098
  bt = Minitest.filter_backtrace(self.backtrace).join("\n ")
@@ -1125,16 +1138,6 @@ module Minitest
1125
1138
  "java" == platform
1126
1139
  end
1127
1140
 
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
1141
  ##
1139
1142
  # Is this running on mri?
1140
1143
 
@@ -1149,16 +1152,6 @@ module Minitest
1149
1152
  platform.include? "darwin"
1150
1153
  end
1151
1154
 
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
1155
  ##
1163
1156
  # Is this running on windows?
1164
1157
 
@@ -1204,12 +1197,6 @@ module Minitest
1204
1197
 
1205
1198
  self.backtrace_filter = BacktraceFilter.new
1206
1199
 
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
1200
  # :stopdoc:
1214
1201
 
1215
1202
  if defined? Process::CLOCK_MONOTONIC # :nodoc:
@@ -1232,4 +1219,4 @@ module Minitest
1232
1219
  # :startdoc:
1233
1220
  end
1234
1221
 
1235
- require "minitest/test"
1222
+ 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