test-unit 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/History.txt +5 -0
  2. data/Manifest.txt +48 -0
  3. data/README.txt +27 -0
  4. data/Rakefile +15 -0
  5. data/bin/testrb +5 -0
  6. data/lib/test/unit.rb +280 -0
  7. data/lib/test/unit/assertionfailederror.rb +14 -0
  8. data/lib/test/unit/assertions.rb +622 -0
  9. data/lib/test/unit/autorunner.rb +220 -0
  10. data/lib/test/unit/collector.rb +43 -0
  11. data/lib/test/unit/collector/dir.rb +108 -0
  12. data/lib/test/unit/collector/objectspace.rb +34 -0
  13. data/lib/test/unit/error.rb +56 -0
  14. data/lib/test/unit/failure.rb +51 -0
  15. data/lib/test/unit/testcase.rb +160 -0
  16. data/lib/test/unit/testresult.rb +80 -0
  17. data/lib/test/unit/testsuite.rb +76 -0
  18. data/lib/test/unit/ui/console/testrunner.rb +127 -0
  19. data/lib/test/unit/ui/fox/testrunner.rb +268 -0
  20. data/lib/test/unit/ui/gtk/testrunner.rb +416 -0
  21. data/lib/test/unit/ui/gtk2/testrunner.rb +465 -0
  22. data/lib/test/unit/ui/testrunnermediator.rb +68 -0
  23. data/lib/test/unit/ui/testrunnerutilities.rb +46 -0
  24. data/lib/test/unit/ui/tk/testrunner.rb +260 -0
  25. data/lib/test/unit/util/backtracefilter.rb +40 -0
  26. data/lib/test/unit/util/observable.rb +90 -0
  27. data/lib/test/unit/util/procwrapper.rb +48 -0
  28. data/lib/test/unit/version.rb +7 -0
  29. data/sample/adder.rb +13 -0
  30. data/sample/subtracter.rb +12 -0
  31. data/sample/tc_adder.rb +18 -0
  32. data/sample/tc_subtracter.rb +18 -0
  33. data/sample/ts_examples.rb +7 -0
  34. data/test/collector/test_dir.rb +406 -0
  35. data/test/collector/test_objectspace.rb +98 -0
  36. data/test/runit/test_assert.rb +402 -0
  37. data/test/runit/test_testcase.rb +91 -0
  38. data/test/runit/test_testresult.rb +144 -0
  39. data/test/runit/test_testsuite.rb +49 -0
  40. data/test/test_assertions.rb +528 -0
  41. data/test/test_error.rb +26 -0
  42. data/test/test_failure.rb +33 -0
  43. data/test/test_testcase.rb +275 -0
  44. data/test/test_testresult.rb +104 -0
  45. data/test/test_testsuite.rb +129 -0
  46. data/test/util/test_backtracefilter.rb +41 -0
  47. data/test/util/test_observable.rb +102 -0
  48. data/test/util/test_procwrapper.rb +36 -0
  49. metadata +128 -0
@@ -0,0 +1,26 @@
1
+ # Author:: Nathaniel Talbott.
2
+ # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
3
+ # License:: Ruby license.
4
+
5
+ require 'test/unit'
6
+
7
+ module Test
8
+ module Unit
9
+ class TC_Error < TestCase
10
+ TF_Exception = Struct.new('TF_Exception', :message, :backtrace)
11
+ def test_display
12
+ ex = TF_Exception.new("message1\nmessage2", ['line1', 'line2'])
13
+ e = Error.new("name", ex)
14
+ assert_equal("name: #{TF_Exception.name}: message1", e.short_display)
15
+ assert_equal(<<EOM.strip, e.long_display)
16
+ Error:
17
+ name:
18
+ Struct::TF_Exception: message1
19
+ message2
20
+ line1
21
+ line2
22
+ EOM
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,33 @@
1
+ # Author:: Nathaniel Talbott.
2
+ # Copyright:: Copyright (c) 2003 Nathaniel Talbott. All rights reserved.
3
+ # License:: Ruby license.
4
+
5
+ require 'test/unit'
6
+ require 'test/unit/failure'
7
+
8
+ module Test::Unit
9
+ class TestFailure < TestCase
10
+ def test_display
11
+ f = Failure.new("name", [%q{location:1 in 'l'}], "message1\nmessage2")
12
+ assert_equal("name: message1", f.short_display)
13
+ assert_equal(<<EOM.strip, f.long_display)
14
+ Failure:
15
+ name [location:1]:
16
+ message1
17
+ message2
18
+ EOM
19
+
20
+ f = Failure.new("name", [%q{location1:2 in 'l1'}, 'location2:1', %q{location3:3 in 'l3'}], "message1\nmessage2")
21
+ assert_equal("name: message1", f.short_display)
22
+ assert_equal(<<EOM.strip, f.long_display)
23
+ Failure:
24
+ name
25
+ [location1:2 in 'l1'
26
+ location2:1
27
+ location3:3 in 'l3']:
28
+ message1
29
+ message2
30
+ EOM
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,275 @@
1
+ # Author:: Nathaniel Talbott.
2
+ # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
3
+ # License:: Ruby license.
4
+
5
+ require 'test/unit'
6
+
7
+ module Test
8
+ module Unit
9
+ class TC_TestCase < TestCase
10
+ def test_creation
11
+ tc = Class.new(TestCase) do
12
+ def test_with_arguments(arg1, arg2)
13
+ end
14
+ end
15
+
16
+ caught = true
17
+ catch(:invalid_test) do
18
+ tc.new(:test_with_arguments)
19
+ caught = false
20
+ end
21
+ check("Should have caught an invalid test when there are arguments", caught)
22
+
23
+ caught = true
24
+ catch(:invalid_test) do
25
+ tc.new(:non_existent_test)
26
+ caught = false
27
+ end
28
+ check("Should have caught an invalid test when the method does not exist", caught)
29
+ end
30
+
31
+ def setup
32
+ @tc_failure_error = Class.new(TestCase) do
33
+ def test_failure
34
+ assert_block("failure") { false }
35
+ end
36
+ def test_error
37
+ 1 / 0
38
+ end
39
+ def test_nested_failure
40
+ nested
41
+ end
42
+ def nested
43
+ assert_block("nested"){false}
44
+ end
45
+ def return_passed?
46
+ return passed?
47
+ end
48
+ end
49
+
50
+ def @tc_failure_error.name
51
+ "TC_FailureError"
52
+ end
53
+ end
54
+
55
+ def test_add_failed_assertion
56
+ test_case = @tc_failure_error.new(:test_failure)
57
+ check("passed? should start out true", test_case.return_passed?)
58
+ result = TestResult.new
59
+ called = false
60
+ result.add_listener(TestResult::FAULT) {
61
+ | fault |
62
+ check("Should have a Failure", fault.instance_of?(Failure))
63
+ check("The Failure should have the correct message", "failure" == fault.message)
64
+ check("The Failure should have the correct test_name (was <#{fault.test_name}>)", fault.test_name == "test_failure(TC_FailureError)")
65
+ r = /\A.*#{Regexp.escape(File.basename(__FILE__))}:\d+:in `test_failure'\Z/
66
+
67
+ location = fault.location
68
+ check("The location should be an array", location.kind_of?(Array))
69
+ check("The location should have two lines (was: <#{location.inspect}>)", location.size == 2)
70
+ check("The Failure should have the correct location (was <#{location[0].inspect}>, expected <#{r.inspect}>)", r =~ location[0])
71
+ called = true
72
+ }
73
+ progress = []
74
+ test_case.run(result) { |*arguments| progress << arguments }
75
+ check("The failure should have triggered the listener", called)
76
+ check("The failure should have set passed?", !test_case.return_passed?)
77
+ check("The progress block should have been updated correctly", [[TestCase::STARTED, test_case.name], [TestCase::FINISHED, test_case.name]] == progress)
78
+ end
79
+
80
+ def test_add_failure_nested
81
+ test_case = @tc_failure_error.new(:test_nested_failure)
82
+ check("passed? should start out true", test_case.return_passed?)
83
+
84
+ result = TestResult.new
85
+ called = false
86
+ result.add_listener(TestResult::FAULT) {
87
+ | fault |
88
+ check("Should have a Failure", fault.instance_of?(Failure))
89
+ check("The Failure should have the correct message", "nested" == fault.message)
90
+ check("The Failure should have the correct test_name (was <#{fault.test_name}>)", fault.test_name == "test_nested_failure(TC_FailureError)")
91
+ r =
92
+
93
+ location = fault.location
94
+ check("The location should be an array", location.kind_of?(Array))
95
+ check("The location should have the correct number of lines (was: <#{location.inspect}>)", location.size == 3)
96
+ check("The Failure should have the correct location (was <#{location[0].inspect}>)", /\A.*#{Regexp.escape(File.basename(__FILE__))}:\d+:in `nested'\Z/ =~ location[0])
97
+ check("The Failure should have the correct location (was <#{location[1].inspect}>)", /\A.*#{Regexp.escape(File.basename(__FILE__))}:\d+:in `test_nested_failure'\Z/ =~ location[1])
98
+ called = true
99
+ }
100
+ test_case.run(result){}
101
+ check("The failure should have triggered the listener", called)
102
+ end
103
+
104
+ def test_add_error
105
+ test_case = @tc_failure_error.new(:test_error)
106
+ check("passed? should start out true", test_case.return_passed?)
107
+ result = TestResult.new
108
+ called = false
109
+ result.add_listener(TestResult::FAULT) {
110
+ | fault |
111
+ check("Should have a TestError", fault.instance_of?(Error))
112
+ check("The Error should have the correct message", "ZeroDivisionError: divided by 0" == fault.message)
113
+ check("The Error should have the correct test_name", "test_error(TC_FailureError)" == fault.test_name)
114
+ check("The Error should have the correct exception", fault.exception.instance_of?(ZeroDivisionError))
115
+ called = true
116
+ }
117
+ test_case.run(result) {}
118
+ check("The error should have triggered the listener", called)
119
+ check("The error should have set passed?", !test_case.return_passed?)
120
+ end
121
+
122
+ def test_no_tests
123
+ suite = TestCase.suite
124
+ check("Should have a test suite", suite.instance_of?(TestSuite))
125
+ check("Should have one test", suite.size == 1)
126
+ check("Should have the default test", suite.tests.first.name == "default_test(Test::Unit::TestCase)")
127
+
128
+ result = TestResult.new
129
+ suite.run(result) {}
130
+ check("Should have had one test run", result.run_count == 1)
131
+ check("Should have had one test failure", result.failure_count == 1)
132
+ check("Should have had no errors", result.error_count == 0)
133
+ end
134
+
135
+ def test_suite
136
+ tc = Class.new(TestCase) do
137
+ def test_succeed
138
+ assert_block {true}
139
+ end
140
+ def test_fail
141
+ assert_block {false}
142
+ end
143
+ def test_error
144
+ 1/0
145
+ end
146
+ def dont_run
147
+ assert_block {true}
148
+ end
149
+ def test_dont_run(argument)
150
+ assert_block {true}
151
+ end
152
+ def test
153
+ assert_block {true}
154
+ end
155
+ end
156
+
157
+ suite = tc.suite
158
+ check("Should have a test suite", suite.instance_of?(TestSuite))
159
+ check("Should have three tests", suite.size == 3)
160
+
161
+ result = TestResult.new
162
+ suite.run(result) {}
163
+ check("Should have had three test runs", result.run_count == 3)
164
+ check("Should have had one test failure", result.failure_count == 1)
165
+ check("Should have had one test error", result.error_count == 1)
166
+ end
167
+
168
+
169
+ def test_setup_teardown
170
+ tc = Class.new(TestCase) do
171
+ attr_reader(:setup_called, :teardown_called)
172
+ def initialize(test)
173
+ super(test)
174
+ @setup_called = false
175
+ @teardown_called = false
176
+ end
177
+ def setup
178
+ @setup_called = true
179
+ end
180
+ def teardown
181
+ @teardown_called = true
182
+ end
183
+ def test_succeed
184
+ assert_block {true}
185
+ end
186
+ def test_fail
187
+ assert_block {false}
188
+ end
189
+ def test_error
190
+ raise "Error!"
191
+ end
192
+ end
193
+ result = TestResult.new
194
+
195
+ test = tc.new(:test_succeed)
196
+ test.run(result) {}
197
+ check("Should have called setup the correct number of times", test.setup_called)
198
+ check("Should have called teardown the correct number of times", test.teardown_called)
199
+
200
+ test = tc.new(:test_fail)
201
+ test.run(result) {}
202
+ check("Should have called setup the correct number of times", test.setup_called)
203
+ check("Should have called teardown the correct number of times", test.teardown_called)
204
+
205
+ test = tc.new(:test_error)
206
+ test.run(result) {}
207
+ check("Should have called setup the correct number of times", test.setup_called)
208
+ check("Should have called teardown the correct number of times", test.teardown_called)
209
+
210
+ check("Should have had two test runs", result.run_count == 3)
211
+ check("Should have had a test failure", result.failure_count == 1)
212
+ check("Should have had a test error", result.error_count == 1)
213
+ end
214
+
215
+ def test_assertion_failed_not_called
216
+ tc = Class.new(TestCase) do
217
+ def test_thing
218
+ raise AssertionFailedError.new
219
+ end
220
+ end
221
+
222
+ suite = tc.suite
223
+ check("Should have one test", suite.size == 1)
224
+ result = TestResult.new
225
+ suite.run(result) {}
226
+ check("Should have had one test run", result.run_count == 1)
227
+ check("Should have had one assertion failure", result.failure_count == 1)
228
+ check("Should not have any assertion errors but had #{result.error_count}", result.error_count == 0)
229
+ end
230
+
231
+ def test_equality
232
+ tc1 = Class.new(TestCase) do
233
+ def test_1
234
+ end
235
+ def test_2
236
+ end
237
+ end
238
+
239
+ tc2 = Class.new(TestCase) do
240
+ def test_1
241
+ end
242
+ end
243
+
244
+ test1 = tc1.new('test_1')
245
+ test2 = tc1.new('test_1')
246
+ check("Should be equal", test1 == test2)
247
+ check("Should be equal", test2 == test1)
248
+
249
+ test1 = tc1.new('test_2')
250
+ check("Should not be equal", test1 != test2)
251
+ check("Should not be equal", test2 != test1)
252
+
253
+ test2 = tc1.new('test_2')
254
+ check("Should be equal", test1 == test2)
255
+ check("Should be equal", test2 == test1)
256
+
257
+ test1 = tc1.new('test_1')
258
+ test2 = tc2.new('test_1')
259
+ check("Should not be equal", test1 != test2)
260
+ check("Should not be equal", test2 != test1)
261
+
262
+
263
+ check("Should not be equal", test1 != Object.new)
264
+ check("Should not be equal", Object.new != test1)
265
+ end
266
+
267
+ def check(message, passed)
268
+ @_result.add_assertion
269
+ if ! passed
270
+ raise AssertionFailedError.new(message)
271
+ end
272
+ end
273
+ end
274
+ end
275
+ end
@@ -0,0 +1,104 @@
1
+ # Author:: Nathaniel Talbott.
2
+ # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
3
+ # License:: Ruby license.
4
+
5
+ require 'test/unit/testcase'
6
+ require 'test/unit/testresult'
7
+
8
+ module Test
9
+ module Unit
10
+ class TC_TestResult < TestCase
11
+ def setup
12
+ @my_result = TestResult.new
13
+ @my_result.add_assertion()
14
+ @my_result.add_failure("")
15
+ @my_result.add_error("")
16
+ end
17
+ def test_result_changed_notification
18
+ called1 = false
19
+ @my_result.add_listener( TestResult::CHANGED) {
20
+ |result|
21
+ assert_block("The result should be correct") { result == @my_result }
22
+ called1 = true
23
+ }
24
+ @my_result.add_assertion
25
+ assert_block("Should have been notified when the assertion happened") { called1 }
26
+
27
+ called1, called2 = false, false
28
+ @my_result.add_listener( TestResult::CHANGED) {
29
+ |result|
30
+ assert_block("The result should be correct") { result == @my_result }
31
+ called2 = true
32
+ }
33
+ @my_result.add_assertion
34
+ assert_block("Both listeners should have been notified for a success") { called1 && called2 }
35
+
36
+ called1, called2 = false, false
37
+ @my_result.add_failure("")
38
+ assert_block("Both listeners should have been notified for a failure") { called1 && called2 }
39
+
40
+ called1, called2 = false, false
41
+ @my_result.add_error("")
42
+ assert_block("Both listeners should have been notified for an error") { called1 && called2 }
43
+
44
+ called1, called2 = false, false
45
+ @my_result.add_run
46
+ assert_block("Both listeners should have been notified for a run") { called1 && called2 }
47
+ end
48
+ def test_fault_notification
49
+ called1 = false
50
+ fault = "fault"
51
+ @my_result.add_listener(TestResult::FAULT) {
52
+ | passed_fault |
53
+ assert_block("The fault should be correct") { passed_fault == fault }
54
+ called1 = true
55
+ }
56
+
57
+ @my_result.add_assertion
58
+ assert_block("Should not have been notified when the assertion happened") { !called1 }
59
+
60
+ @my_result.add_failure(fault)
61
+ assert_block("Should have been notified when the failure happened") { called1 }
62
+
63
+ called1, called2 = false, false
64
+ @my_result.add_listener(TestResult::FAULT) {
65
+ | passed_fault |
66
+ assert_block("The fault should be correct") { passed_fault == fault }
67
+ called2 = true
68
+ }
69
+
70
+ @my_result.add_assertion
71
+ assert_block("Neither listener should have been notified for a success") { !(called1 || called2) }
72
+
73
+ called1, called2 = false, false
74
+ @my_result.add_failure(fault)
75
+ assert_block("Both listeners should have been notified for a failure") { called1 && called2 }
76
+
77
+ called1, called2 = false, false
78
+ @my_result.add_error(fault)
79
+ assert_block("Both listeners should have been notified for an error") { called1 && called2 }
80
+
81
+ called1, called2 = false, false
82
+ @my_result.add_run
83
+ assert_block("Neither listener should have been notified for a run") { !(called1 || called2) }
84
+ end
85
+ def test_passed?
86
+ result = TestResult.new
87
+ assert(result.passed?, "An empty result should have passed")
88
+
89
+ result.add_assertion
90
+ assert(result.passed?, "Adding an assertion should not cause the result to not pass")
91
+
92
+ result.add_run
93
+ assert(result.passed?, "Adding a run should not cause the result to not pass")
94
+
95
+ result.add_failure("")
96
+ assert(!result.passed?, "Adding a failed assertion should cause the result to not pass")
97
+
98
+ result = TestResult.new
99
+ result.add_error("")
100
+ assert(!result.passed?, "Adding an error should cause the result to not pass")
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,129 @@
1
+ # Author:: Nathaniel Talbott.
2
+ # Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
3
+ # License:: Ruby license.
4
+
5
+ require 'test/unit'
6
+
7
+ module Test
8
+ module Unit
9
+ class TC_TestSuite < TestCase
10
+ def setup
11
+ @testcase1 = Class.new(TestCase) do
12
+ def test_succeed1
13
+ assert_block { true }
14
+ end
15
+ def test_fail
16
+ assert_block { false }
17
+ end
18
+ end
19
+
20
+ @testcase2 = Class.new(TestCase) do
21
+ def test_succeed2
22
+ assert_block { true }
23
+ end
24
+ def test_error
25
+ raise
26
+ end
27
+ end
28
+ end
29
+
30
+ def test_add
31
+ s = TestSuite.new
32
+ assert_equal(s, s << self.class.new("test_add"))
33
+ end
34
+
35
+ def test_delete
36
+ s = TestSuite.new
37
+ t1 = self.class.new("test_delete")
38
+ s << t1
39
+ t2 = self.class.new("test_add")
40
+ s << t2
41
+ assert_equal(t1, s.delete(t1))
42
+ assert_nil(s.delete(t1))
43
+ assert_equal(TestSuite.new << t2, s)
44
+ end
45
+
46
+ def test_size
47
+ suite = TestSuite.new
48
+ suite2 = TestSuite.new
49
+ suite2 << self.class.new("test_size")
50
+ suite << suite2
51
+ suite << self.class.new("test_size")
52
+ assert_equal(2, suite.size, "The count should be correct")
53
+ end
54
+
55
+ def test_run
56
+ progress = []
57
+ suite = @testcase1.suite
58
+ result = TestResult.new
59
+ suite.run(result) { |*values| progress << values }
60
+
61
+ assert_equal(2, result.run_count, "Should have had four test runs")
62
+ assert_equal(1, result.failure_count, "Should have had one test failure")
63
+ assert_equal(0, result.error_count, "Should have had one test error")
64
+ assert_equal([[TestSuite::STARTED, suite.name],
65
+ [TestCase::STARTED, "test_fail(#{suite.name})"],
66
+ [TestCase::FINISHED, "test_fail(#{suite.name})"],
67
+ [TestCase::STARTED, "test_succeed1(#{suite.name})"],
68
+ [TestCase::FINISHED, "test_succeed1(#{suite.name})"],
69
+ [TestSuite::FINISHED, suite.name]],
70
+ progress, "Should have had the correct progress")
71
+
72
+ suite = TestSuite.new
73
+ suite << @testcase1.suite
74
+ suite << @testcase2.suite
75
+ result = TestResult.new
76
+ progress = []
77
+ suite.run(result) { |*values| progress << values }
78
+
79
+ assert_equal(4, result.run_count, "Should have had four test runs")
80
+ assert_equal(1, result.failure_count, "Should have had one test failure")
81
+ assert_equal(1, result.error_count, "Should have had one test error")
82
+ assert_equal(14, progress.size, "Should have had the correct number of progress calls")
83
+ end
84
+
85
+ def test_empty?
86
+ assert(TestSuite.new.empty?, "A new test suite should be empty?")
87
+ assert(!@testcase2.suite.empty?, "A test suite with tests should not be empty")
88
+ end
89
+
90
+ def test_equality
91
+ suite1 = TestSuite.new
92
+ suite2 = TestSuite.new
93
+ assert_equal(suite1, suite2)
94
+ assert_equal(suite2, suite1)
95
+
96
+ suite1 = TestSuite.new('name')
97
+ assert_not_equal(suite1, suite2)
98
+ assert_not_equal(suite2, suite1)
99
+
100
+ suite2 = TestSuite.new('name')
101
+ assert_equal(suite1, suite2)
102
+ assert_equal(suite2, suite1)
103
+
104
+ suite1 << 'test'
105
+ assert_not_equal(suite1, suite2)
106
+ assert_not_equal(suite2, suite1)
107
+
108
+ suite2 << 'test'
109
+ assert_equal(suite1, suite2)
110
+ assert_equal(suite2, suite1)
111
+
112
+ suite2 = Object.new
113
+ class << suite2
114
+ def name
115
+ 'name'
116
+ end
117
+ def tests
118
+ ['test']
119
+ end
120
+ end
121
+ assert_not_equal(suite1, suite2)
122
+ assert_not_equal(suite2, suite1)
123
+
124
+ assert_not_equal(suite1, Object.new)
125
+ assert_not_equal(Object.new, suite1)
126
+ end
127
+ end
128
+ end
129
+ end