test-unit 2.0.0 → 2.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.
- data/History.txt +30 -0
- data/Manifest.txt +20 -12
- data/README.txt +28 -12
- data/Rakefile +5 -0
- data/TODO +1 -0
- data/html/classic.html +15 -0
- data/html/index.html +25 -0
- data/html/index.html.ja +27 -0
- data/html/test-unit-classic.png +0 -0
- data/lib/test/unit.rb +62 -0
- data/lib/test/unit/assertions.rb +350 -66
- data/lib/test/unit/autorunner.rb +68 -13
- data/lib/test/unit/collector/load.rb +1 -1
- data/lib/test/unit/color-scheme.rb +85 -0
- data/lib/test/unit/color.rb +40 -5
- data/lib/test/unit/diff.rb +14 -0
- data/lib/test/unit/fixture.rb +2 -2
- data/lib/test/unit/runner/console.rb +8 -2
- data/lib/test/unit/testcase.rb +86 -2
- data/lib/test/unit/ui/console/testrunner.rb +51 -26
- data/lib/test/unit/version.rb +1 -1
- data/sample/test_user.rb +22 -0
- data/test/collector/{test_descendant.rb → test-descendant.rb} +0 -0
- data/test/collector/{test_load.rb → test-load.rb} +1 -1
- data/test/{test_attribute.rb → test-attribute.rb} +0 -0
- data/test/test-color-scheme.rb +55 -0
- data/test/{test_color.rb → test-color.rb} +10 -0
- data/test/{test_diff.rb → test-diff.rb} +0 -0
- data/test/{test_emacs_runner.rb → test-emacs-runner.rb} +0 -0
- data/test/test-fixture.rb +287 -0
- data/test/{test_notification.rb → test-notification.rb} +4 -4
- data/test/{test_omission.rb → test-omission.rb} +6 -6
- data/test/{test_pending.rb → test-pending.rb} +6 -6
- data/test/{test_priority.rb → test-priority.rb} +0 -0
- data/test/test_assertions.rb +366 -63
- data/test/test_testcase.rb +48 -0
- data/test/{testunit_test_util.rb → testunit-test-util.rb} +1 -1
- metadata +27 -29
- data/test/test_fixture.rb +0 -275
data/lib/test/unit/autorunner.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'test/unit'
|
2
|
+
require 'test/unit/color-scheme'
|
2
3
|
require 'optparse'
|
3
4
|
|
4
5
|
module Test
|
@@ -11,10 +12,24 @@ module Test
|
|
11
12
|
class << self
|
12
13
|
def register_runner(id, runner_builder=Proc.new)
|
13
14
|
RUNNERS[id] = runner_builder
|
15
|
+
RUNNERS[id.to_s] = runner_builder
|
16
|
+
end
|
17
|
+
|
18
|
+
def runner(id)
|
19
|
+
RUNNERS[id.to_s]
|
14
20
|
end
|
15
21
|
|
16
22
|
def register_collector(id, collector_builder=Proc.new)
|
17
23
|
COLLECTORS[id] = collector_builder
|
24
|
+
COLLECTORS[id.to_s] = collector_builder
|
25
|
+
end
|
26
|
+
|
27
|
+
def collector(id)
|
28
|
+
COLLECTORS[id.to_s]
|
29
|
+
end
|
30
|
+
|
31
|
+
def register_color_scheme(id, scheme)
|
32
|
+
ColorScheme[id] = scheme
|
18
33
|
end
|
19
34
|
|
20
35
|
def setup_option(option_builder=Proc.new)
|
@@ -76,6 +91,7 @@ module Test
|
|
76
91
|
|
77
92
|
attr_reader :suite, :runner_options
|
78
93
|
attr_accessor :filters, :to_run, :pattern, :exclude, :base, :workdir
|
94
|
+
attr_accessor :color_scheme
|
79
95
|
attr_writer :runner, :collector
|
80
96
|
|
81
97
|
def initialize(standalone)
|
@@ -85,8 +101,11 @@ module Test
|
|
85
101
|
@collector = default_collector
|
86
102
|
@filters = []
|
87
103
|
@to_run = []
|
104
|
+
@color_scheme = ColorScheme.default
|
88
105
|
@runner_options = {}
|
89
106
|
@workdir = nil
|
107
|
+
default_config_file = "test-unit.yml"
|
108
|
+
load_config(default_config_file) if File.exist?(default_config_file)
|
90
109
|
yield(self) if block_given?
|
91
110
|
end
|
92
111
|
|
@@ -96,8 +115,7 @@ module Test
|
|
96
115
|
rescue OptionParser::ParseError => e
|
97
116
|
puts e
|
98
117
|
puts options
|
99
|
-
|
100
|
-
abort
|
118
|
+
exit(false)
|
101
119
|
else
|
102
120
|
@filters << proc{false} unless(@filters.empty?)
|
103
121
|
end
|
@@ -116,7 +134,7 @@ module Test
|
|
116
134
|
@runner = r
|
117
135
|
end
|
118
136
|
|
119
|
-
if(@standalone)
|
137
|
+
if (@standalone)
|
120
138
|
o.on('-b', '--basedir=DIR', "Base directory of test suites.") do |b|
|
121
139
|
@base = b
|
122
140
|
end
|
@@ -169,7 +187,11 @@ module Test
|
|
169
187
|
end
|
170
188
|
|
171
189
|
priority_filter = Proc.new do |test|
|
172
|
-
|
190
|
+
if @filters.size > 2
|
191
|
+
nil
|
192
|
+
else
|
193
|
+
Priority::Checker.new(test).need_to_run? or nil
|
194
|
+
end
|
173
195
|
end
|
174
196
|
o.on("--[no-]priority-mode",
|
175
197
|
"Runs some tests based on their priority.") do |priority_mode|
|
@@ -185,6 +207,18 @@ module Test
|
|
185
207
|
$LOAD_PATH.concat(dirs.split(File::PATH_SEPARATOR))
|
186
208
|
end
|
187
209
|
|
210
|
+
color_schemes = ColorScheme.all
|
211
|
+
o.on("--color-scheme=SCHEME", color_schemes,
|
212
|
+
"Use SCHEME as color scheme.",
|
213
|
+
"(#{keyword_display(color_schemes)})") do |scheme|
|
214
|
+
@color_scheme = scheme
|
215
|
+
end
|
216
|
+
|
217
|
+
o.on("--config=FILE",
|
218
|
+
"Use YAML fomat FILE content as configuration file.") do |file|
|
219
|
+
load_config(file)
|
220
|
+
end
|
221
|
+
|
188
222
|
ADDITIONAL_OPTIONS.each do |option_builder|
|
189
223
|
option_builder.call(self, o)
|
190
224
|
end
|
@@ -201,13 +235,13 @@ module Test
|
|
201
235
|
|
202
236
|
o.on_tail('--console', 'Console runner (use --runner).') do
|
203
237
|
warn("Deprecated option (--console).")
|
204
|
-
@runner =
|
238
|
+
@runner = self.class.runner(:console)
|
205
239
|
end
|
206
240
|
|
207
241
|
if RUNNERS[:fox]
|
208
242
|
o.on_tail('--fox', 'Fox runner (use --runner).') do
|
209
243
|
warn("Deprecated option (--fox).")
|
210
|
-
@runner =
|
244
|
+
@runner = self.class.runner(:fox)
|
211
245
|
end
|
212
246
|
end
|
213
247
|
|
@@ -215,10 +249,12 @@ module Test
|
|
215
249
|
end
|
216
250
|
end
|
217
251
|
|
218
|
-
def keyword_display(
|
219
|
-
|
220
|
-
|
221
|
-
|
252
|
+
def keyword_display(keywords)
|
253
|
+
keywords.collect do |keyword, _|
|
254
|
+
keyword.to_s
|
255
|
+
end.uniq.sort.collect do |keyword|
|
256
|
+
keyword.sub(/^(.)([A-Za-z]+)(?=\w*$)/, '\\1[\\2]')
|
257
|
+
end.join(", ")
|
222
258
|
end
|
223
259
|
|
224
260
|
def run
|
@@ -226,21 +262,40 @@ module Test
|
|
226
262
|
return false if suite.nil?
|
227
263
|
runner = @runner[self]
|
228
264
|
return false if runner.nil?
|
265
|
+
@runner_options[:color_scheme] ||= @color_scheme
|
229
266
|
Dir.chdir(@workdir) if @workdir
|
230
267
|
runner.run(suite, @runner_options).passed?
|
231
268
|
end
|
232
269
|
|
270
|
+
def load_config(file)
|
271
|
+
require 'yaml'
|
272
|
+
config = YAML.load(File.read(file))
|
273
|
+
runner_name = config["runner"]
|
274
|
+
@runner = self.class.runner(runner_name) || @runner
|
275
|
+
@collector = self.class.collector(config["collector"]) || @collector
|
276
|
+
(config["color_schemes"] || {}).each do |name, options|
|
277
|
+
ColorScheme[name] = options
|
278
|
+
end
|
279
|
+
runner_options = {}
|
280
|
+
(config["#{runner_name}_options"] || {}).each do |key, value|
|
281
|
+
key = key.to_sym
|
282
|
+
value = ColorScheme[value] if key == :color_scheme
|
283
|
+
runner_options[key.to_sym] = value
|
284
|
+
end
|
285
|
+
@runner_options = @runner_options.merge(runner_options)
|
286
|
+
end
|
287
|
+
|
233
288
|
private
|
234
289
|
def default_runner
|
235
290
|
if ENV["EMACS"] == "t"
|
236
|
-
|
291
|
+
self.class.runner(:emacs)
|
237
292
|
else
|
238
|
-
|
293
|
+
self.class.runner(:console)
|
239
294
|
end
|
240
295
|
end
|
241
296
|
|
242
297
|
def default_collector
|
243
|
-
|
298
|
+
self.class.collector(@standalone ? :load : :descendant)
|
244
299
|
end
|
245
300
|
end
|
246
301
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'test/unit/color'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Unit
|
5
|
+
class ColorScheme
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
class << self
|
9
|
+
@@default = nil
|
10
|
+
def default
|
11
|
+
@@default ||= new("success" => Color.new("green", :bold => true),
|
12
|
+
"failure" => Color.new("red", :bold => true),
|
13
|
+
"pending" => Color.new("magenta", :bold => true),
|
14
|
+
"omission" => Color.new("blue", :bold => true),
|
15
|
+
"notification" => Color.new("cyan", :bold => true),
|
16
|
+
"error" => Color.new("yellow", :bold => true))
|
17
|
+
end
|
18
|
+
|
19
|
+
@@schemes = {}
|
20
|
+
def all
|
21
|
+
@@schemes.merge("default" => default)
|
22
|
+
end
|
23
|
+
|
24
|
+
def [](id)
|
25
|
+
@@schemes[id.to_s]
|
26
|
+
end
|
27
|
+
|
28
|
+
def []=(id, scheme_or_spec)
|
29
|
+
if scheme_or_spec.is_a?(self)
|
30
|
+
scheme = scheme_or_spec
|
31
|
+
else
|
32
|
+
scheme = new(scheme_or_spec)
|
33
|
+
end
|
34
|
+
@@schemes[id.to_s] = scheme
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize(scheme_spec)
|
39
|
+
@scheme = {}
|
40
|
+
scheme_spec.each do |key, color_spec|
|
41
|
+
self[key] = color_spec
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def [](name)
|
46
|
+
@scheme[name.to_s]
|
47
|
+
end
|
48
|
+
|
49
|
+
def []=(name, color_spec)
|
50
|
+
@scheme[name.to_s] = make_color(color_spec)
|
51
|
+
end
|
52
|
+
|
53
|
+
def each(&block)
|
54
|
+
@scheme.each(&block)
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_hash
|
58
|
+
hash = {}
|
59
|
+
@scheme.each do |key, color|
|
60
|
+
hash[key] = color
|
61
|
+
end
|
62
|
+
hash
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
def make_color(color_spec)
|
67
|
+
if color_spec.is_a?(Color)
|
68
|
+
color_spec
|
69
|
+
else
|
70
|
+
color_name = nil
|
71
|
+
normalized_color_spec = {}
|
72
|
+
color_spec.each do |key, value|
|
73
|
+
key = key.to_sym
|
74
|
+
if key == :name
|
75
|
+
color_name = value
|
76
|
+
else
|
77
|
+
normalized_color_spec[key] = value
|
78
|
+
end
|
79
|
+
end
|
80
|
+
Color.new(color_name, normalized_color_spec)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/test/unit/color.rb
CHANGED
@@ -3,6 +3,8 @@ module Test
|
|
3
3
|
class Color
|
4
4
|
NAMES = ["black", "red", "green", "yellow",
|
5
5
|
"blue", "magenta", "cyan", "white"]
|
6
|
+
|
7
|
+
attr_reader :name
|
6
8
|
def initialize(name, options={})
|
7
9
|
@name = name
|
8
10
|
@foreground = options[:foreground]
|
@@ -13,19 +15,47 @@ module Test
|
|
13
15
|
@underline = options[:underline]
|
14
16
|
end
|
15
17
|
|
18
|
+
def foreground?
|
19
|
+
@foreground
|
20
|
+
end
|
21
|
+
|
22
|
+
def intensity?
|
23
|
+
@intensity
|
24
|
+
end
|
25
|
+
|
26
|
+
def bold?
|
27
|
+
@bold
|
28
|
+
end
|
29
|
+
|
30
|
+
def italic?
|
31
|
+
@italic
|
32
|
+
end
|
33
|
+
|
34
|
+
def underline?
|
35
|
+
@underline
|
36
|
+
end
|
37
|
+
|
38
|
+
def ==(other)
|
39
|
+
self.class === other and
|
40
|
+
[name, foreground?, intensity?,
|
41
|
+
bold?, italic?, underline?] ==
|
42
|
+
[other.name, other.foreground?, other.intensity?,
|
43
|
+
other.bold?, other.italic?, other.underline?]
|
44
|
+
end
|
45
|
+
|
16
46
|
def sequence
|
17
47
|
sequence = []
|
18
48
|
if @name == "none"
|
19
49
|
elsif @name == "reset"
|
20
50
|
sequence << "0"
|
21
51
|
else
|
22
|
-
foreground_parameter =
|
23
|
-
foreground_parameter += 6 if
|
52
|
+
foreground_parameter = foreground? ? 3 : 4
|
53
|
+
foreground_parameter += 6 if intensity?
|
24
54
|
sequence << "#{foreground_parameter}#{NAMES.index(@name)}"
|
25
55
|
end
|
26
|
-
sequence << "1" if
|
27
|
-
sequence << "3" if
|
28
|
-
sequence << "4" if
|
56
|
+
sequence << "1" if bold?
|
57
|
+
sequence << "3" if italic?
|
58
|
+
sequence << "4" if underline?
|
29
59
|
sequence
|
30
60
|
end
|
31
61
|
|
@@ -39,6 +69,7 @@ module Test
|
|
39
69
|
end
|
40
70
|
|
41
71
|
class MixColor
|
72
|
+
attr_reader :colors
|
42
73
|
def initialize(colors)
|
43
74
|
@colors = colors
|
44
75
|
end
|
@@ -56,6 +87,10 @@ module Test
|
|
56
87
|
def +(other)
|
57
88
|
self.class.new([self, other])
|
58
89
|
end
|
90
|
+
|
91
|
+
def ==(other)
|
92
|
+
self.class === other and colors == other.colors
|
93
|
+
end
|
59
94
|
end
|
60
95
|
end
|
61
96
|
end
|
data/lib/test/unit/diff.rb
CHANGED
@@ -507,6 +507,20 @@ module Test
|
|
507
507
|
end
|
508
508
|
|
509
509
|
module_function
|
510
|
+
def need_fold?(diff)
|
511
|
+
/^[-+].{79}/ =~ diff
|
512
|
+
end
|
513
|
+
|
514
|
+
def fold(string)
|
515
|
+
string.split(/\r?\n/).collect do |line|
|
516
|
+
line.gsub(/(.{78})/, "\\1\n")
|
517
|
+
end.join("\n")
|
518
|
+
end
|
519
|
+
|
520
|
+
def folded_readable(from, to, options={})
|
521
|
+
readable(fold(from), fold(to), options)
|
522
|
+
end
|
523
|
+
|
510
524
|
def readable(from, to, options={})
|
511
525
|
diff(ReadableDiffer, from, to, options)
|
512
526
|
end
|
data/lib/test/unit/fixture.rb
CHANGED
@@ -153,10 +153,10 @@ module Test
|
|
153
153
|
unregistered_methods =
|
154
154
|
instance_variable_get(unregistered_methods_variable)
|
155
155
|
end
|
156
|
-
result
|
156
|
+
(result | methods) - unregistered_methods
|
157
157
|
end
|
158
158
|
else
|
159
|
-
|
159
|
+
result
|
160
160
|
end
|
161
161
|
end
|
162
162
|
end
|
@@ -31,8 +31,8 @@ module Test
|
|
31
31
|
["true", true],
|
32
32
|
]
|
33
33
|
opts.on("--[no-]use-color=[auto]", use_color_options,
|
34
|
-
"
|
35
|
-
"(default is auto") do |use_color|
|
34
|
+
"Uses color output",
|
35
|
+
"(default is auto)") do |use_color|
|
36
36
|
case use_color
|
37
37
|
when nil
|
38
38
|
use_color = true
|
@@ -41,6 +41,12 @@ module Test
|
|
41
41
|
end
|
42
42
|
auto_runner.runner_options[:use_color] = use_color
|
43
43
|
end
|
44
|
+
|
45
|
+
opts.on("--progress-row-max=MAX", Integer,
|
46
|
+
"Uses MAX as max terminal width for progress mark",
|
47
|
+
"(default is auto)") do |max|
|
48
|
+
auto_runner.runner_options[:progress_row_max] = max
|
49
|
+
end
|
44
50
|
end
|
45
51
|
end
|
46
52
|
end
|
data/lib/test/unit/testcase.rb
CHANGED
@@ -109,6 +109,79 @@ module Test
|
|
109
109
|
end
|
110
110
|
suite
|
111
111
|
end
|
112
|
+
|
113
|
+
# Called before every test case runs. Can be used
|
114
|
+
# to set up fixture information used in test case
|
115
|
+
# scope.
|
116
|
+
#
|
117
|
+
# Here is an example test case:
|
118
|
+
# class TestMyClass < Test::Unit::TestCase
|
119
|
+
# class << self
|
120
|
+
# def startup
|
121
|
+
# ...
|
122
|
+
# end
|
123
|
+
# end
|
124
|
+
#
|
125
|
+
# def setup
|
126
|
+
# ...
|
127
|
+
# end
|
128
|
+
#
|
129
|
+
# def test_my_class1
|
130
|
+
# ...
|
131
|
+
# end
|
132
|
+
#
|
133
|
+
# def test_my_class2
|
134
|
+
# ...
|
135
|
+
# end
|
136
|
+
# end
|
137
|
+
#
|
138
|
+
# Here is a call order:
|
139
|
+
# * startup
|
140
|
+
# * setup
|
141
|
+
# * test_my_class1 (or test_my_class2)
|
142
|
+
# * setup
|
143
|
+
# * test_my_class2 (or test_my_class1)
|
144
|
+
#
|
145
|
+
# Note that you should not assume test order. Tests
|
146
|
+
# should be worked in any order.
|
147
|
+
def startup
|
148
|
+
end
|
149
|
+
|
150
|
+
# Called after every test case runs. Can be used to tear
|
151
|
+
# down fixture information used in test case scope.
|
152
|
+
#
|
153
|
+
# Here is an example test case:
|
154
|
+
# class TestMyClass < Test::Unit::TestCase
|
155
|
+
# class << self
|
156
|
+
# def shutdown
|
157
|
+
# ...
|
158
|
+
# end
|
159
|
+
# end
|
160
|
+
#
|
161
|
+
# def teardown
|
162
|
+
# ...
|
163
|
+
# end
|
164
|
+
#
|
165
|
+
# def test_my_class1
|
166
|
+
# ...
|
167
|
+
# end
|
168
|
+
#
|
169
|
+
# def test_my_class2
|
170
|
+
# ...
|
171
|
+
# end
|
172
|
+
# end
|
173
|
+
#
|
174
|
+
# Here is a call order:
|
175
|
+
# * test_my_class1 (or test_my_class2)
|
176
|
+
# * teardown
|
177
|
+
# * test_my_class2 (or test_my_class1)
|
178
|
+
# * teardown
|
179
|
+
# * shutdown
|
180
|
+
#
|
181
|
+
# Note that you should not assume test order. Tests
|
182
|
+
# should be worked in any order.
|
183
|
+
def shutdown
|
184
|
+
end
|
112
185
|
end
|
113
186
|
|
114
187
|
attr_reader :method_name
|
@@ -117,7 +190,14 @@ module Test
|
|
117
190
|
# test represented by test_method_name.
|
118
191
|
def initialize(test_method_name)
|
119
192
|
throw :invalid_test unless respond_to?(test_method_name)
|
120
|
-
|
193
|
+
test_method = method(test_method_name)
|
194
|
+
throw :invalid_test if test_method.arity > 0
|
195
|
+
if test_method.respond_to?(:owner)
|
196
|
+
if test_method.owner.class != Module and
|
197
|
+
self.class != test_method.owner
|
198
|
+
throw :invalid_test
|
199
|
+
end
|
200
|
+
end
|
121
201
|
@method_name = test_method_name
|
122
202
|
@test_passed = true
|
123
203
|
@interrupted = false
|
@@ -132,7 +212,7 @@ module Test
|
|
132
212
|
yield(STARTED, name)
|
133
213
|
begin
|
134
214
|
run_setup
|
135
|
-
|
215
|
+
run_test
|
136
216
|
rescue Exception
|
137
217
|
@interrupted = true
|
138
218
|
raise unless handle_exception($!)
|
@@ -251,6 +331,10 @@ module Test
|
|
251
331
|
@_result
|
252
332
|
end
|
253
333
|
|
334
|
+
def run_test
|
335
|
+
__send__(@method_name)
|
336
|
+
end
|
337
|
+
|
254
338
|
def handle_exception(exception)
|
255
339
|
self.class.exception_handlers.each do |handler|
|
256
340
|
return true if send(handler, exception)
|