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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/History.rdoc +373 -1
- data/Manifest.txt +16 -4
- data/README.rdoc +48 -118
- data/Rakefile +17 -2
- data/bin/minitest +5 -0
- data/design_rationale.rb +21 -19
- data/lib/hoe/minitest.rb +4 -2
- data/lib/minitest/assertions.rb +142 -124
- data/lib/minitest/autorun.rb +3 -11
- data/lib/minitest/benchmark.rb +9 -12
- data/lib/minitest/bisect.rb +304 -0
- data/lib/minitest/complete.rb +56 -0
- data/lib/minitest/compress.rb +94 -0
- data/lib/minitest/error_on_warning.rb +11 -0
- data/lib/minitest/expectations.rb +18 -0
- data/lib/minitest/find_minimal_combination.rb +127 -0
- data/lib/minitest/hell.rb +1 -1
- data/lib/minitest/manual_plugins.rb +4 -0
- data/lib/minitest/parallel.rb +10 -8
- data/lib/minitest/path_expander.rb +432 -0
- data/lib/minitest/pride.rb +2 -2
- data/lib/minitest/pride_plugin.rb +17 -24
- data/lib/minitest/server.rb +49 -0
- data/lib/minitest/server_plugin.rb +88 -0
- data/lib/minitest/spec.rb +27 -46
- data/lib/minitest/sprint.rb +105 -0
- data/lib/minitest/sprint_plugin.rb +39 -0
- data/lib/minitest/test.rb +32 -52
- data/lib/minitest/test_task.rb +68 -42
- data/lib/minitest.rb +361 -215
- data/test/minitest/metametameta.rb +33 -19
- data/test/minitest/test_bisect.rb +249 -0
- data/test/minitest/test_find_minimal_combination.rb +138 -0
- data/test/minitest/test_minitest_assertions.rb +311 -173
- data/test/minitest/test_minitest_benchmark.rb +15 -1
- data/test/minitest/test_minitest_reporter.rb +148 -23
- data/test/minitest/test_minitest_spec.rb +157 -132
- data/test/minitest/test_minitest_test.rb +270 -204
- data/test/minitest/test_minitest_test_task.rb +18 -7
- data/test/minitest/test_path_expander.rb +229 -0
- data/test/minitest/test_server.rb +146 -0
- data.tar.gz.sig +2 -2
- metadata +97 -37
- metadata.gz.sig +0 -0
- data/.autotest +0 -34
- data/lib/minitest/mock.rb +0 -323
- data/lib/minitest/unit.rb +0 -42
- 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
|
|
7
|
-
|
|
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
|
|
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 =
|
|
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(""
|
|
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
|
|
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.
|
|
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 =
|
|
86
|
-
Run options: #{flags.map { |s| s
|
|
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!(/\[[^\]:]
|
|
113
|
-
output.gsub!(/^(\s+)[^:]
|
|
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!(/
|
|
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
|