test-unit 1.2.3 → 2.0.0
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 +27 -0
- data/Manifest.txt +30 -8
- data/README.txt +9 -4
- data/Rakefile +16 -1
- data/bin/testrb +0 -0
- data/lib/test/unit/assertions.rb +148 -48
- data/lib/test/unit/attribute.rb +125 -0
- data/lib/test/unit/autorunner.rb +101 -71
- data/lib/test/unit/collector/descendant.rb +23 -0
- data/lib/test/unit/collector/dir.rb +1 -1
- data/lib/test/unit/collector/load.rb +135 -0
- data/lib/test/unit/color.rb +61 -0
- data/lib/test/unit/diff.rb +524 -0
- data/lib/test/unit/error.rb +70 -2
- data/lib/test/unit/exceptionhandler.rb +39 -0
- data/lib/test/unit/failure.rb +63 -4
- data/lib/test/unit/fixture.rb +185 -0
- data/lib/test/unit/notification.rb +125 -0
- data/lib/test/unit/omission.rb +143 -0
- data/lib/test/unit/pending.rb +146 -0
- data/lib/test/unit/priority.rb +146 -0
- data/lib/test/unit/runner/console.rb +46 -0
- data/lib/test/unit/runner/emacs.rb +8 -0
- data/lib/test/unit/testcase.rb +193 -76
- data/lib/test/unit/testresult.rb +37 -28
- data/lib/test/unit/testsuite.rb +35 -1
- data/lib/test/unit/ui/console/outputlevel.rb +14 -0
- data/lib/test/unit/ui/console/testrunner.rb +96 -28
- data/lib/test/unit/ui/emacs/testrunner.rb +49 -0
- data/lib/test/unit/ui/testrunner.rb +20 -0
- data/lib/test/unit/ui/testrunnermediator.rb +28 -19
- data/lib/test/unit/ui/testrunnerutilities.rb +2 -7
- data/lib/test/unit/util/backtracefilter.rb +2 -1
- data/lib/test/unit/version.rb +1 -1
- data/test/collector/test_descendant.rb +135 -0
- data/test/collector/test_load.rb +333 -0
- data/test/run-test.rb +13 -0
- data/test/test_assertions.rb +221 -56
- data/test/test_attribute.rb +86 -0
- data/test/test_color.rb +37 -0
- data/test/test_diff.rb +477 -0
- data/test/test_emacs_runner.rb +60 -0
- data/test/test_fixture.rb +275 -0
- data/test/test_notification.rb +33 -0
- data/test/test_omission.rb +81 -0
- data/test/test_pending.rb +70 -0
- data/test/test_priority.rb +89 -0
- data/test/test_testcase.rb +160 -5
- data/test/test_testresult.rb +61 -52
- data/test/testunit_test_util.rb +14 -0
- data/test/ui/test_testrunmediator.rb +20 -0
- metadata +53 -23
- data/lib/test/unit/ui/fox/testrunner.rb +0 -268
- data/lib/test/unit/ui/gtk/testrunner.rb +0 -416
- data/lib/test/unit/ui/gtk2/testrunner.rb +0 -465
- data/lib/test/unit/ui/tk/testrunner.rb +0 -260
- data/test/runit/test_assert.rb +0 -402
- data/test/runit/test_testcase.rb +0 -91
- data/test/runit/test_testresult.rb +0 -144
- data/test/runit/test_testsuite.rb +0 -49
data/lib/test/unit/testsuite.rb
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
|
5
5
|
# License:: Ruby license.
|
6
6
|
|
7
|
+
require 'test/unit/error'
|
8
|
+
|
7
9
|
module Test
|
8
10
|
module Unit
|
9
11
|
|
@@ -21,18 +23,21 @@ module Test
|
|
21
23
|
FINISHED = name + "::FINISHED"
|
22
24
|
|
23
25
|
# Creates a new TestSuite with the given name.
|
24
|
-
def initialize(name="Unnamed TestSuite")
|
26
|
+
def initialize(name="Unnamed TestSuite", test_case=nil)
|
25
27
|
@name = name
|
26
28
|
@tests = []
|
29
|
+
@test_case = test_case
|
27
30
|
end
|
28
31
|
|
29
32
|
# Runs the tests and/or suites contained in this
|
30
33
|
# TestSuite.
|
31
34
|
def run(result, &progress_block)
|
32
35
|
yield(STARTED, name)
|
36
|
+
run_startup(result)
|
33
37
|
@tests.each do |test|
|
34
38
|
test.run(result, &progress_block)
|
35
39
|
end
|
40
|
+
run_shutdown(result)
|
36
41
|
yield(FINISHED, name)
|
37
42
|
end
|
38
43
|
|
@@ -71,6 +76,35 @@ module Test
|
|
71
76
|
return false unless(@name == other.name)
|
72
77
|
@tests == other.tests
|
73
78
|
end
|
79
|
+
|
80
|
+
private
|
81
|
+
def run_startup(result)
|
82
|
+
return if @test_case.nil? or !@test_case.respond_to?(:startup)
|
83
|
+
begin
|
84
|
+
@test_case.startup
|
85
|
+
rescue Exception
|
86
|
+
raise unless handle_exception($!, result)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def run_shutdown(result)
|
91
|
+
return if @test_case.nil? or !@test_case.respond_to?(:shutdown)
|
92
|
+
begin
|
93
|
+
@test_case.shutdown
|
94
|
+
rescue Exception
|
95
|
+
raise unless handle_exception($!, result)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def handle_exception(exception, result)
|
100
|
+
case exception
|
101
|
+
when *ErrorHandler::PASS_THROUGH_EXCEPTIONS
|
102
|
+
false
|
103
|
+
else
|
104
|
+
result.add_error(Error.new(@test_case.name, exception))
|
105
|
+
true
|
106
|
+
end
|
107
|
+
end
|
74
108
|
end
|
75
109
|
end
|
76
110
|
end
|
@@ -4,8 +4,10 @@
|
|
4
4
|
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
|
5
5
|
# License:: Ruby license.
|
6
6
|
|
7
|
+
require 'test/unit/color'
|
8
|
+
require 'test/unit/ui/testrunner'
|
7
9
|
require 'test/unit/ui/testrunnermediator'
|
8
|
-
require 'test/unit/ui/
|
10
|
+
require 'test/unit/ui/console/outputlevel'
|
9
11
|
|
10
12
|
module Test
|
11
13
|
module Unit
|
@@ -13,8 +15,19 @@ module Test
|
|
13
15
|
module Console
|
14
16
|
|
15
17
|
# Runs a Test::Unit::TestSuite on the console.
|
16
|
-
class TestRunner
|
17
|
-
|
18
|
+
class TestRunner < UI::TestRunner
|
19
|
+
include OutputLevel
|
20
|
+
|
21
|
+
COLOR_SCHEMES = {
|
22
|
+
:default => {
|
23
|
+
"success" => Color.new("green", :bold => true),
|
24
|
+
"failure" => Color.new("red", :bold => true),
|
25
|
+
"pending" => Color.new("magenta", :bold => true),
|
26
|
+
"omission" => Color.new("blue", :bold => true),
|
27
|
+
"notification" => Color.new("cyan", :bold => true),
|
28
|
+
"error" => Color.new("yellow", :bold => true),
|
29
|
+
},
|
30
|
+
}
|
18
31
|
|
19
32
|
# Creates a new TestRunner for running the passed
|
20
33
|
# suite. If quiet_mode is true, the output while
|
@@ -22,14 +35,14 @@ module Test
|
|
22
35
|
# failures, and the final result. io specifies
|
23
36
|
# where runner output should go to; defaults to
|
24
37
|
# STDOUT.
|
25
|
-
def initialize(suite,
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
@
|
32
|
-
@
|
38
|
+
def initialize(suite, options={})
|
39
|
+
super
|
40
|
+
@output_level = @options[:output_level] || NORMAL
|
41
|
+
@output = @options[:output] || STDOUT
|
42
|
+
@use_color = @options[:use_color]
|
43
|
+
@use_color = guess_color_availability if @use_color.nil?
|
44
|
+
@color_scheme = COLOR_SCHEMES[:default]
|
45
|
+
@reset_color = Color.new("reset")
|
33
46
|
@already_outputted = false
|
34
47
|
@faults = []
|
35
48
|
end
|
@@ -44,13 +57,15 @@ module Test
|
|
44
57
|
private
|
45
58
|
def setup_mediator
|
46
59
|
@mediator = create_mediator(@suite)
|
60
|
+
output_setup_end
|
61
|
+
end
|
62
|
+
|
63
|
+
def output_setup_end
|
47
64
|
suite_name = @suite.to_s
|
48
|
-
|
49
|
-
suite_name = @suite.name
|
50
|
-
end
|
65
|
+
suite_name = @suite.name if @suite.kind_of?(Module)
|
51
66
|
output("Loaded suite #{suite_name}")
|
52
67
|
end
|
53
|
-
|
68
|
+
|
54
69
|
def create_mediator(suite)
|
55
70
|
return TestRunnerMediator.new(suite)
|
56
71
|
end
|
@@ -69,53 +84,106 @@ module Test
|
|
69
84
|
|
70
85
|
def add_fault(fault)
|
71
86
|
@faults << fault
|
72
|
-
output_single(fault.single_character_display,
|
87
|
+
output_single(fault.single_character_display,
|
88
|
+
fault_color(fault),
|
89
|
+
PROGRESS_ONLY)
|
73
90
|
@already_outputted = true
|
74
91
|
end
|
75
92
|
|
76
93
|
def started(result)
|
77
94
|
@result = result
|
95
|
+
output_started
|
96
|
+
end
|
97
|
+
|
98
|
+
def output_started
|
78
99
|
output("Started")
|
79
100
|
end
|
80
|
-
|
101
|
+
|
81
102
|
def finished(elapsed_time)
|
103
|
+
nl if output?(NORMAL) and !output?(VERBOSE)
|
82
104
|
nl
|
83
105
|
output("Finished in #{elapsed_time} seconds.")
|
84
106
|
@faults.each_with_index do |fault, index|
|
85
107
|
nl
|
86
|
-
|
108
|
+
output_single("%3d) " % (index + 1))
|
109
|
+
label, detail = format_fault(fault).split(/\r?\n/, 2)
|
110
|
+
output(label, fault_color(fault))
|
111
|
+
output(detail)
|
87
112
|
end
|
88
113
|
nl
|
89
|
-
output(@result)
|
114
|
+
output(@result, result_color)
|
115
|
+
end
|
116
|
+
|
117
|
+
def format_fault(fault)
|
118
|
+
fault.long_display
|
90
119
|
end
|
91
120
|
|
92
121
|
def test_started(name)
|
93
|
-
output_single(name + ": ", VERBOSE)
|
122
|
+
output_single(name + ": ", nil, VERBOSE)
|
94
123
|
end
|
95
124
|
|
96
125
|
def test_finished(name)
|
97
|
-
|
126
|
+
unless @already_outputted
|
127
|
+
output_single(".", @color_scheme["success"], PROGRESS_ONLY)
|
128
|
+
end
|
98
129
|
nl(VERBOSE)
|
99
130
|
@already_outputted = false
|
100
131
|
end
|
101
132
|
|
102
133
|
def nl(level=NORMAL)
|
103
|
-
output("", level)
|
134
|
+
output("", nil, level)
|
104
135
|
end
|
105
136
|
|
106
|
-
def output(something, level=NORMAL)
|
107
|
-
|
108
|
-
|
137
|
+
def output(something, color=nil, level=NORMAL)
|
138
|
+
return unless output?(level)
|
139
|
+
output_single(something, color, level)
|
140
|
+
@output.puts
|
109
141
|
end
|
110
142
|
|
111
|
-
def output_single(something, level=NORMAL)
|
112
|
-
|
113
|
-
@
|
143
|
+
def output_single(something, color=nil, level=NORMAL)
|
144
|
+
return unless output?(level)
|
145
|
+
if @use_color and color
|
146
|
+
something = "%s%s%s" % [color.escape_sequence,
|
147
|
+
something,
|
148
|
+
@reset_color.escape_sequence]
|
149
|
+
end
|
150
|
+
@output.write(something)
|
151
|
+
@output.flush
|
114
152
|
end
|
115
153
|
|
116
154
|
def output?(level)
|
117
155
|
level <= @output_level
|
118
156
|
end
|
157
|
+
|
158
|
+
def fault_color(fault)
|
159
|
+
@color_scheme[fault.class.name.split(/::/).last.downcase]
|
160
|
+
end
|
161
|
+
|
162
|
+
def result_color
|
163
|
+
if @result.passed?
|
164
|
+
if @result.pending_count > 0
|
165
|
+
@color_scheme["pending"]
|
166
|
+
elsif @result.omission_count > 0
|
167
|
+
@color_scheme["omission"]
|
168
|
+
elsif @result.notification_count > 0
|
169
|
+
@color_scheme["notification"]
|
170
|
+
else
|
171
|
+
@color_scheme["success"]
|
172
|
+
end
|
173
|
+
elsif @result.error_count > 0
|
174
|
+
@color_scheme["error"]
|
175
|
+
elsif @result.failure_count > 0
|
176
|
+
@color_scheme["failure"]
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def guess_color_availability
|
181
|
+
return false unless @output.tty?
|
182
|
+
term = ENV["TERM"]
|
183
|
+
return true if term and (/term\z/ =~ term or term == "screen")
|
184
|
+
return true if ENV["EMACS"] == "t"
|
185
|
+
false
|
186
|
+
end
|
119
187
|
end
|
120
188
|
end
|
121
189
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'test/unit/ui/console/testrunner'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Unit
|
5
|
+
module UI
|
6
|
+
module Emacs
|
7
|
+
class TestRunner < Console::TestRunner
|
8
|
+
private
|
9
|
+
def output_setup_end
|
10
|
+
end
|
11
|
+
|
12
|
+
def output_started
|
13
|
+
end
|
14
|
+
|
15
|
+
def format_fault(fault)
|
16
|
+
return super unless fault.respond_to?(:label)
|
17
|
+
format_method_name = "format_fault_#{fault.label.downcase}"
|
18
|
+
if respond_to?(format_method_name, true)
|
19
|
+
send(format_method_name, fault)
|
20
|
+
else
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def format_fault_failure(failure)
|
26
|
+
if failure.location.size == 1
|
27
|
+
location = failure.location[0]
|
28
|
+
location_display = location.sub(/\A(.+:\d+).*/, ' [\\1]')
|
29
|
+
else
|
30
|
+
location_display = "\n" + failure.location.join("\n")
|
31
|
+
end
|
32
|
+
result = "#{failure.label}:\n"
|
33
|
+
result << "#{failure.test_name}#{location_display}:\n"
|
34
|
+
result << failure.message
|
35
|
+
result
|
36
|
+
end
|
37
|
+
|
38
|
+
def format_fault_error(error)
|
39
|
+
result = "#{error.label}:\n"
|
40
|
+
result << "#{error.test_name}:\n"
|
41
|
+
result << "#{error.message}\n"
|
42
|
+
result << error.backtrace.join("\n")
|
43
|
+
result
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'test/unit/ui/testrunnerutilities'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Unit
|
5
|
+
module UI
|
6
|
+
class TestRunner
|
7
|
+
extend TestRunnerUtilities
|
8
|
+
|
9
|
+
def initialize(suite, options={})
|
10
|
+
if suite.respond_to?(:suite)
|
11
|
+
@suite = suite.suite
|
12
|
+
else
|
13
|
+
@suite = suite
|
14
|
+
end
|
15
|
+
@options = options
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -31,28 +31,31 @@ module Test
|
|
31
31
|
# with.
|
32
32
|
def run_suite
|
33
33
|
Unit.run = true
|
34
|
-
|
35
|
-
notify_listeners(RESET, @suite.size)
|
34
|
+
|
36
35
|
result = create_result
|
37
|
-
|
38
|
-
|
39
|
-
notify_listeners(TestResult::CHANGED, updated_result)
|
36
|
+
result_listener = result.add_listener(TestResult::CHANGED) do |*args|
|
37
|
+
notify_listeners(TestResult::CHANGED, *args)
|
40
38
|
end
|
41
|
-
|
42
|
-
|
43
|
-
notify_listeners(TestResult::FAULT, fault)
|
39
|
+
fault_listener = result.add_listener(TestResult::FAULT) do |*args|
|
40
|
+
notify_listeners(TestResult::FAULT, *args)
|
44
41
|
end
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
|
43
|
+
start_time = Time.now
|
44
|
+
begin
|
45
|
+
notify_listeners(RESET, @suite.size)
|
46
|
+
notify_listeners(STARTED, result)
|
47
|
+
|
48
|
+
@suite.run(result) do |channel, value|
|
49
|
+
notify_listeners(channel, value)
|
50
|
+
end
|
51
|
+
ensure
|
52
|
+
elapsed_time = Time.now - start_time
|
53
|
+
result.remove_listener(TestResult::FAULT, fault_listener)
|
54
|
+
result.remove_listener(TestResult::CHANGED, result_listener)
|
55
|
+
notify_listeners(FINISHED, elapsed_time)
|
48
56
|
end
|
49
|
-
|
50
|
-
result
|
51
|
-
result.remove_listener(TestResult::CHANGED, result_listener)
|
52
|
-
end_time = Time.now
|
53
|
-
elapsed_time = end_time - begin_time
|
54
|
-
notify_listeners(FINISHED, elapsed_time) #"Finished in #{elapsed_time} seconds.")
|
55
|
-
return result
|
57
|
+
|
58
|
+
result
|
56
59
|
end
|
57
60
|
|
58
61
|
private
|
@@ -60,7 +63,13 @@ module Test
|
|
60
63
|
# should run with. Can be overridden by subclasses if
|
61
64
|
# one wants to use a different result.
|
62
65
|
def create_result
|
63
|
-
|
66
|
+
TestResult.new
|
67
|
+
end
|
68
|
+
|
69
|
+
def measure_time
|
70
|
+
begin_time = Time.now
|
71
|
+
yield
|
72
|
+
Time.now - begin_time
|
64
73
|
end
|
65
74
|
end
|
66
75
|
end
|
@@ -8,11 +8,6 @@ module Test
|
|
8
8
|
module Unit
|
9
9
|
module UI
|
10
10
|
|
11
|
-
SILENT = 0
|
12
|
-
PROGRESS_ONLY = 1
|
13
|
-
NORMAL = 2
|
14
|
-
VERBOSE = 3
|
15
|
-
|
16
11
|
# Provides some utilities common to most, if not all,
|
17
12
|
# TestRunners.
|
18
13
|
#
|
@@ -25,8 +20,8 @@ module Test
|
|
25
20
|
module TestRunnerUtilities
|
26
21
|
|
27
22
|
# Creates a new TestRunner and runs the suite.
|
28
|
-
def run(suite,
|
29
|
-
return new(suite,
|
23
|
+
def run(suite, options={})
|
24
|
+
return new(suite, options).start
|
30
25
|
end
|
31
26
|
|
32
27
|
# Takes care of the ARGV parsing and suite
|
@@ -5,7 +5,8 @@ module Test
|
|
5
5
|
TESTUNIT_FILE_SEPARATORS = %r{[\\/:]}
|
6
6
|
TESTUNIT_PREFIX = __FILE__.split(TESTUNIT_FILE_SEPARATORS)[0..-3]
|
7
7
|
TESTUNIT_RB_FILE = /\.rb\Z/
|
8
|
-
|
8
|
+
|
9
|
+
module_function
|
9
10
|
def filter_backtrace(backtrace, prefix=nil)
|
10
11
|
return ["No backtrace"] unless(backtrace)
|
11
12
|
split_p = if(prefix)
|