test-unit 3.1.5 → 3.6.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.
- 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
|