test-unit 3.1.5 → 3.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/BSDL +24 -0
- data/COPYING +41 -41
- data/README.md +24 -17
- data/Rakefile +21 -24
- data/doc/text/getting-started.md +246 -0
- data/doc/text/news.md +797 -56
- data/lib/test/unit/assertion-failed-error.rb +35 -0
- data/lib/test/unit/assertions.rb +542 -220
- data/lib/test/unit/attribute.rb +78 -4
- data/lib/test/unit/auto-runner-loader.rb +17 -0
- data/lib/test/unit/autorunner.rb +175 -78
- data/lib/test/unit/code-snippet-fetcher.rb +7 -7
- data/lib/test/unit/collector/descendant.rb +1 -0
- data/lib/test/unit/collector/dir.rb +4 -2
- data/lib/test/unit/collector/load.rb +25 -15
- data/lib/test/unit/collector/objectspace.rb +1 -0
- data/lib/test/unit/collector.rb +31 -0
- data/lib/test/unit/color-scheme.rb +29 -2
- data/lib/test/unit/data-sets.rb +127 -0
- data/lib/test/unit/data.rb +121 -12
- data/lib/test/unit/diff.rb +10 -11
- data/lib/test/unit/fixture.rb +77 -27
- data/lib/test/unit/notification.rb +9 -7
- data/lib/test/unit/omission.rb +34 -31
- data/lib/test/unit/pending.rb +12 -11
- data/lib/test/unit/priority.rb +7 -5
- data/lib/test/unit/runner/console.rb +20 -1
- data/lib/test/unit/test-suite-creator.rb +30 -9
- data/lib/test/unit/testcase.rb +349 -196
- data/lib/test/unit/testresult.rb +7 -0
- data/lib/test/unit/testsuite.rb +1 -1
- data/lib/test/unit/ui/console/testrunner.rb +171 -60
- data/lib/test/unit/ui/emacs/testrunner.rb +5 -5
- data/lib/test/unit/ui/testrunnermediator.rb +9 -7
- data/lib/test/unit/util/backtracefilter.rb +17 -5
- data/lib/test/unit/util/memory-usage.rb +47 -0
- data/lib/test/unit/util/observable.rb +2 -2
- data/lib/test/unit/util/output.rb +5 -4
- data/lib/test/unit/util/procwrapper.rb +4 -4
- data/lib/test/unit/version.rb +1 -1
- data/lib/test/unit/warning.rb +3 -0
- data/lib/test/unit.rb +177 -161
- data/lib/test-unit.rb +2 -17
- metadata +20 -94
- data/GPL +0 -339
- data/LGPL +0 -502
- data/test/collector/test-descendant.rb +0 -178
- data/test/collector/test-load.rb +0 -442
- data/test/collector/test_dir.rb +0 -406
- data/test/collector/test_objectspace.rb +0 -100
- data/test/fixtures/header-label.csv +0 -3
- data/test/fixtures/header-label.tsv +0 -3
- data/test/fixtures/header.csv +0 -3
- data/test/fixtures/header.tsv +0 -3
- data/test/fixtures/no-header.csv +0 -2
- data/test/fixtures/no-header.tsv +0 -2
- data/test/fixtures/plus.csv +0 -3
- data/test/run-test.rb +0 -22
- data/test/test-assertions.rb +0 -2157
- data/test/test-attribute-matcher.rb +0 -38
- data/test/test-attribute.rb +0 -123
- data/test/test-code-snippet.rb +0 -37
- data/test/test-color-scheme.rb +0 -82
- data/test/test-color.rb +0 -47
- data/test/test-data.rb +0 -281
- data/test/test-diff.rb +0 -518
- data/test/test-emacs-runner.rb +0 -60
- data/test/test-error.rb +0 -26
- data/test/test-failure.rb +0 -33
- data/test/test-fault-location-detector.rb +0 -163
- data/test/test-fixture.rb +0 -659
- data/test/test-notification.rb +0 -33
- data/test/test-omission.rb +0 -81
- data/test/test-pending.rb +0 -70
- data/test/test-priority.rb +0 -173
- data/test/test-test-case.rb +0 -1171
- data/test/test-test-result.rb +0 -113
- data/test/test-test-suite-creator.rb +0 -97
- data/test/test-test-suite.rb +0 -150
- data/test/testunit-test-util.rb +0 -31
- data/test/ui/test_testrunmediator.rb +0 -20
- data/test/util/test-method-owner-finder.rb +0 -38
- data/test/util/test-output.rb +0 -11
- data/test/util/test_backtracefilter.rb +0 -41
- data/test/util/test_observable.rb +0 -102
- data/test/util/test_procwrapper.rb +0 -36
data/lib/test/unit/fixture.rb
CHANGED
@@ -24,9 +24,11 @@ module Test
|
|
24
24
|
attr_reader :teardown
|
25
25
|
def initialize(test_case)
|
26
26
|
@test_case = test_case
|
27
|
-
@setup = HookPoint.new(:after => :append)
|
28
|
-
@cleanup = HookPoint.new(:before => :prepend)
|
29
|
-
@teardown = HookPoint.new(:before => :prepend)
|
27
|
+
@setup = HookPoint.new(@test_case, :setup, :after => :append)
|
28
|
+
@cleanup = HookPoint.new(@test_case, :cleanup, :before => :prepend)
|
29
|
+
@teardown = HookPoint.new(@test_case, :teardown, :before => :prepend)
|
30
|
+
@cached_before_callbacks = {}
|
31
|
+
@cached_after_callbacks = {}
|
30
32
|
end
|
31
33
|
|
32
34
|
def [](type)
|
@@ -41,6 +43,19 @@ module Test
|
|
41
43
|
end
|
42
44
|
|
43
45
|
def before_callbacks(type)
|
46
|
+
@cached_before_callbacks[type] ||= collect_before_callbacks(type)
|
47
|
+
end
|
48
|
+
|
49
|
+
def after_callbacks(type)
|
50
|
+
@cached_after_callbacks[type] ||= collect_after_callbacks(type)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def target_test_cases
|
55
|
+
@cached_target_test_cases ||= collect_target_test_cases
|
56
|
+
end
|
57
|
+
|
58
|
+
def collect_before_callbacks(type)
|
44
59
|
prepend_callbacks = []
|
45
60
|
append_callbacks = []
|
46
61
|
target_test_cases.each do |ancestor|
|
@@ -51,7 +66,7 @@ module Test
|
|
51
66
|
merge_callbacks(prepend_callbacks, append_callbacks)
|
52
67
|
end
|
53
68
|
|
54
|
-
def
|
69
|
+
def collect_after_callbacks(type)
|
55
70
|
prepend_callbacks = []
|
56
71
|
append_callbacks = []
|
57
72
|
target_test_cases.each do |ancestor|
|
@@ -62,11 +77,6 @@ module Test
|
|
62
77
|
merge_callbacks(prepend_callbacks, append_callbacks)
|
63
78
|
end
|
64
79
|
|
65
|
-
private
|
66
|
-
def target_test_cases
|
67
|
-
@cached_target_test_cases ||= collect_target_test_cases
|
68
|
-
end
|
69
|
-
|
70
80
|
def collect_target_test_cases
|
71
81
|
ancestors = @test_case.ancestors
|
72
82
|
base_index = ancestors.index(::Test::Unit::Fixture)
|
@@ -89,8 +99,11 @@ module Test
|
|
89
99
|
end
|
90
100
|
|
91
101
|
class HookPoint
|
92
|
-
def initialize(default_options)
|
102
|
+
def initialize(test_case, type, default_options)
|
103
|
+
@test_case = test_case
|
104
|
+
@type = type
|
93
105
|
@default_options = default_options
|
106
|
+
@callbacks = {}
|
94
107
|
@before_prepend_callbacks = []
|
95
108
|
@before_append_callbacks = []
|
96
109
|
@after_prepend_callbacks = []
|
@@ -112,11 +125,32 @@ module Test
|
|
112
125
|
end
|
113
126
|
before_how = options[:before]
|
114
127
|
after_how = options[:after]
|
115
|
-
|
128
|
+
if method_name_or_callback.respond_to?(:call)
|
129
|
+
callback = method_name_or_callback
|
130
|
+
method_name = callback_method_name(callback)
|
131
|
+
@test_case.attribute(:source_location,
|
132
|
+
callback.source_location,
|
133
|
+
method_name)
|
134
|
+
# For Ruby 2.6 or earlier. callback may be GC-ed. If
|
135
|
+
# callback is GC-ed, callback_method_name may be
|
136
|
+
# duplicated because callback_method_name uses callback.object_id.
|
137
|
+
# See also: https://github.com/test-unit/test-unit/issues/179
|
138
|
+
@callbacks[callback] = true
|
139
|
+
@test_case.__send__(:define_method, method_name, &callback)
|
140
|
+
else
|
141
|
+
method_name = method_name_or_callback
|
142
|
+
end
|
143
|
+
add_callback(method_name, before_how, after_how)
|
116
144
|
end
|
117
145
|
|
118
146
|
def unregister(method_name_or_callback)
|
119
|
-
|
147
|
+
if method_name_or_callback.respond_to?(:call)
|
148
|
+
callback = method_name_or_callback
|
149
|
+
method_name = callback_method_name(callback)
|
150
|
+
else
|
151
|
+
method_name = method_name_or_callback
|
152
|
+
end
|
153
|
+
@unregistered_callbacks << method_name
|
120
154
|
end
|
121
155
|
|
122
156
|
def before_prepend_callbacks
|
@@ -145,6 +179,10 @@ module Test
|
|
145
179
|
[:prepend, :append].include?(options[key])
|
146
180
|
end
|
147
181
|
|
182
|
+
def callback_method_name(callback)
|
183
|
+
"#{@type}_#{callback.object_id}"
|
184
|
+
end
|
185
|
+
|
148
186
|
def add_callback(method_name_or_callback, before_how, after_how)
|
149
187
|
case before_how
|
150
188
|
when :prepend
|
@@ -208,38 +246,50 @@ module Test
|
|
208
246
|
end
|
209
247
|
|
210
248
|
private
|
211
|
-
def run_fixture(type, options={})
|
212
|
-
[
|
249
|
+
def run_fixture(type, options={}, &block)
|
250
|
+
fixtures = [
|
213
251
|
self.class.fixture.before_callbacks(type),
|
214
252
|
type,
|
215
253
|
self.class.fixture.after_callbacks(type),
|
216
|
-
].flatten
|
217
|
-
|
254
|
+
].flatten
|
255
|
+
if block
|
256
|
+
runner = create_fixtures_runner(fixtures, options, &block)
|
257
|
+
runner.call
|
258
|
+
else
|
259
|
+
fixtures.each do |method_name|
|
260
|
+
run_fixture_callback(method_name, options)
|
261
|
+
end
|
218
262
|
end
|
219
263
|
end
|
220
264
|
|
221
|
-
def
|
222
|
-
if
|
223
|
-
|
224
|
-
instance_eval(&method_name_or_callback)
|
225
|
-
end
|
265
|
+
def create_fixtures_runner(fixtures, options, &block)
|
266
|
+
if fixtures.empty?
|
267
|
+
block
|
226
268
|
else
|
227
|
-
|
228
|
-
|
229
|
-
|
269
|
+
last_fixture = fixtures.pop
|
270
|
+
create_fixtures_runner(fixtures, options) do
|
271
|
+
block_is_called = false
|
272
|
+
run_fixture_callback(last_fixture, options) do
|
273
|
+
block_is_called = true
|
274
|
+
block.call
|
275
|
+
end
|
276
|
+
block.call unless block_is_called
|
230
277
|
end
|
231
278
|
end
|
279
|
+
end
|
232
280
|
|
281
|
+
def run_fixture_callback(method_name, options, &block)
|
282
|
+
return unless respond_to?(method_name, true)
|
233
283
|
begin
|
234
|
-
|
284
|
+
__send__(method_name, &block)
|
235
285
|
rescue Exception
|
236
286
|
raise unless options[:handle_exception]
|
237
287
|
raise unless handle_exception($!)
|
238
288
|
end
|
239
289
|
end
|
240
290
|
|
241
|
-
def run_setup
|
242
|
-
run_fixture(:setup)
|
291
|
+
def run_setup(&block)
|
292
|
+
run_fixture(:setup, &block)
|
243
293
|
end
|
244
294
|
|
245
295
|
def run_cleanup
|
@@ -65,15 +65,17 @@ module Test
|
|
65
65
|
# Notify some information.
|
66
66
|
#
|
67
67
|
# Example:
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
68
|
+
#
|
69
|
+
# def test_notification
|
70
|
+
# notify("I'm here!")
|
71
|
+
# # Reached here
|
72
|
+
# notify("Special!") if special_case?
|
73
|
+
# # Reached here too
|
74
|
+
# end
|
74
75
|
#
|
75
76
|
# options:
|
76
|
-
#
|
77
|
+
#
|
78
|
+
# :backtrace override backtrace.
|
77
79
|
def notify(message, options={}, &block)
|
78
80
|
backtrace = filter_backtrace(options[:backtrace] || caller)
|
79
81
|
notification = Notification.new(name, backtrace, message,
|
data/lib/test/unit/omission.rb
CHANGED
@@ -65,17 +65,18 @@ module Test
|
|
65
65
|
# Omit the test or part of the test.
|
66
66
|
#
|
67
67
|
# Example:
|
68
|
-
# def test_omission
|
69
|
-
# omit
|
70
|
-
# # Not reached here
|
71
|
-
# end
|
72
68
|
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
# # Not
|
69
|
+
# def test_omission
|
70
|
+
# omit
|
71
|
+
# # Not reached here
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# def test_omission_with_here
|
75
|
+
# omit do
|
76
|
+
# # Not ran here
|
77
|
+
# end
|
78
|
+
# # Reached here
|
76
79
|
# end
|
77
|
-
# # Reached here
|
78
|
-
# end
|
79
80
|
def omit(message=nil, &block)
|
80
81
|
message ||= "omitted."
|
81
82
|
if block_given?
|
@@ -91,20 +92,21 @@ module Test
|
|
91
92
|
# true.
|
92
93
|
#
|
93
94
|
# Example:
|
94
|
-
# def test_omission
|
95
|
-
# omit_if("".empty?)
|
96
|
-
# # Not reached here
|
97
|
-
# end
|
98
95
|
#
|
99
|
-
#
|
100
|
-
#
|
101
|
-
# # Not
|
96
|
+
# def test_omission
|
97
|
+
# omit_if("".empty?)
|
98
|
+
# # Not reached here
|
102
99
|
# end
|
103
|
-
#
|
104
|
-
#
|
100
|
+
#
|
101
|
+
# def test_omission_with_here
|
102
|
+
# omit_if(true) do
|
103
|
+
# # Not ran here
|
104
|
+
# end
|
105
|
+
# omit_if(false) do
|
106
|
+
# # Reached here
|
107
|
+
# end
|
108
|
+
# # Reached here too
|
105
109
|
# end
|
106
|
-
# # Reached here too
|
107
|
-
# end
|
108
110
|
def omit_if(condition, *args, &block)
|
109
111
|
if condition
|
110
112
|
omit(*args, &block)
|
@@ -117,20 +119,21 @@ module Test
|
|
117
119
|
# not true.
|
118
120
|
#
|
119
121
|
# Example:
|
120
|
-
# def test_omission
|
121
|
-
# omit_unless("string".empty?)
|
122
|
-
# # Not reached here
|
123
|
-
# end
|
124
122
|
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
# #
|
123
|
+
# def test_omission
|
124
|
+
# omit_unless("string".empty?)
|
125
|
+
# # Not reached here
|
128
126
|
# end
|
129
|
-
#
|
130
|
-
#
|
127
|
+
#
|
128
|
+
# def test_omission_with_here
|
129
|
+
# omit_unless(true) do
|
130
|
+
# # Reached here
|
131
|
+
# end
|
132
|
+
# omit_unless(false) do
|
133
|
+
# # Not ran here
|
134
|
+
# end
|
135
|
+
# # Reached here too
|
131
136
|
# end
|
132
|
-
# # Reached here too
|
133
|
-
# end
|
134
137
|
def omit_unless(condition, *args, &block)
|
135
138
|
if condition
|
136
139
|
block.call if block
|
data/lib/test/unit/pending.rb
CHANGED
@@ -65,19 +65,20 @@ module Test
|
|
65
65
|
# Marks the test or part of the test is pending.
|
66
66
|
#
|
67
67
|
# Example:
|
68
|
-
# def test_pending
|
69
|
-
# pend
|
70
|
-
# # Not reached here
|
71
|
-
# end
|
72
68
|
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
# #
|
76
|
-
#
|
77
|
-
#
|
69
|
+
# def test_pending
|
70
|
+
# pend
|
71
|
+
# # Not reached here
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# def test_pending_with_here
|
75
|
+
# pend do
|
76
|
+
# # Ran here
|
77
|
+
# # Fails if the block doesn't raise any error.
|
78
|
+
# # Because it means the block is passed unexpectedly.
|
79
|
+
# end
|
80
|
+
# # Reached here
|
78
81
|
# end
|
79
|
-
# # Reached here
|
80
|
-
# end
|
81
82
|
def pend(message=nil, &block)
|
82
83
|
message ||= "pended."
|
83
84
|
if block_given?
|
data/lib/test/unit/priority.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require "fileutils"
|
2
|
-
|
3
1
|
module Test
|
4
2
|
module Unit
|
5
3
|
module Priority
|
@@ -148,15 +146,19 @@ module Test
|
|
148
146
|
end
|
149
147
|
|
150
148
|
def escape_class_name(class_name)
|
151
|
-
class_name
|
149
|
+
escape_name(class_name)
|
152
150
|
end
|
153
151
|
|
154
152
|
def escaped_method_name
|
155
|
-
@test.method_name.to_s
|
153
|
+
escape_name(@test.method_name.to_s)
|
154
|
+
end
|
155
|
+
|
156
|
+
def escape_name(name)
|
157
|
+
name.gsub(/(?:[: \/!?=])/) do |matched|
|
156
158
|
case matched
|
157
159
|
when ":"
|
158
160
|
"_colon_"
|
159
|
-
when " "
|
161
|
+
when " ", "/"
|
160
162
|
"_"
|
161
163
|
when "!"
|
162
164
|
".destructive"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# Copyright (C) 2008-2023 Sutou Kouhei <kou@clear-code.com>
|
2
|
+
|
1
3
|
module Test
|
2
4
|
module Unit
|
3
5
|
AutoRunner.register_runner(:console) do |auto_runner|
|
@@ -16,7 +18,7 @@ module Test
|
|
16
18
|
["verbose", UI::Console::OutputLevel::VERBOSE],
|
17
19
|
]
|
18
20
|
opts.on('-v', '--verbose=[LEVEL]', output_levels,
|
19
|
-
"Set the output level (default is
|
21
|
+
"Set the output level (default is normal).",
|
20
22
|
"(#{auto_runner.keyword_display(output_levels)})") do |level|
|
21
23
|
level ||= output_levels.assoc("verbose")[1]
|
22
24
|
auto_runner.runner_options[:output_level] = level
|
@@ -49,11 +51,28 @@ module Test
|
|
49
51
|
auto_runner.runner_options[:progress_row_max] = max
|
50
52
|
end
|
51
53
|
|
54
|
+
progress_styles = [
|
55
|
+
["inplace", :inplace],
|
56
|
+
["mark", :mark],
|
57
|
+
["fault-only", :fault_only],
|
58
|
+
]
|
59
|
+
opts.on("--progress-style=STYLE", progress_styles,
|
60
|
+
"Uses STYLE as progress style",
|
61
|
+
"(#{auto_runner.keyword_display(progress_styles)}") do |style|
|
62
|
+
auto_runner.runner_options[:progress_style] = style
|
63
|
+
end
|
64
|
+
|
52
65
|
opts.on("--no-show-detail-immediately",
|
53
66
|
"Shows not passed test details immediately.",
|
54
67
|
"(default is yes)") do |boolean|
|
55
68
|
auto_runner.runner_options[:show_detail_immediately] = boolean
|
56
69
|
end
|
70
|
+
|
71
|
+
opts.on("--[no-]reverse-output",
|
72
|
+
"Shows fault details in reverse.",
|
73
|
+
"(default is yes for tty output, no otherwise)") do |boolean|
|
74
|
+
auto_runner.runner_options[:reverse_output] = boolean
|
75
|
+
end
|
57
76
|
end
|
58
77
|
end
|
59
78
|
end
|
@@ -5,9 +5,18 @@
|
|
5
5
|
# * Copyright (c) 2011 Kouhei Sutou <tt><kou@clear-code.com></tt>
|
6
6
|
# License:: Ruby license.
|
7
7
|
|
8
|
+
require "test/unit/data-sets"
|
9
|
+
|
8
10
|
module Test
|
9
11
|
module Unit
|
10
12
|
class TestSuiteCreator # :nodoc:
|
13
|
+
class << self
|
14
|
+
def test_method?(test_case, method_name)
|
15
|
+
/\Atest./ =~ method_name.to_s or
|
16
|
+
test_case.find_attribute(method_name, :test)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
11
20
|
def initialize(test_case)
|
12
21
|
@test_case = test_case
|
13
22
|
end
|
@@ -15,14 +24,11 @@ module Test
|
|
15
24
|
def create
|
16
25
|
suite = TestSuite.new(@test_case.name, @test_case)
|
17
26
|
collect_test_names.each do |test_name|
|
18
|
-
data_sets =
|
27
|
+
data_sets = extract_data_sets(test_name)
|
19
28
|
if data_sets
|
20
|
-
data_sets.each do |
|
21
|
-
|
22
|
-
|
23
|
-
append_test(suite, test_name) do |test|
|
24
|
-
test.assign_test_data(label, data)
|
25
|
-
end
|
29
|
+
data_sets.each do |label, data|
|
30
|
+
append_test(suite, test_name) do |test|
|
31
|
+
test.assign_test_data(label, data)
|
26
32
|
end
|
27
33
|
end
|
28
34
|
else
|
@@ -34,6 +40,22 @@ module Test
|
|
34
40
|
end
|
35
41
|
|
36
42
|
private
|
43
|
+
def extract_data_sets(test_name)
|
44
|
+
data_sets = @test_case.find_attribute(test_name,
|
45
|
+
:data,
|
46
|
+
:recursive => false)
|
47
|
+
data_method_name = "data_#{test_name}"
|
48
|
+
test = @test_case.new(test_name)
|
49
|
+
if test.respond_to?(data_method_name)
|
50
|
+
data_method = test.method(data_method_name)
|
51
|
+
if data_method.arity <= 0
|
52
|
+
data_sets ||= DataSets.new
|
53
|
+
data_sets << data_method
|
54
|
+
end
|
55
|
+
end
|
56
|
+
data_sets
|
57
|
+
end
|
58
|
+
|
37
59
|
def append_test(suite, test_name)
|
38
60
|
test = @test_case.new(test_name)
|
39
61
|
yield(test) if block_given?
|
@@ -47,8 +69,7 @@ module Test
|
|
47
69
|
methods |= @test_case.public_instance_methods(false)
|
48
70
|
method_names = methods.collect(&:to_s)
|
49
71
|
test_names = method_names.find_all do |method_name|
|
50
|
-
|
51
|
-
@test_case.find_attribute(method_name, :test)
|
72
|
+
self.class.test_method?(@test_case, method_name)
|
52
73
|
end
|
53
74
|
__send__("sort_test_names_in_#{@test_case.test_order}_order", test_names)
|
54
75
|
end
|