test-unit 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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/History.txt
CHANGED
@@ -1,3 +1,33 @@
|
|
1
|
+
=== 2.0.1 / 2008-11-09
|
2
|
+
|
3
|
+
* 19 major enhancements
|
4
|
+
|
5
|
+
* support ruby 1.9.1.
|
6
|
+
* add run_test method to be extensible.
|
7
|
+
* improve priority-mode auto off.
|
8
|
+
* improve startup/shutdown RDoc. [Daniel Berger]
|
9
|
+
* add assert_compare. [#20851] [Designing Patterns]
|
10
|
+
* add assert_fail_assertion. [#20851] [Designing Patterns]
|
11
|
+
* add assert_raise_message. [#20851] [Designing Patterns]
|
12
|
+
* support folded diff.
|
13
|
+
* add assert_raise_kind_of. [Daniel Berger]
|
14
|
+
* ingore inherited test for nested test case.
|
15
|
+
* add assert_const_defined.
|
16
|
+
* add assert_not_const_defined.
|
17
|
+
* support assert_raise with an exception object.
|
18
|
+
* support assert_raise with no arguments that asserts any
|
19
|
+
exception is raised. [#22602] [Daniel Berger]
|
20
|
+
* support folded dot progress.
|
21
|
+
* add --progress-row-max option.
|
22
|
+
* support color scheme customize.
|
23
|
+
* support configuration file. (YAML)
|
24
|
+
* recognize test-XXX.rb files as test files not only test_XXX.rb
|
25
|
+
|
26
|
+
* Thanks
|
27
|
+
|
28
|
+
* Daniel Berger
|
29
|
+
* Designing Patterns
|
30
|
+
|
1
31
|
=== 2.0.0 / 2008-06-18
|
2
32
|
|
3
33
|
* 15 major enhancements
|
data/Manifest.txt
CHANGED
@@ -2,7 +2,12 @@ History.txt
|
|
2
2
|
Manifest.txt
|
3
3
|
README.txt
|
4
4
|
Rakefile
|
5
|
+
TODO
|
5
6
|
bin/testrb
|
7
|
+
html/classic.html
|
8
|
+
html/index.html
|
9
|
+
html/index.html.ja
|
10
|
+
html/test-unit-classic.png
|
6
11
|
lib/test/unit.rb
|
7
12
|
lib/test/unit/assertionfailederror.rb
|
8
13
|
lib/test/unit/assertions.rb
|
@@ -13,6 +18,7 @@ lib/test/unit/collector/descendant.rb
|
|
13
18
|
lib/test/unit/collector/dir.rb
|
14
19
|
lib/test/unit/collector/load.rb
|
15
20
|
lib/test/unit/collector/objectspace.rb
|
21
|
+
lib/test/unit/color-scheme.rb
|
16
22
|
lib/test/unit/color.rb
|
17
23
|
lib/test/unit/diff.rb
|
18
24
|
lib/test/unit/error.rb
|
@@ -42,28 +48,30 @@ sample/adder.rb
|
|
42
48
|
sample/subtracter.rb
|
43
49
|
sample/tc_adder.rb
|
44
50
|
sample/tc_subtracter.rb
|
51
|
+
sample/test_user.rb
|
45
52
|
sample/ts_examples.rb
|
46
|
-
test/collector/
|
53
|
+
test/collector/test-descendant.rb
|
54
|
+
test/collector/test-load.rb
|
47
55
|
test/collector/test_dir.rb
|
48
|
-
test/collector/test_load.rb
|
49
56
|
test/collector/test_objectspace.rb
|
50
57
|
test/run-test.rb
|
58
|
+
test/test-attribute.rb
|
59
|
+
test/test-color-scheme.rb
|
60
|
+
test/test-color.rb
|
61
|
+
test/test-diff.rb
|
62
|
+
test/test-emacs-runner.rb
|
63
|
+
test/test-fixture.rb
|
64
|
+
test/test-notification.rb
|
65
|
+
test/test-omission.rb
|
66
|
+
test/test-pending.rb
|
67
|
+
test/test-priority.rb
|
51
68
|
test/test_assertions.rb
|
52
|
-
test/test_attribute.rb
|
53
|
-
test/test_color.rb
|
54
|
-
test/test_diff.rb
|
55
|
-
test/test_emacs_runner.rb
|
56
69
|
test/test_error.rb
|
57
70
|
test/test_failure.rb
|
58
|
-
test/test_fixture.rb
|
59
|
-
test/test_notification.rb
|
60
|
-
test/test_omission.rb
|
61
|
-
test/test_pending.rb
|
62
|
-
test/test_priority.rb
|
63
71
|
test/test_testcase.rb
|
64
72
|
test/test_testresult.rb
|
65
73
|
test/test_testsuite.rb
|
66
|
-
test/
|
74
|
+
test/testunit-test-util.rb
|
67
75
|
test/ui/test_testrunmediator.rb
|
68
76
|
test/util/test_backtracefilter.rb
|
69
77
|
test/util/test_observable.rb
|
data/README.txt
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
-
= Test::Unit
|
1
|
+
= Test::Unit 2.x
|
2
2
|
|
3
3
|
* http://rubyforge.org/projects/test-unit/
|
4
4
|
|
5
|
-
== DESCRIPTION
|
5
|
+
== DESCRIPTION
|
6
6
|
|
7
|
-
Test::Unit
|
8
|
-
|
7
|
+
Test::Unit 2.x - Improved version of Test::Unit bundled in
|
8
|
+
Ruby 1.8.x.
|
9
9
|
|
10
|
-
|
10
|
+
Ruby 1.9.x bundles miniunit not Test::Unit. Test::Unit
|
11
|
+
bundled in Ruby 1.8.x had not been improved but unbundled
|
12
|
+
Test::Unit (Test::Unit 2.x) will be improved actively.
|
13
|
+
|
14
|
+
== FEATURES
|
11
15
|
|
12
16
|
* Test::Unit 1.2.3 is the original Test::Unit, taken
|
13
17
|
straight from the ruby distribution. It is being
|
@@ -15,18 +19,30 @@ externalized from the ruby project as a gem (for tool developers).
|
|
15
19
|
stand-alone package. (The test framework in ruby is going
|
16
20
|
to radically change very soon).
|
17
21
|
|
18
|
-
*
|
19
|
-
|
22
|
+
* Test::Unit 2.x will be improved actively and may break
|
23
|
+
compatiblity with Test::Unit 1.2.3. (We will not hope it
|
24
|
+
if it isn't needed.)
|
25
|
+
|
26
|
+
* Some features exist as separated gems like GUI test
|
27
|
+
runner. (Tk, GTK+ and Fox) test-unit-full gem package
|
28
|
+
provides for installing all Test::Unit related gems
|
29
|
+
easily.
|
30
|
+
|
31
|
+
== INSTALL
|
20
32
|
|
21
|
-
|
22
|
-
original Test::Unit (== Tset::Unit 1.2.3).
|
33
|
+
% sudo gem install test-unit
|
23
34
|
|
24
|
-
|
35
|
+
If you want to use full Test::Unit features:
|
25
36
|
|
26
|
-
|
37
|
+
% sudo gem install test-unit-full
|
27
38
|
|
28
|
-
== LICENSE
|
39
|
+
== LICENSE
|
29
40
|
|
30
41
|
(The Ruby License)
|
31
42
|
|
32
43
|
This software is distributed under the same terms as ruby.
|
44
|
+
|
45
|
+
== Thanks
|
46
|
+
|
47
|
+
* Daniel Berger: suggestions.
|
48
|
+
* Designing Patterns: Suggestions.
|
data/Rakefile
CHANGED
@@ -15,12 +15,17 @@ Hoe.new('test-unit', version) do |p|
|
|
15
15
|
end
|
16
16
|
|
17
17
|
task :check_manifest => :clean_test_result
|
18
|
+
task :check_manifest => :clean_coverage
|
18
19
|
|
19
20
|
task :clean_test_result do
|
20
21
|
test_results = Dir.glob("**/.test-result")
|
21
22
|
sh("rm", "-rf", *test_results) unless test_results.empty?
|
22
23
|
end
|
23
24
|
|
25
|
+
task :clean_coverage do
|
26
|
+
sh("rm", "-rf", "coverage")
|
27
|
+
end
|
28
|
+
|
24
29
|
task :tag do
|
25
30
|
message = "Released Test::Unit #{version}!"
|
26
31
|
base = "svn+ssh://#{ENV['USER']}@rubyforge.org/var/svn/test-unit/"
|
data/html/classic.html
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Test::Unit (Classic)</title>
|
5
|
+
</head>
|
6
|
+
<body bgcolor="red">
|
7
|
+
<p style="text-align: center">
|
8
|
+
<img height="161" width="308" src="test-unit-classic.png">
|
9
|
+
<br>
|
10
|
+
<br>
|
11
|
+
<br>
|
12
|
+
Read the <a href="classic/test-unit/">rdoc</a>
|
13
|
+
</p>
|
14
|
+
</body>
|
15
|
+
</html>
|
data/html/index.html
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
2
|
+
<!DOCTYPE html
|
3
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
4
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
5
|
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
6
|
+
<head>
|
7
|
+
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
8
|
+
<title>Test::Unit - a Unit Testing Framework for Ruby</title>
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<h1>Test::Unit - a Unit Testing Framework for Ruby</h1>
|
12
|
+
<p>[<a href="index.html.ja">Japanese</a>]</p>
|
13
|
+
<ul>
|
14
|
+
<li><a href="http://rubyforge.org/projects/test-unit/">Project Page</a></li>
|
15
|
+
<li>
|
16
|
+
<a href="test-unit/">RDoc</a>
|
17
|
+
<!--(<a href="ja/test-unit/">ja</a>)-->
|
18
|
+
</li>
|
19
|
+
<li>
|
20
|
+
<a href="classic.html">Classic</a>
|
21
|
+
<!--(<a href="ja/classic.html">ja</a>)-->
|
22
|
+
</li>
|
23
|
+
</ul>
|
24
|
+
</body>
|
25
|
+
</html>
|
data/html/index.html.ja
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
2
|
+
<!DOCTYPE html
|
3
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
4
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
5
|
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
|
6
|
+
<head>
|
7
|
+
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
8
|
+
<title>Test::Unit - Ruby用単体テストフレームワーク</title>
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<h1>Test::Unit - Ruby用単体テストフレームワーク</h1>
|
12
|
+
<p>[<a href="./">English</a>]</p>
|
13
|
+
<ul>
|
14
|
+
<li>
|
15
|
+
<a href="http://rubyforge.org/projects/test-unit/">プロジェクトページ</a>
|
16
|
+
</li>
|
17
|
+
<li>
|
18
|
+
<!--<a href="ja/test-unit/">RDoc</a>-->
|
19
|
+
RDoc(<a href="test-unit/">en</a>)
|
20
|
+
</li>
|
21
|
+
<li>
|
22
|
+
<!--<a href="classic.html.html">Classic</a>-->
|
23
|
+
Classic(<a href="classic.html">en</a>)
|
24
|
+
</li>
|
25
|
+
</ul>
|
26
|
+
</body>
|
27
|
+
</html>
|
Binary file
|
data/lib/test/unit.rb
CHANGED
@@ -253,6 +253,68 @@ module Test # :nodoc:
|
|
253
253
|
# the dynamic suite using the console TestRunner.
|
254
254
|
#
|
255
255
|
#
|
256
|
+
# == Configuration file
|
257
|
+
#
|
258
|
+
# Test::Unit reads 'test-unit.yml' in the current working
|
259
|
+
# directory as Test::Unit's configuration file. It can
|
260
|
+
# contain the following configurations:
|
261
|
+
#
|
262
|
+
# * color scheme definitions
|
263
|
+
# * test runner to be used
|
264
|
+
# * test runner options
|
265
|
+
# * test collector to be used
|
266
|
+
#
|
267
|
+
# Except color scheme definitions, all of them are
|
268
|
+
# specified by command line option.
|
269
|
+
#
|
270
|
+
# Here are sample color scheme definitions:
|
271
|
+
#
|
272
|
+
# color_schemes:
|
273
|
+
# inverted:
|
274
|
+
# success:
|
275
|
+
# name: red
|
276
|
+
# bold: true
|
277
|
+
# failure:
|
278
|
+
# name: green
|
279
|
+
# bold: true
|
280
|
+
# other_scheme:
|
281
|
+
# ...
|
282
|
+
#
|
283
|
+
# Here are the syntax of color scheme definitions:
|
284
|
+
#
|
285
|
+
# color_schemes:
|
286
|
+
# SCHEME_NAME:
|
287
|
+
# EVENT_NAME:
|
288
|
+
# name: COLOR_NAME
|
289
|
+
# intensity: BOOLEAN
|
290
|
+
# bold: BOOLEAN
|
291
|
+
# italic: BOOLEAN
|
292
|
+
# underline: BOOLEAN
|
293
|
+
# ...
|
294
|
+
# ...
|
295
|
+
#
|
296
|
+
# SCHEME_NAME:: the name of the color scheme
|
297
|
+
# EVENT_NAME:: one of [success, failure, pending,
|
298
|
+
# omission, notification, error]
|
299
|
+
# COLOR_NAME:: one of [black, red, green, yellow, blue,
|
300
|
+
# magenta, cyan, white]
|
301
|
+
# BOOLEAN:: true or false
|
302
|
+
#
|
303
|
+
# You can use the above 'inverted' color scheme with the
|
304
|
+
# following configuration:
|
305
|
+
#
|
306
|
+
# runner: console
|
307
|
+
# console_options:
|
308
|
+
# color_scheme: inverted
|
309
|
+
# color_schemes:
|
310
|
+
# inverted:
|
311
|
+
# success:
|
312
|
+
# name: red
|
313
|
+
# bold: true
|
314
|
+
# failure:
|
315
|
+
# name: green
|
316
|
+
# bold: true
|
317
|
+
#
|
256
318
|
# == Questions?
|
257
319
|
#
|
258
320
|
# I'd really like to get feedback from all levels of Ruby
|
data/lib/test/unit/assertions.rb
CHANGED
@@ -77,21 +77,7 @@ module Test
|
|
77
77
|
|
78
78
|
public
|
79
79
|
def assert_equal(expected, actual, message=nil)
|
80
|
-
diff = AssertionMessage.
|
81
|
-
if !expected.is_a?(String) or !actual.is_a?(String)
|
82
|
-
expected = AssertionMessage.convert(expected)
|
83
|
-
actual = AssertionMessage.convert(actual)
|
84
|
-
end
|
85
|
-
diff = Diff.readable(expected, actual)
|
86
|
-
if /^[-+]/ !~ diff
|
87
|
-
diff = ""
|
88
|
-
elsif /^[ ?]/ =~ diff or /(?:.*\n){2,}/ =~ diff
|
89
|
-
diff = "\n\ndiff:\n#{diff}"
|
90
|
-
else
|
91
|
-
diff = ""
|
92
|
-
end
|
93
|
-
diff
|
94
|
-
end
|
80
|
+
diff = AssertionMessage.delayed_diff(expected, actual)
|
95
81
|
full_message = build_message(message, <<EOT, expected, actual, diff)
|
96
82
|
<?> expected but was
|
97
83
|
<?>.?
|
@@ -99,53 +85,36 @@ EOT
|
|
99
85
|
assert_block(full_message) { expected == actual }
|
100
86
|
end
|
101
87
|
|
102
|
-
private
|
103
|
-
def _check_exception_class(args) # :nodoc:
|
104
|
-
args.partition do |klass|
|
105
|
-
next if klass.instance_of?(Module)
|
106
|
-
assert(Exception >= klass, "Should expect a class of exception, #{klass}")
|
107
|
-
true
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
private
|
112
|
-
def _expected_exception?(actual_exception, exceptions, modules) # :nodoc:
|
113
|
-
exceptions.include?(actual_exception.class) or
|
114
|
-
modules.any? {|mod| actual_exception.is_a?(mod)}
|
115
|
-
end
|
116
|
-
|
117
88
|
##
|
118
|
-
# Passes if the block raises one of the
|
89
|
+
# Passes if the block raises one of the expected
|
90
|
+
# exceptions. When an expected exception is an Exception
|
91
|
+
# object, passes if expected_exception == actual_exception.
|
119
92
|
#
|
120
93
|
# Example:
|
121
|
-
# assert_raise
|
94
|
+
# assert_raise(RuntimeError, LoadError) do
|
122
95
|
# raise 'Boom!!!'
|
123
|
-
# end
|
124
|
-
|
96
|
+
# end # -> pass
|
97
|
+
#
|
98
|
+
# assert_raise do
|
99
|
+
# raise Exception, 'Any exception should be raised!!!'
|
100
|
+
# end # -> pass
|
101
|
+
#
|
102
|
+
# assert_raise(RuntimeError.new("XXX")) {raise "XXX"} # -> pass
|
103
|
+
# assert_raise(MyError.new("XXX")) {raise "XXX"} # -> fail
|
104
|
+
# assert_raise(RuntimeError.new("ZZZ")) {raise "XXX"} # -> fail
|
125
105
|
public
|
126
|
-
def assert_raise(*args)
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
exceptions, modules = _check_exception_class(args)
|
134
|
-
expected = args.size == 1 ? args.first : args
|
135
|
-
actual_exception = nil
|
136
|
-
full_message = build_message(message, "<?> exception expected but none was thrown.", expected)
|
106
|
+
def assert_raise(*args, &block)
|
107
|
+
assert_expected_exception = Proc.new do |*_args|
|
108
|
+
message, assert_exception_helper, actual_exception = _args
|
109
|
+
expected = assert_exception_helper.expected_exceptions
|
110
|
+
full_message = build_message(message,
|
111
|
+
"<?> exception expected but was\n?",
|
112
|
+
expected, actual_exception)
|
137
113
|
assert_block(full_message) do
|
138
|
-
|
139
|
-
yield
|
140
|
-
rescue Exception => actual_exception
|
141
|
-
break
|
142
|
-
end
|
143
|
-
false
|
114
|
+
expected == [] or assert_exception_helper.expected?(actual_exception)
|
144
115
|
end
|
145
|
-
full_message = build_message(message, "<?> exception expected but was\n?", expected, actual_exception)
|
146
|
-
assert_block(full_message) {_expected_exception?(actual_exception, exceptions, modules)}
|
147
|
-
actual_exception
|
148
116
|
end
|
117
|
+
_assert_raise(assert_expected_exception, *args, &block)
|
149
118
|
end
|
150
119
|
|
151
120
|
##
|
@@ -158,6 +127,30 @@ EOT
|
|
158
127
|
assert_raise(*args, &block)
|
159
128
|
end
|
160
129
|
|
130
|
+
##
|
131
|
+
# Passes if the block raises one of the given
|
132
|
+
# exceptions or sub exceptions of the given exceptions.
|
133
|
+
#
|
134
|
+
# Example:
|
135
|
+
# assert_raise_kind_of(SystemCallError) do
|
136
|
+
# raise Errno::EACCES
|
137
|
+
# end
|
138
|
+
def assert_raise_kind_of(*args, &block)
|
139
|
+
assert_expected_exception = Proc.new do |*_args|
|
140
|
+
message, assert_exception_helper, actual_exception = _args
|
141
|
+
expected = assert_exception_helper.expected_exceptions
|
142
|
+
full_message = build_message(message,
|
143
|
+
"<?> family exception expected " +
|
144
|
+
"but was\n?",
|
145
|
+
expected, actual_exception)
|
146
|
+
assert_block(full_message) do
|
147
|
+
assert_exception_helper.expected?(actual_exception, :kind_of?)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
_assert_raise(assert_expected_exception, *args, &block)
|
151
|
+
end
|
152
|
+
|
153
|
+
|
161
154
|
##
|
162
155
|
# Passes if +object+ .instance_of? +klass+
|
163
156
|
#
|
@@ -301,18 +294,20 @@ EOT
|
|
301
294
|
public
|
302
295
|
def assert_nothing_raised(*args)
|
303
296
|
_wrap_assertion do
|
304
|
-
if
|
305
|
-
message = ""
|
306
|
-
else
|
297
|
+
if args.last.is_a?(String)
|
307
298
|
message = args.pop
|
299
|
+
else
|
300
|
+
message = ""
|
308
301
|
end
|
309
|
-
|
302
|
+
|
303
|
+
assert_exception_helper = AssertExceptionHelper.new(self, args)
|
310
304
|
begin
|
311
305
|
yield
|
312
306
|
rescue Exception => e
|
313
307
|
if ((args.empty? && !e.instance_of?(AssertionFailedError)) ||
|
314
|
-
|
315
|
-
|
308
|
+
assert_exception_helper.expected?(e))
|
309
|
+
failure_message = build_message(message, "Exception raised:\n?", e)
|
310
|
+
assert_block(failure_message) {false}
|
316
311
|
else
|
317
312
|
raise
|
318
313
|
end
|
@@ -398,12 +393,12 @@ EOT
|
|
398
393
|
# Passes if the block throws +expected_object+
|
399
394
|
#
|
400
395
|
# Example:
|
401
|
-
#
|
402
|
-
# throw
|
396
|
+
# assert_throw(:done) do
|
397
|
+
# throw(:done)
|
403
398
|
# end
|
404
399
|
|
405
400
|
public
|
406
|
-
def
|
401
|
+
def assert_throw(expected_object, message="", &proc)
|
407
402
|
_wrap_assertion do
|
408
403
|
begin
|
409
404
|
catch([]) {}
|
@@ -411,7 +406,7 @@ EOT
|
|
411
406
|
assert_instance_of(Symbol, expected_object,
|
412
407
|
"assert_throws expects the symbol that should be thrown for its first argument")
|
413
408
|
end
|
414
|
-
assert_block("Should have passed a block to
|
409
|
+
assert_block("Should have passed a block to assert_throw.") do
|
415
410
|
block_given?
|
416
411
|
end
|
417
412
|
caught = true
|
@@ -437,6 +432,14 @@ EOT
|
|
437
432
|
end
|
438
433
|
end
|
439
434
|
|
435
|
+
##
|
436
|
+
# Alias of assert_throw.
|
437
|
+
#
|
438
|
+
# Will be deprecated in 1.9, and removed in 2.0.
|
439
|
+
def assert_throws(*args, &block)
|
440
|
+
assert_throw(*args, &block)
|
441
|
+
end
|
442
|
+
|
440
443
|
##
|
441
444
|
# Passes if block does not throw anything.
|
442
445
|
#
|
@@ -559,6 +562,136 @@ EOT
|
|
559
562
|
end
|
560
563
|
end
|
561
564
|
|
565
|
+
##
|
566
|
+
# Passes if expression "+expected+ +operator+
|
567
|
+
# +actual+" is true.
|
568
|
+
#
|
569
|
+
# Example:
|
570
|
+
# assert_compare(1, "<", 10) # -> pass
|
571
|
+
# assert_compare(1, ">=", 10) # -> fail
|
572
|
+
def assert_compare(expected, operator, actual, message=nil)
|
573
|
+
_wrap_assertion do
|
574
|
+
assert_send([["<", "<=", ">", ">="], :include?, operator.to_s])
|
575
|
+
case operator.to_s
|
576
|
+
when "<"
|
577
|
+
operator_description = "less than"
|
578
|
+
when "<="
|
579
|
+
operator_description = "less than or equal to"
|
580
|
+
when ">"
|
581
|
+
operator_description = "greater than"
|
582
|
+
when ">="
|
583
|
+
operator_description = "greater than or equal to"
|
584
|
+
end
|
585
|
+
template = <<-EOT
|
586
|
+
<?> #{operator} <?> should be true
|
587
|
+
<?> expected #{operator_description}
|
588
|
+
<?>.
|
589
|
+
EOT
|
590
|
+
full_message = build_message(message, template,
|
591
|
+
expected, actual,
|
592
|
+
expected, actual)
|
593
|
+
assert_block(full_message) do
|
594
|
+
expected.send(operator, actual)
|
595
|
+
end
|
596
|
+
end
|
597
|
+
end
|
598
|
+
|
599
|
+
##
|
600
|
+
# Passes if assertion is failed in block.
|
601
|
+
#
|
602
|
+
# Example:
|
603
|
+
# assert_fail_assertion {assert_equal("A", "B")} # -> pass
|
604
|
+
# assert_fail_assertion {assert_equal("A", "A")} # -> fail
|
605
|
+
def assert_fail_assertion(message=nil)
|
606
|
+
_wrap_assertion do
|
607
|
+
full_message = build_message(message,
|
608
|
+
"Failed assertion was expected.")
|
609
|
+
assert_block(full_message) do
|
610
|
+
begin
|
611
|
+
yield
|
612
|
+
false
|
613
|
+
rescue AssertionFailedError
|
614
|
+
true
|
615
|
+
end
|
616
|
+
end
|
617
|
+
end
|
618
|
+
end
|
619
|
+
|
620
|
+
##
|
621
|
+
# Passes if an exception is raised in block and its
|
622
|
+
# message is +expected+.
|
623
|
+
#
|
624
|
+
# Example:
|
625
|
+
# assert_raise_message("exception") {raise "exception"} # -> pass
|
626
|
+
# assert_raise_message(/exc/i) {raise "exception"} # -> pass
|
627
|
+
# assert_raise_message("exception") {raise "EXCEPTION"} # -> fail
|
628
|
+
# assert_raise_message("exception") {} # -> fail
|
629
|
+
def assert_raise_message(expected, message=nil)
|
630
|
+
_wrap_assertion do
|
631
|
+
full_message = build_message(message,
|
632
|
+
"<?> exception message expected " +
|
633
|
+
"but none was thrown.",
|
634
|
+
expected)
|
635
|
+
exception = nil
|
636
|
+
assert_block(full_message) do
|
637
|
+
begin
|
638
|
+
yield
|
639
|
+
false
|
640
|
+
rescue Exception => exception
|
641
|
+
true
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
actual = exception.message
|
646
|
+
diff = AssertionMessage.delayed_diff(expected, actual)
|
647
|
+
full_message =
|
648
|
+
build_message(message,
|
649
|
+
"<?> exception message expected but was\n" +
|
650
|
+
"<?>.?", expected, actual, diff)
|
651
|
+
assert_block(full_message) do
|
652
|
+
if expected.is_a?(Regexp)
|
653
|
+
expected =~ actual
|
654
|
+
else
|
655
|
+
expected == actual
|
656
|
+
end
|
657
|
+
end
|
658
|
+
end
|
659
|
+
end
|
660
|
+
|
661
|
+
##
|
662
|
+
# Passes if +object+.const_defined?(+constant_name+)
|
663
|
+
#
|
664
|
+
# Example:
|
665
|
+
# assert_const_defined(Test, :Unit) # -> pass
|
666
|
+
# assert_const_defined(Object, :Nonexistent) # -> fail
|
667
|
+
def assert_const_defined(object, constant_name, message=nil)
|
668
|
+
_wrap_assertion do
|
669
|
+
full_message = build_message(message,
|
670
|
+
"<?>.const_defined\\?(<?>) expected.",
|
671
|
+
object, constant_name)
|
672
|
+
assert_block(full_message) do
|
673
|
+
object.const_defined?(constant_name)
|
674
|
+
end
|
675
|
+
end
|
676
|
+
end
|
677
|
+
|
678
|
+
##
|
679
|
+
# Passes if !+object+.const_defined?(+constant_name+)
|
680
|
+
#
|
681
|
+
# Example:
|
682
|
+
# assert_not_const_defined(Object, :Nonexistent) # -> pass
|
683
|
+
# assert_not_const_defined(Test, :Unit) # -> fail
|
684
|
+
def assert_not_const_defined(object, constant_name, message=nil)
|
685
|
+
_wrap_assertion do
|
686
|
+
full_message = build_message(message,
|
687
|
+
"!<?>.const_defined\\?(<?>) expected.",
|
688
|
+
object, constant_name)
|
689
|
+
assert_block(full_message) do
|
690
|
+
!object.const_defined?(constant_name)
|
691
|
+
end
|
692
|
+
end
|
693
|
+
end
|
694
|
+
|
562
695
|
##
|
563
696
|
# Builds a failure message. +head+ is added before the +template+ and
|
564
697
|
# +arguments+ replaces the '?'s positionally in the template.
|
@@ -601,8 +734,37 @@ EOT
|
|
601
734
|
def self.use_pp=(value)
|
602
735
|
AssertionMessage.use_pp = value
|
603
736
|
end
|
604
|
-
|
737
|
+
|
605
738
|
# :stopdoc:
|
739
|
+
private
|
740
|
+
def _assert_raise(assert_expected_exception, *args, &block)
|
741
|
+
_wrap_assertion do
|
742
|
+
if args.last.is_a?(String)
|
743
|
+
message = args.pop
|
744
|
+
else
|
745
|
+
message = ""
|
746
|
+
end
|
747
|
+
|
748
|
+
assert_exception_helper = AssertExceptionHelper.new(self, args)
|
749
|
+
expected = assert_exception_helper.expected_exceptions
|
750
|
+
actual_exception = nil
|
751
|
+
full_message = build_message(message,
|
752
|
+
"<?> exception expected " +
|
753
|
+
"but none was thrown.",
|
754
|
+
expected)
|
755
|
+
assert_block(full_message) do
|
756
|
+
begin
|
757
|
+
yield
|
758
|
+
false
|
759
|
+
rescue Exception => actual_exception
|
760
|
+
true
|
761
|
+
end
|
762
|
+
end
|
763
|
+
assert_expected_exception.call(message, assert_exception_helper,
|
764
|
+
actual_exception)
|
765
|
+
actual_exception
|
766
|
+
end
|
767
|
+
end
|
606
768
|
|
607
769
|
class AssertionMessage
|
608
770
|
@use_pp = true
|
@@ -617,6 +779,31 @@ EOT
|
|
617
779
|
DelayedLiteral.new(block)
|
618
780
|
end
|
619
781
|
|
782
|
+
def delayed_diff(from, to)
|
783
|
+
delayed_literal do
|
784
|
+
if !from.is_a?(String) or !to.is_a?(String)
|
785
|
+
from = convert(from)
|
786
|
+
to = convert(to)
|
787
|
+
end
|
788
|
+
|
789
|
+
diff = Diff.readable(from, to)
|
790
|
+
if /^[-+]/ !~ diff
|
791
|
+
diff = ""
|
792
|
+
elsif /^[ ?]/ =~ diff or /(?:.*\n){2,}/ =~ diff
|
793
|
+
diff = "\n\ndiff:\n#{diff}"
|
794
|
+
else
|
795
|
+
diff = ""
|
796
|
+
end
|
797
|
+
|
798
|
+
if Diff.need_fold?(diff)
|
799
|
+
folded_diff = Diff.folded_readable(from, to)
|
800
|
+
diff << "\n\nfolded diff:\n#{folded_diff}"
|
801
|
+
end
|
802
|
+
|
803
|
+
diff
|
804
|
+
end
|
805
|
+
end
|
806
|
+
|
620
807
|
def convert(object)
|
621
808
|
case object
|
622
809
|
when Exception
|
@@ -715,8 +902,105 @@ EOM
|
|
715
902
|
end
|
716
903
|
end
|
717
904
|
|
718
|
-
|
905
|
+
class AssertExceptionHelper
|
906
|
+
class WrappedException
|
907
|
+
def initialize(exception)
|
908
|
+
@exception = exception
|
909
|
+
end
|
910
|
+
|
911
|
+
def inspect
|
912
|
+
inspect_method = @exception.method(:inspect)
|
913
|
+
if inspect_method.respond_to?(:owner) and
|
914
|
+
inspect_method.owner == Exception
|
915
|
+
"#{@exception.class.inspect}(#{@exception.message.inspect})"
|
916
|
+
else
|
917
|
+
@exception.inspect
|
918
|
+
end
|
919
|
+
end
|
920
|
+
|
921
|
+
def method_missing(name, *args, &block)
|
922
|
+
@exception.send(name, *args, &block)
|
923
|
+
end
|
924
|
+
end
|
925
|
+
|
926
|
+
def initialize(test_case, expected_exceptions)
|
927
|
+
@test_case = test_case
|
928
|
+
@expected_exceptions = expected_exceptions
|
929
|
+
@expected_classes, @expected_modules, @expected_objects =
|
930
|
+
split_expected_exceptions(expected_exceptions)
|
931
|
+
end
|
932
|
+
|
933
|
+
def expected_exceptions
|
934
|
+
exceptions = @expected_exceptions.collect do |exception|
|
935
|
+
if exception.is_a?(Exception)
|
936
|
+
WrappedException.new(exception)
|
937
|
+
else
|
938
|
+
exception
|
939
|
+
end
|
940
|
+
end
|
941
|
+
if exceptions.size == 1
|
942
|
+
exceptions[0]
|
943
|
+
else
|
944
|
+
exceptions
|
945
|
+
end
|
946
|
+
end
|
947
|
+
|
948
|
+
def expected?(actual_exception, equality=nil)
|
949
|
+
equality ||= :instance_of?
|
950
|
+
expected_class?(actual_exception, equality) or
|
951
|
+
expected_module?(actual_exception) or
|
952
|
+
expected_object?(actual_exception)
|
953
|
+
end
|
954
|
+
|
955
|
+
private
|
956
|
+
def split_expected_exceptions(expected_exceptions)
|
957
|
+
exception_modules = []
|
958
|
+
exception_objects = []
|
959
|
+
exception_classes = []
|
960
|
+
expected_exceptions.each do |exception_type|
|
961
|
+
if exception_type.instance_of?(Module)
|
962
|
+
exception_modules << exception_type
|
963
|
+
elsif exception_type.is_a?(Exception)
|
964
|
+
exception_objects << exception_type
|
965
|
+
else
|
966
|
+
@test_case.send(:assert,
|
967
|
+
Exception >= exception_type,
|
968
|
+
"Should expect a class of exception, " +
|
969
|
+
"#{exception_type}")
|
970
|
+
exception_classes << exception_type
|
971
|
+
end
|
972
|
+
end
|
973
|
+
[exception_classes, exception_modules, exception_objects]
|
974
|
+
end
|
975
|
+
|
976
|
+
def expected_class?(actual_exception, equality)
|
977
|
+
@expected_classes.any? do |expected_class|
|
978
|
+
actual_exception.send(equality, expected_class)
|
979
|
+
end
|
980
|
+
end
|
719
981
|
|
982
|
+
def expected_module?(actual_exception)
|
983
|
+
@expected_modules.any? do |expected_module|
|
984
|
+
actual_exception.is_a?(expected_module)
|
985
|
+
end
|
986
|
+
end
|
987
|
+
|
988
|
+
def expected_object?(actual_exception)
|
989
|
+
@expected_objects.any? do |expected_object|
|
990
|
+
equal_method = expected_object.method(:==)
|
991
|
+
if equal_method.respond_to?(:owner) and
|
992
|
+
(equal_method.owner == Kernel or
|
993
|
+
equal_method.owner == Exception)
|
994
|
+
expected_object.class == actual_exception.class and
|
995
|
+
expected_object.message == actual_exception.message
|
996
|
+
else
|
997
|
+
expected_object == actual_exception
|
998
|
+
end
|
999
|
+
end
|
1000
|
+
end
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
# :startdoc:
|
720
1004
|
end
|
721
1005
|
end
|
722
1006
|
end
|