minitest 5.16.2 → 6.0.5

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 (50) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/History.rdoc +373 -1
  4. data/Manifest.txt +16 -4
  5. data/README.rdoc +48 -118
  6. data/Rakefile +17 -2
  7. data/bin/minitest +5 -0
  8. data/design_rationale.rb +21 -19
  9. data/lib/hoe/minitest.rb +4 -2
  10. data/lib/minitest/assertions.rb +142 -124
  11. data/lib/minitest/autorun.rb +3 -11
  12. data/lib/minitest/benchmark.rb +9 -12
  13. data/lib/minitest/bisect.rb +304 -0
  14. data/lib/minitest/complete.rb +56 -0
  15. data/lib/minitest/compress.rb +94 -0
  16. data/lib/minitest/error_on_warning.rb +11 -0
  17. data/lib/minitest/expectations.rb +18 -0
  18. data/lib/minitest/find_minimal_combination.rb +127 -0
  19. data/lib/minitest/hell.rb +1 -1
  20. data/lib/minitest/manual_plugins.rb +4 -0
  21. data/lib/minitest/parallel.rb +10 -8
  22. data/lib/minitest/path_expander.rb +432 -0
  23. data/lib/minitest/pride.rb +2 -2
  24. data/lib/minitest/pride_plugin.rb +17 -24
  25. data/lib/minitest/server.rb +49 -0
  26. data/lib/minitest/server_plugin.rb +88 -0
  27. data/lib/minitest/spec.rb +27 -46
  28. data/lib/minitest/sprint.rb +105 -0
  29. data/lib/minitest/sprint_plugin.rb +39 -0
  30. data/lib/minitest/test.rb +32 -52
  31. data/lib/minitest/test_task.rb +68 -42
  32. data/lib/minitest.rb +361 -215
  33. data/test/minitest/metametameta.rb +33 -19
  34. data/test/minitest/test_bisect.rb +249 -0
  35. data/test/minitest/test_find_minimal_combination.rb +138 -0
  36. data/test/minitest/test_minitest_assertions.rb +311 -173
  37. data/test/minitest/test_minitest_benchmark.rb +15 -1
  38. data/test/minitest/test_minitest_reporter.rb +148 -23
  39. data/test/minitest/test_minitest_spec.rb +157 -132
  40. data/test/minitest/test_minitest_test.rb +270 -204
  41. data/test/minitest/test_minitest_test_task.rb +18 -7
  42. data/test/minitest/test_path_expander.rb +229 -0
  43. data/test/minitest/test_server.rb +146 -0
  44. data.tar.gz.sig +2 -2
  45. metadata +97 -37
  46. metadata.gz.sig +0 -0
  47. data/.autotest +0 -34
  48. data/lib/minitest/mock.rb +0 -323
  49. data/lib/minitest/unit.rb +0 -42
  50. data/test/minitest/test_minitest_mock.rb +0 -1139
@@ -3,29 +3,38 @@ require "stringio"
3
3
  require "minitest/autorun"
4
4
 
5
5
  class Minitest::Test
6
- def clean s
7
- s.gsub(/^ {6}/, "")
6
+ def with_empty_backtrace_filter
7
+ with_backtrace_filter Minitest::BacktraceFilter.new %r%.% do
8
+ yield
9
+ end
8
10
  end
9
11
 
10
- def with_empty_backtrace_filter
12
+ def with_backtrace_filter filter
11
13
  original = Minitest.backtrace_filter
12
14
 
13
- obj = Minitest::BacktraceFilter.new
14
- def obj.filter _bt
15
- []
16
- end
17
-
18
15
  Minitest::Test.io_lock.synchronize do # try not to trounce in parallel
19
16
  begin
20
- Minitest.backtrace_filter = obj
17
+ Minitest.backtrace_filter = filter
21
18
  yield
22
19
  ensure
23
20
  Minitest.backtrace_filter = original
24
21
  end
25
22
  end
26
23
  end
27
- end
28
24
 
25
+ def error_on_warn?
26
+ defined?(Minitest::ErrorOnWarning)
27
+ end
28
+
29
+ def assert_deprecation re = /DEPRECATED/
30
+ re = // if $-w.nil? # "skip" if running `rake testW0`
31
+ assert_output "", re do
32
+ yield
33
+ end
34
+ rescue Minitest::UnexpectedWarning => e # raised if -Werror was used
35
+ assert_match re, e.message
36
+ end
37
+ end
29
38
 
30
39
  class FakeNamedTest < Minitest::Test
31
40
  @@count = 0
@@ -55,7 +64,7 @@ class MetaMetaMetaTestCase < Minitest::Test
55
64
  def run_tu_with_fresh_reporter flags = %w[--seed 42]
56
65
  options = Minitest.process_args flags
57
66
 
58
- @output = StringIO.new("".encode('UTF-8'))
67
+ @output = StringIO.new(+"")
59
68
 
60
69
  self.reporter = Minitest::CompositeReporter.new
61
70
  reporter << Minitest::SummaryReporter.new(@output, options)
@@ -64,13 +73,13 @@ class MetaMetaMetaTestCase < Minitest::Test
64
73
  with_stderr @output do
65
74
  reporter.start
66
75
 
67
- yield(reporter) if block_given?
76
+ yield reporter if block_given?
68
77
 
69
78
  @tus ||= [@tu]
70
79
  @tus.each do |tu|
71
80
  Minitest::Runnable.runnables.delete tu
72
81
 
73
- tu.run reporter, options
82
+ tu.run_suite reporter, options
74
83
  end
75
84
 
76
85
  reporter.report
@@ -82,8 +91,8 @@ class MetaMetaMetaTestCase < Minitest::Test
82
91
  end
83
92
 
84
93
  def assert_report expected, flags = %w[--seed 42], &block
85
- header = clean <<-EOM
86
- Run options: #{flags.map { |s| s =~ /\|/ ? s.inspect : s }.join " "}
94
+ header = <<~EOM
95
+ Run options: #{flags.map { |s| s.include?("|") ? s.inspect : s }.join " "}
87
96
 
88
97
  # Running:
89
98
 
@@ -105,15 +114,20 @@ class MetaMetaMetaTestCase < Minitest::Test
105
114
  output.gsub!(/0x[A-Fa-f0-9]+/, "0xXXX")
106
115
  output.gsub!(/ +$/, "")
107
116
 
117
+ file = ->(s) { s.start_with?("/") ? "FULLFILE" : "FILE" }
118
+
108
119
  if windows? then
109
120
  output.gsub!(/\[(?:[A-Za-z]:)?[^\]:]+:\d+\]/, "[FILE:LINE]")
110
- output.gsub!(/^(\s+)(?:[A-Za-z]:)?[^:]+:\d+:in/, '\1FILE:LINE:in')
121
+ output.gsub!(/^(\s+)(?:[A-Za-z]:)?[^:]+:\d+:in [`']/, '\1FILE:LINE:in \'')
111
122
  else
112
- output.gsub!(/\[[^\]:]+:\d+\]/, "[FILE:LINE]")
113
- output.gsub!(/^(\s+)[^:]+:\d+:in/, '\1FILE:LINE:in')
123
+ output.gsub!(/\[([^\]:]+):\d+\]/) { "[#{file[$1]}:LINE]" }
124
+ output.gsub!(/^(\s+)([^:]+):\d+:in [`']/) { "#{$1}#{file[$2]}:LINE:in '" }
114
125
  end
115
126
 
116
- output.gsub!(/( at )[^:]+:\d+/, '\1[FILE:LINE]')
127
+ output.gsub!(/in [`']block in (?:([^']+)[#.])?/, "in 'block in")
128
+ output.gsub!(/in [`'](?:([^']+)[#.])?/, "in '")
129
+
130
+ output.gsub!(/( at )([^:]+):\d+/) { "#{$1}[#{file[$2]}:LINE]" } # eval?
117
131
 
118
132
  output
119
133
  end
@@ -0,0 +1,249 @@
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
+ exp = "minitest -Ilib:test a.rb b.rb c.rb --seed 42"
32
+ act = bisect.build_files_cmd(files, rb, mt, cmd:"minitest")
33
+
34
+ assert_equal exp, act
35
+ end
36
+
37
+ def test_build_methods_cmd
38
+ cmd = "cmd"
39
+ assert_equal "cmd", bisect.build_methods_cmd(cmd)
40
+ end
41
+
42
+ def test_build_methods_cmd_verify
43
+ cmd = "cmd"
44
+ cul = []
45
+ bad = %w[A#test_1 B#test_2]
46
+
47
+ exp = "cmd -n \"/^(?:A#(?:test_1)|B#(?:test_2))$/\""
48
+
49
+ assert_equal exp, bisect.build_methods_cmd(cmd, cul, bad)
50
+ end
51
+
52
+ def test_build_methods_cmd_verify_same
53
+ cmd = "cmd"
54
+ cul = []
55
+ bad = %w[C#test_5 C#test_6]
56
+
57
+ exp = "cmd -n \"/^(?:C#(?:test_5|test_6))$/\""
58
+
59
+ assert_equal exp, bisect.build_methods_cmd(cmd, cul, bad)
60
+ end
61
+
62
+ def test_build_methods_cmd_full
63
+ cmd = "cmd"
64
+ cul = %w[A#test_1 A#test_2 B#test_3 B#test_4]
65
+ bad = %w[C#test_5 C#test_6]
66
+
67
+ a = "A#(?:test_1|test_2)"
68
+ b = "B#(?:test_3|test_4)"
69
+ c = "C#(?:test_5|test_6)"
70
+ exp = "cmd -n \"/^(?:#{a}|#{b}|#{c})$/\""
71
+
72
+ assert_equal exp, bisect.build_methods_cmd(cmd, cul, bad)
73
+ end
74
+
75
+ def test_build_re
76
+ bad = %w[A#test_1 B#test_2]
77
+
78
+ exp = "/^(?:A#(?:test_1)|B#(?:test_2))$/"
79
+
80
+ assert_equal exp, bisect.build_re(bad)
81
+ end
82
+
83
+ def test_build_re_same
84
+ bad = %w[C#test_5 C#test_6]
85
+
86
+ exp = "/^(?:C#(?:test_5|test_6))$/"
87
+
88
+ assert_equal exp, bisect.build_re(bad)
89
+ end
90
+
91
+ def test_build_re_class_escaping
92
+ bad = ["{}#[]"]
93
+
94
+ exp = "/^(?:\\{\\}#(?:\\[\\]))$/"
95
+
96
+ assert_equal exp, bisect.build_re(bad)
97
+ end
98
+
99
+ def test_build_re_method_escaping
100
+ bad = ["Some Class#It shouldn't care what the name is"]
101
+
102
+ exp = "/^(?:Some Class#(?:It shouldn\\'t care what the name is))$/"
103
+
104
+ assert_equal exp, bisect.build_re(bad)
105
+ end
106
+
107
+ def test_map_failures
108
+ bisect.failures =
109
+ {
110
+ "file.rb" => { "Class" => %w[test_method1 test_method2] },
111
+ "blah.rb" => { "Apple" => %w[test_method3 test_method4] },
112
+ }
113
+
114
+ exp = %w[
115
+ Apple#test_method3
116
+ Apple#test_method4
117
+ Class#test_method1
118
+ Class#test_method2
119
+ ]
120
+
121
+ assert_equal exp, bisect.map_failures
122
+ end
123
+
124
+ def test_minitest_result
125
+ bisect.minitest_result "file.rb", "TestClass", "test_method", [], 1, 1
126
+
127
+ assert_equal false, bisect.tainted
128
+ assert_empty bisect.failures
129
+ assert_equal ["TestClass#test_method"], bisect.culprits
130
+ end
131
+
132
+ def test_minitest_result_skip
133
+ fail = Minitest::Skip.new("woot")
134
+
135
+ bisect.minitest_result "file.rb", "TestClass", "test_method", [fail], 1, 1
136
+
137
+ assert_equal false, bisect.tainted
138
+ assert_empty bisect.failures
139
+ assert_equal ["TestClass#test_method"], bisect.culprits
140
+ end
141
+
142
+ def test_minitest_result_fail
143
+ fail = Minitest::Assertion.new "msg"
144
+
145
+ bisect.minitest_result "file.rb", "TestClass", "test_method", [fail], 1, 1
146
+
147
+ exp = {"file.rb" => {"TestClass" => ["test_method"] }}
148
+
149
+ assert_equal true, bisect.tainted
150
+ assert_equal exp, bisect.failures
151
+ assert_empty bisect.culprits
152
+ end
153
+
154
+ def test_minitest_result_error
155
+ fail = Minitest::UnexpectedError.new RuntimeError.new("woot")
156
+
157
+ bisect.minitest_result "file.rb", "TestClass", "test_method", [fail], 1, 1
158
+
159
+ exp = {"file.rb" => {"TestClass" => ["test_method"] }}
160
+
161
+ assert_equal true, bisect.tainted
162
+ assert_equal exp, bisect.failures
163
+ assert_empty bisect.culprits
164
+ end
165
+
166
+ def test_minitest_start
167
+ bisect.failures["file.rb"]["Class"] << "test_bad1"
168
+
169
+ bisect.minitest_start
170
+
171
+ assert_empty bisect.failures
172
+ end
173
+
174
+ def test_reset
175
+ bisect.seen_bad = true
176
+ bisect.tainted = true
177
+ bisect.failures["file.rb"]["Class"] << "test_bad1"
178
+ bisect.culprits << "A#test_1" << "B#test_2"
179
+
180
+ bisect.reset
181
+
182
+ assert_equal false, bisect.seen_bad
183
+ assert_equal false, bisect.tainted
184
+ assert_empty bisect.failures
185
+ assert_equal %w[A#test_1 B#test_2], bisect.culprits
186
+ end
187
+
188
+ def test_run
189
+ skip "Need to write test_run"
190
+ end
191
+
192
+ def test_time_it
193
+ exp = /\Ado stuff: in 0.\d\d sec\n\z/
194
+
195
+ assert_output exp, "" do
196
+ bisect.time_it "do stuff:", "echo you should not see me"
197
+ end
198
+ end
199
+ end
200
+
201
+ class TestMinitest::TestBisect::TestPathExpander < Minitest::Test
202
+ def setup
203
+ @orig_i = $LOAD_PATH.dup
204
+ @orig_w = $VERBOSE
205
+ @orig_d = $DEBUG
206
+ end
207
+
208
+ def teardown
209
+ $LOAD_PATH.replace @orig_i
210
+ $VERBOSE = @orig_w
211
+ $DEBUG = @orig_d
212
+ end
213
+
214
+ def test_sanity
215
+ args = %w[1 -Iblah 2 -d 3 -w 4 5 6 lib/hoe] # lib to not have any test files
216
+
217
+ mtbpe = Minitest::Bisect::PathExpander
218
+ expander = mtbpe.new args
219
+
220
+ files = expander.process.to_a # to_a forces process -> files
221
+
222
+ assert_empty files
223
+ assert_empty $LOAD_PATH - @orig_i
224
+ assert_equal %w[-Iblah -d -w], expander.rb_flags
225
+ assert_equal %w[1 2 3 4 5 6], args
226
+ assert_same mtbpe::TEST_GLOB, expander.glob
227
+ end
228
+
229
+ def test_process_flags
230
+ args = %w[1 -Iblah 2 -d 3 -w 4 5 6]
231
+
232
+ expander = Minitest::Bisect::PathExpander.new args
233
+
234
+ exp_files = %w[1 2 3 4 5 6]
235
+ exp_flags = %w[-Iblah -d -w]
236
+
237
+ files = expander.process_flags(args)
238
+
239
+ assert_equal files, exp_files
240
+
241
+ # process_flags only filters and does not mutate args
242
+ assert_same args, expander.args
243
+ refute_equal args, exp_files
244
+ refute_equal files, args
245
+
246
+ # separates rb_flags out for separate handling
247
+ assert_equal exp_flags, expander.rb_flags
248
+ end
249
+ end
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/ruby -w
2
+
3
+ $: << "." << "lib"
4
+
5
+ require "minitest/autorun"
6
+ require "minitest/find_minimal_combination"
7
+
8
+ describe Array, :find_minimal_combination do
9
+ def check(*bad)
10
+ lambda { |sample| bad & sample == bad }
11
+ end
12
+
13
+ def record_and_check(tests, *bad)
14
+ lambda { |test| tests << test.join; bad & test == bad }
15
+ end
16
+
17
+ def parse_trials s
18
+ s.lines.map { |s| s.chomp.sub(/#.*/, '').delete " " }.reject(&:empty?)
19
+ end
20
+
21
+ def assert_steps input, bad, exp
22
+ tests = []
23
+
24
+ found = input.find_minimal_combination(&record_and_check(tests, *bad))
25
+
26
+ assert_equal bad, found, "algorithm is bad"
27
+
28
+ assert_equal parse_trials(exp), tests
29
+ end
30
+
31
+ HEX = "0123456789ABCDEF".chars.to_a
32
+
33
+ # lvl collection
34
+ #
35
+ # 0 | A
36
+ # 1 | B C
37
+ # 2 | D E F G
38
+ # 3 | H I J K L M N O
39
+ # |
40
+ # 4 | 0123456789ABCDEF
41
+
42
+ def test_ordering_best_case_1
43
+ ary = HEX
44
+ bad = %w[0]
45
+ exp = <<~EOT
46
+ #123456789ABCDEF
47
+ 01234567 # HIT! -- level 1 = B, C
48
+ 0123 # HIT! -- level 2 = D, E
49
+ 01 # HIT! -- level 3 = H, I
50
+ 0 # HIT!
51
+ EOT
52
+
53
+ assert_steps ary, bad, exp
54
+ end
55
+
56
+ def test_ordering_best_case_2
57
+ ary = HEX
58
+ bad = %w[0 1]
59
+ exp = <<~EOT
60
+ 01234567 # HIT! -- level 1 = B, C
61
+ 0123 # HIT! -- level 2 = D, E
62
+ 01 # HIT! -- level 3 = H, I
63
+ 0 # miss -- level 4 = 0, 1, n_combos = 1
64
+ 1 # miss
65
+ 01 # HIT! -- level 3 = H, n_combos = 2
66
+ EOT
67
+
68
+ assert_steps ary, bad, exp
69
+ end
70
+
71
+ def test_ordering
72
+ ary = HEX
73
+ bad = %w[1 F]
74
+ exp = <<~EOT
75
+ 01234567 # miss -- level 1 = B, C
76
+ 89ABCDEF # miss
77
+ 0123 89AB # miss -- level 2 = DF, DG, EF, EG
78
+ 0123 CDEF # HIT!
79
+ 01 CD # miss -- level 3 = HN, HO
80
+ 01 EF # HIT!
81
+ 0 E # miss -- level 4 = 0E, 0F, 1E, 1F
82
+ 0 F # miss
83
+ 1 E # miss
84
+ 1 F # HIT!
85
+ EOT
86
+
87
+ assert_steps ary, bad, exp
88
+ end
89
+
90
+ def self.test_find_minimal_combination max, *bad
91
+ define_method "%s_%s_%s" % [__method__, max, bad.join("_")] do
92
+ a = (1..max).to_a
93
+
94
+ assert_equal bad, a.find_minimal_combination(&check(*bad))
95
+ end
96
+ end
97
+
98
+ def self.test_find_minimal_combination_and_count max, nsteps, *bad
99
+ define_method "%s_%s_%s_%s" % [__method__, max, nsteps, bad.join("_")] do
100
+ a = (1..max).to_a
101
+
102
+ found, count = a.find_minimal_combination_and_count(&check(*bad))
103
+
104
+ assert_equal bad, found
105
+ assert_equal nsteps, count
106
+ end
107
+ end
108
+
109
+ test_find_minimal_combination 8, 5
110
+ test_find_minimal_combination 8, 2, 7
111
+ test_find_minimal_combination 8, 1, 2, 7
112
+ test_find_minimal_combination 8, 1, 4, 7
113
+ test_find_minimal_combination 8, 1, 3, 5, 7
114
+
115
+ test_find_minimal_combination 9, 5
116
+ test_find_minimal_combination 9, 9
117
+ test_find_minimal_combination 9, 2, 7
118
+ test_find_minimal_combination 9, 1, 2, 7
119
+ test_find_minimal_combination 9, 1, 4, 7
120
+ test_find_minimal_combination 9, 1, 3, 5, 7
121
+
122
+ test_find_minimal_combination 1023, 5
123
+ test_find_minimal_combination 1023, 1005
124
+ test_find_minimal_combination 1023, 802, 907
125
+ test_find_minimal_combination 1023, 7, 15, 166, 1001
126
+ test_find_minimal_combination 1023, 1000, 1001, 1002
127
+ test_find_minimal_combination 1023, 1001, 1003, 1005, 1007
128
+ test_find_minimal_combination 1024, 1001, 1003, 1005, 1007
129
+ test_find_minimal_combination 1024, 1, 1024
130
+
131
+ test_find_minimal_combination_and_count 1024, 12, 1, 2
132
+ test_find_minimal_combination_and_count 1024, 23, 1, 1023
133
+ test_find_minimal_combination_and_count 1024, 24, 1, 1024
134
+ test_find_minimal_combination_and_count 1023, 26, 1, 1023
135
+
136
+ test_find_minimal_combination_and_count 1024, 93, 1001, 1003, 1005, 1007
137
+ test_find_minimal_combination_and_count 1023, 93, 1001, 1003, 1005, 1007
138
+ end