minitest 5.25.5 → 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 +132 -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 +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 +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 +44 -20
  29. data/lib/minitest.rb +99 -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_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 +149 -0
  40. data.tar.gz.sig +0 -0
  41. metadata +58 -25
  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.1" # :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,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,22 +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)
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
290
+ # Minitest.run_all_suites(reporter, options)
291
+ # Runnable.runnables.each |runnable_klass|
292
+ # runnable_klass.run_suite(reporter, options)
293
+ # filtered_methods = runnable_klass.filter_runnable_methods options
294
+ # filtered_methods.each |runnable_method|
295
+ # runnable_klass.run(self, runnable_method, reporter)
296
+ # runnable_klass.new(runnable_method).run
268
297
 
269
298
  def self.run args = []
270
- self.load_plugins unless args.delete("--no-plugins") || ENV["MT_NO_PLUGINS"]
271
-
272
299
  options = process_args args
273
300
 
274
301
  Minitest.seed = options[:seed]
@@ -285,23 +312,24 @@ module Minitest
285
312
  self.parallel_executor.start if parallel_executor.respond_to? :start
286
313
  reporter.start
287
314
  begin
288
- __run reporter, options
315
+ run_all_suites reporter, options
316
+ finished = true
289
317
  rescue Interrupt
290
318
  warn "Interrupted. Exiting..."
291
319
  end
292
- self.parallel_executor.shutdown
320
+ self.parallel_executor.shutdown if parallel_executor.respond_to? :shutdown
293
321
 
294
322
  # might have been removed/replaced during init_plugins:
295
323
  summary = reporter.reporters.grep(SummaryReporter).first
296
324
 
297
325
  reporter.report
298
326
 
299
- return empty_run! options if summary && summary.count == 0
300
- reporter.passed?
327
+ return empty_run! options if finished && summary && summary.count == 0
328
+ finished and reporter.passed?
301
329
  end
302
330
 
303
331
  def self.empty_run! options # :nodoc:
304
- filter = options[:filter]
332
+ filter = options[:include]
305
333
  return true unless filter # no filter, but nothing ran == success
306
334
 
307
335
  warn "Nothing ran for filter: %s" % [filter]
@@ -320,17 +348,17 @@ module Minitest
320
348
  # Internal run method. Responsible for telling all Runnable
321
349
  # sub-classes to run.
322
350
 
323
- def self.__run reporter, options
351
+ def self.run_all_suites reporter, options
324
352
  suites = Runnable.runnables.shuffle
325
- parallel, serial = suites.partition { |s| s.test_order == :parallel }
353
+ parallel, serial = suites.partition { |s| s.run_order == :parallel }
326
354
 
327
355
  # If we run the parallel tests before the serial tests, the parallel tests
328
356
  # could run in parallel with the serial tests. This would be bad because
329
357
  # the serial tests won't lock around Reporter#record. Run the serial tests
330
358
  # first, so that after they complete, the parallel tests will lock when
331
359
  # recording results.
332
- serial.map { |suite| suite.run reporter, options } +
333
- 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 }
334
362
  end
335
363
 
336
364
  def self.filter_backtrace bt # :nodoc:
@@ -398,20 +426,30 @@ module Minitest
398
426
  reset
399
427
 
400
428
  ##
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.
429
+ # Returns an array of filtered +runnable_methods+. Uses
430
+ # options[:include] (--include arguments) and options[:exclude]
431
+ # (--exclude arguments) values to filter.
404
432
 
405
- def self.run reporter, options = {}
406
- pos = options[:filter]
433
+ def self.filter_runnable_methods options={}
434
+ pos = options[:include]
407
435
  neg = options[:exclude]
408
436
 
409
437
  pos = Regexp.new $1 if pos.kind_of?(String) && pos =~ %r%/(.*)/%
410
438
  neg = Regexp.new $1 if neg.kind_of?(String) && neg =~ %r%/(.*)/%
411
439
 
412
- filtered_methods = self.runnable_methods
440
+ # at most 1-2% slower than a 1-pass version, stop optimizing this
441
+ self.runnable_methods
413
442
  .select { |m| !pos || pos === m || pos === "#{self}##{m}" }
414
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
415
453
 
416
454
  return if filtered_methods.empty?
417
455
 
@@ -426,12 +464,12 @@ module Minitest
426
464
  warn "Current: %s#%s %.2fs" % [self, name, Minitest.clock_time - t0]
427
465
  end
428
466
 
429
- with_info_handler reporter do
467
+ with_info_handler do
430
468
  filtered_methods.each do |method_name|
431
469
  name = method_name
432
470
  t0 = Minitest.clock_time
433
471
 
434
- run_one_method self, method_name, reporter
472
+ run self, method_name, reporter
435
473
  end
436
474
  end
437
475
  end
@@ -442,20 +480,20 @@ module Minitest
442
480
  # that subclasses can specialize the running of an individual
443
481
  # test. See Minitest::ParallelTest::ClassMethods for an example.
444
482
 
445
- def self.run_one_method klass, method_name, reporter
483
+ def Runnable.run klass, method_name, reporter
446
484
  reporter.prerecord klass, method_name
447
- reporter.record Minitest.run_one_method(klass, method_name)
485
+ reporter.record klass.new(method_name).run
448
486
  end
449
487
 
450
488
  ##
451
489
  # Defines the order to run tests (:random by default). Override
452
490
  # this or use a convenience method to change it for your tests.
453
491
 
454
- def self.test_order
492
+ def self.run_order
455
493
  :random
456
494
  end
457
495
 
458
- def self.with_info_handler reporter, &block # :nodoc:
496
+ def self.with_info_handler _reporter=nil, &block # :nodoc:
459
497
  on_signal ::Minitest.info_signal, @_info_handler, &block
460
498
  end
461
499
 
@@ -489,22 +527,6 @@ module Minitest
489
527
  @@runnables
490
528
  end
491
529
 
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
530
  def failure # :nodoc:
509
531
  self.failures.first
510
532
  end
@@ -572,7 +594,7 @@ module Minitest
572
594
  def skipped?
573
595
  raise NotImplementedError, "subclass responsibility"
574
596
  end
575
- end
597
+ end # Runnable
576
598
 
577
599
  ##
578
600
  # Shared code for anything that can get passed to a Reporter. See
@@ -624,7 +646,7 @@ module Minitest
624
646
  def error?
625
647
  self.failures.any? UnexpectedError
626
648
  end
627
- end
649
+ end # Reportable
628
650
 
629
651
  ##
630
652
  # This represents a test result in a clean way that can be
@@ -636,9 +658,6 @@ module Minitest
636
658
  class Result < Runnable
637
659
  include Minitest::Reportable
638
660
 
639
- undef_method :marshal_dump
640
- undef_method :marshal_load
641
-
642
661
  ##
643
662
  # The class name of the test result.
644
663
 
@@ -678,7 +697,7 @@ module Minitest
678
697
  "#{failure.result_label}:\n#{self.location}:\n#{failure.message}\n"
679
698
  }.join "\n"
680
699
  end
681
- end
700
+ end # Result
682
701
 
683
702
  ##
684
703
  # Defines the API for Reporters. Subclass this and override whatever
@@ -728,7 +747,7 @@ module Minitest
728
747
  def synchronize &block # :nodoc:
729
748
  @mutex.synchronize(&block)
730
749
  end
731
- end
750
+ end # AbstractReportera
732
751
 
733
752
  class Reporter < AbstractReporter # :nodoc:
734
753
  ##
@@ -883,7 +902,7 @@ module Minitest
883
902
  self.warnings = aggregate[UnexpectedWarning].size
884
903
  self.skips = aggregate[Skip].size
885
904
  end
886
- end
905
+ end # StatisticsReporter
887
906
 
888
907
  ##
889
908
  # A reporter that prints the header, summary, and failure details at
@@ -961,7 +980,7 @@ module Minitest
961
980
  "%d runs, %d assertions, %d failures, %d errors, %d skips%s" %
962
981
  [count, assertions, failures, errors, skips, extra.join]
963
982
  end
964
- end
983
+ end # SummaryReporter
965
984
 
966
985
  ##
967
986
  # Dispatch to multiple reporters as one.
@@ -998,8 +1017,7 @@ module Minitest
998
1017
 
999
1018
  def prerecord klass, name # :nodoc:
1000
1019
  self.reporters.each do |reporter|
1001
- # TODO: remove conditional for minitest 6
1002
- reporter.prerecord klass, name if reporter.respond_to? :prerecord
1020
+ reporter.prerecord klass, name
1003
1021
  end
1004
1022
  end
1005
1023
 
@@ -1012,7 +1030,7 @@ module Minitest
1012
1030
  def report # :nodoc:
1013
1031
  self.reporters.each(&:report)
1014
1032
  end
1015
- end
1033
+ end # CompositeReporter
1016
1034
 
1017
1035
  ##
1018
1036
  # Represents run failures.
@@ -1079,7 +1097,7 @@ module Minitest
1079
1097
  self.error.backtrace
1080
1098
  end
1081
1099
 
1082
- BASE_RE = %r%#{Dir.pwd}/% # :nodoc:
1100
+ BASE_RE = %r%#{Regexp.escape Dir.pwd}/% # :nodoc:
1083
1101
 
1084
1102
  def message # :nodoc:
1085
1103
  bt = Minitest.filter_backtrace(self.backtrace).join("\n ")
@@ -1125,16 +1143,6 @@ module Minitest
1125
1143
  "java" == platform
1126
1144
  end
1127
1145
 
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
1146
  ##
1139
1147
  # Is this running on mri?
1140
1148
 
@@ -1149,16 +1157,6 @@ module Minitest
1149
1157
  platform.include? "darwin"
1150
1158
  end
1151
1159
 
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
1160
  ##
1163
1161
  # Is this running on windows?
1164
1162
 
@@ -1204,12 +1202,6 @@ module Minitest
1204
1202
 
1205
1203
  self.backtrace_filter = BacktraceFilter.new
1206
1204
 
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
1205
  # :stopdoc:
1214
1206
 
1215
1207
  if defined? Process::CLOCK_MONOTONIC # :nodoc:
@@ -1232,4 +1224,4 @@ module Minitest
1232
1224
  # :startdoc:
1233
1225
  end
1234
1226
 
1235
- 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