test-unit 1.2.3

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.
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