test-unit 2.3.0 → 2.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +9 -1
- data/{README.txt → README.textile} +24 -17
- data/Rakefile +301 -27
- data/lib/test/unit/assertions.rb +49 -23
- data/lib/test/unit/attribute.rb +1 -1
- data/lib/test/unit/collector/load.rb +3 -3
- data/lib/test/unit/runner/console.rb +11 -4
- data/lib/test/unit/testcase.rb +1 -1
- data/lib/test/unit/ui/console/outputlevel.rb +3 -2
- data/lib/test/unit/ui/console/testrunner.rb +101 -22
- data/lib/test/unit/version.rb +1 -1
- data/test/test-assertions.rb +20 -0
- data/test/test-data.rb +1 -1
- data/test/test-priority.rb +17 -2
- data/test/test-testcase.rb +3 -3
- metadata +62 -111
- data/History.txt +0 -302
- data/Manifest.txt +0 -118
- data/html/bar.png +0 -0
- data/html/bar.svg +0 -153
- data/html/developer.png +0 -0
- data/html/developer.svg +0 -469
- data/html/famfamfam-logo.png +0 -0
- data/html/favicon.ico +0 -0
- data/html/favicon.png +0 -0
- data/html/favicon.svg +0 -82
- data/html/github-logo.png +0 -0
- data/html/heading-mark.png +0 -0
- data/html/heading-mark.svg +0 -393
- data/html/index.html +0 -291
- data/html/index.html.ja +0 -306
- data/html/install.png +0 -0
- data/html/install.svg +0 -636
- data/html/jp.png +0 -0
- data/html/kinotan-failure.png +0 -0
- data/html/kinotan-pass.png +0 -0
- data/html/logo.png +0 -0
- data/html/logo.svg +0 -483
- data/html/reference.png +0 -0
- data/html/rubyforge.png +0 -0
- data/html/tango-logo.png +0 -0
- data/html/test-unit.css +0 -346
- data/html/tutorial.png +0 -0
- data/html/tutorial.svg +0 -559
- data/html/us.png +0 -0
- data/images/color-diff.png +0 -0
- data/test/fixtures/plus.csv +0 -3
data/lib/test/unit/assertions.rb
CHANGED
@@ -116,7 +116,7 @@ EOT
|
|
116
116
|
failure.inspected_expected = AssertionMessage.convert(expected)
|
117
117
|
failure.inspected_actual = AssertionMessage.convert(actual)
|
118
118
|
failure.user_message = message
|
119
|
-
raise
|
119
|
+
raise failure # For JRuby. :<
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
@@ -1019,7 +1019,7 @@ EOT
|
|
1019
1019
|
expected, actual,
|
1020
1020
|
expected, actual)
|
1021
1021
|
assert_block(full_message) do
|
1022
|
-
expected.
|
1022
|
+
expected.__send__(operator, actual)
|
1023
1023
|
end
|
1024
1024
|
end
|
1025
1025
|
end
|
@@ -1129,7 +1129,7 @@ EOT
|
|
1129
1129
|
def assert_predicate(object, predicate, message=nil)
|
1130
1130
|
_wrap_assertion do
|
1131
1131
|
assert_respond_to(object, predicate, message)
|
1132
|
-
actual = object.
|
1132
|
+
actual = object.__send__(predicate)
|
1133
1133
|
full_message = build_message(message,
|
1134
1134
|
"<?>.? is true value expected but was\n" +
|
1135
1135
|
"<?>",
|
@@ -1151,7 +1151,7 @@ EOT
|
|
1151
1151
|
def assert_not_predicate(object, predicate, message=nil)
|
1152
1152
|
_wrap_assertion do
|
1153
1153
|
assert_respond_to(object, predicate, message)
|
1154
|
-
actual = object.
|
1154
|
+
actual = object.__send__(predicate)
|
1155
1155
|
full_message = build_message(message,
|
1156
1156
|
"<?>.? is false value expected but was\n" +
|
1157
1157
|
"<?>",
|
@@ -1525,8 +1525,20 @@ EOM
|
|
1525
1525
|
end
|
1526
1526
|
|
1527
1527
|
class Inspector
|
1528
|
-
|
1528
|
+
include Comparable
|
1529
|
+
|
1530
|
+
class << self
|
1531
|
+
def cached_new(object, inspected_objects)
|
1532
|
+
inspected_objects[object.object_id] ||=
|
1533
|
+
new(object, inspected_objects)
|
1534
|
+
end
|
1535
|
+
end
|
1536
|
+
|
1537
|
+
attr_reader :object
|
1538
|
+
def initialize(object, inspected_objects={})
|
1539
|
+
@inspected_objects = inspected_objects
|
1529
1540
|
@object = object
|
1541
|
+
@inspected_objects[@object.object_id] = self
|
1530
1542
|
@inspect_target = inspect_target
|
1531
1543
|
end
|
1532
1544
|
|
@@ -1543,12 +1555,20 @@ EOM
|
|
1543
1555
|
@inspect_target.pretty_print_cycle(q)
|
1544
1556
|
end
|
1545
1557
|
|
1558
|
+
def <=>(other)
|
1559
|
+
if other.is_a?(self.class)
|
1560
|
+
@object <=> other.object
|
1561
|
+
else
|
1562
|
+
@object <=> other
|
1563
|
+
end
|
1564
|
+
end
|
1565
|
+
|
1546
1566
|
private
|
1547
1567
|
def inspect_target
|
1548
1568
|
if HashInspector.target?(@object)
|
1549
|
-
HashInspector.new(@object)
|
1569
|
+
HashInspector.new(@object, @inspected_objects)
|
1550
1570
|
elsif ArrayInspector.target?(@object)
|
1551
|
-
ArrayInspector.new(@object)
|
1571
|
+
ArrayInspector.new(@object, @inspected_objects)
|
1552
1572
|
else
|
1553
1573
|
@object
|
1554
1574
|
end
|
@@ -1562,8 +1582,14 @@ EOM
|
|
1562
1582
|
end
|
1563
1583
|
end
|
1564
1584
|
|
1565
|
-
def initialize(hash)
|
1566
|
-
@
|
1585
|
+
def initialize(hash, inspected_objects)
|
1586
|
+
@inspected_objects = inspected_objects
|
1587
|
+
@hash = {}
|
1588
|
+
hash.each do |key, value|
|
1589
|
+
key = Inspector.cached_new(key, @inspected_objects)
|
1590
|
+
value = Inspector.cached_new(value, @inspected_objects)
|
1591
|
+
@hash[key] = value
|
1592
|
+
end
|
1567
1593
|
end
|
1568
1594
|
|
1569
1595
|
def inspect
|
@@ -1596,8 +1622,7 @@ EOM
|
|
1596
1622
|
rescue ArgumentError
|
1597
1623
|
end
|
1598
1624
|
keys.each do |key|
|
1599
|
-
yield(
|
1600
|
-
Inspector.new(@hash[key]))
|
1625
|
+
yield(key, @hash[key])
|
1601
1626
|
end
|
1602
1627
|
end
|
1603
1628
|
end
|
@@ -1609,8 +1634,11 @@ EOM
|
|
1609
1634
|
end
|
1610
1635
|
end
|
1611
1636
|
|
1612
|
-
def initialize(array)
|
1613
|
-
@
|
1637
|
+
def initialize(array, inspected_objects)
|
1638
|
+
@inspected_objects = inspected_objects
|
1639
|
+
@array = array.collect do |element|
|
1640
|
+
Inspector.cached_new(element, @inspected_objects)
|
1641
|
+
end
|
1614
1642
|
end
|
1615
1643
|
|
1616
1644
|
def inspect
|
@@ -1629,10 +1657,8 @@ EOM
|
|
1629
1657
|
@array.pretty_print_cycle(q)
|
1630
1658
|
end
|
1631
1659
|
|
1632
|
-
def each
|
1633
|
-
@array.each
|
1634
|
-
yield(Inspector.new(element))
|
1635
|
-
end
|
1660
|
+
def each(&block)
|
1661
|
+
@array.each(&block)
|
1636
1662
|
end
|
1637
1663
|
end
|
1638
1664
|
|
@@ -1743,7 +1769,7 @@ EOM
|
|
1743
1769
|
end
|
1744
1770
|
|
1745
1771
|
def method_missing(name, *args, &block)
|
1746
|
-
@exception.
|
1772
|
+
@exception.__send__(name, *args, &block)
|
1747
1773
|
end
|
1748
1774
|
|
1749
1775
|
private
|
@@ -1799,10 +1825,10 @@ EOM
|
|
1799
1825
|
elsif exception_type.is_a?(Exception)
|
1800
1826
|
exception_objects << exception_type
|
1801
1827
|
else
|
1802
|
-
@test_case.
|
1803
|
-
|
1804
|
-
|
1805
|
-
|
1828
|
+
@test_case.__send__(:assert,
|
1829
|
+
Exception >= exception_type,
|
1830
|
+
"Should expect a class of exception, " +
|
1831
|
+
"#{exception_type}")
|
1806
1832
|
exception_classes << exception_type
|
1807
1833
|
end
|
1808
1834
|
end
|
@@ -1811,7 +1837,7 @@ EOM
|
|
1811
1837
|
|
1812
1838
|
def expected_class?(actual_exception, equality)
|
1813
1839
|
@expected_classes.any? do |expected_class|
|
1814
|
-
actual_exception.
|
1840
|
+
actual_exception.__send__(equality, expected_class)
|
1815
1841
|
end
|
1816
1842
|
end
|
1817
1843
|
|
data/lib/test/unit/attribute.rb
CHANGED
@@ -36,7 +36,7 @@ module Test
|
|
36
36
|
return unless defined?(@current_attributes)
|
37
37
|
|
38
38
|
attributes = {}
|
39
|
-
kept_attributes =
|
39
|
+
kept_attributes = StringifyKeyHash.new
|
40
40
|
@current_attributes.each do |attribute_name, attribute|
|
41
41
|
attributes[attribute_name] = attribute[:value]
|
42
42
|
kept_attributes[attribute_name] = attribute if attribute[:keep]
|
@@ -102,7 +102,7 @@ module Test
|
|
102
102
|
return if @program_file == expanded_path.to_s
|
103
103
|
add_load_path(expanded_path.dirname) do
|
104
104
|
begin
|
105
|
-
require(path.to_s)
|
105
|
+
require(path.basename.to_s)
|
106
106
|
rescue LoadError
|
107
107
|
@require_failed_infos << {:path => expanded_path, :exception => $!}
|
108
108
|
end
|
@@ -121,10 +121,10 @@ module Test
|
|
121
121
|
end
|
122
122
|
|
123
123
|
def add_load_path(path)
|
124
|
-
$LOAD_PATH.
|
124
|
+
$LOAD_PATH.unshift(path.to_s) if path
|
125
125
|
yield
|
126
126
|
ensure
|
127
|
-
$LOAD_PATH.delete_at($LOAD_PATH.
|
127
|
+
$LOAD_PATH.delete_at($LOAD_PATH.index(path.to_s)) if path
|
128
128
|
end
|
129
129
|
|
130
130
|
def excluded_directory?(base)
|
@@ -9,10 +9,11 @@ module Test
|
|
9
9
|
require 'test/unit/ui/console/outputlevel'
|
10
10
|
|
11
11
|
output_levels = [
|
12
|
-
[
|
13
|
-
[
|
14
|
-
[
|
15
|
-
[
|
12
|
+
["silent", UI::Console::OutputLevel::SILENT],
|
13
|
+
["progress", UI::Console::OutputLevel::PROGRESS_ONLY],
|
14
|
+
["important-only", UI::Console::OutputLevel::IMPORTANT_FAULTS_ONLY],
|
15
|
+
["normal", UI::Console::OutputLevel::NORMAL],
|
16
|
+
["verbose", UI::Console::OutputLevel::VERBOSE],
|
16
17
|
]
|
17
18
|
opts.on('-v', '--verbose=[LEVEL]', output_levels,
|
18
19
|
"Set the output level (default is verbose).",
|
@@ -47,6 +48,12 @@ module Test
|
|
47
48
|
"(default is auto)") do |max|
|
48
49
|
auto_runner.runner_options[:progress_row_max] = max
|
49
50
|
end
|
51
|
+
|
52
|
+
opts.on("--[no-]show-detail-immediately",
|
53
|
+
"Shows not passed test details immediately.",
|
54
|
+
"(default is no)") do |boolean|
|
55
|
+
auto_runner.runner_options[:show_detail_immediately] = boolean
|
56
|
+
end
|
50
57
|
end
|
51
58
|
end
|
52
59
|
end
|
data/lib/test/unit/testcase.rb
CHANGED
@@ -257,7 +257,7 @@ module Test
|
|
257
257
|
message = "wrong number of arguments (#{n_arguments} for 1)"
|
258
258
|
raise ArgumentError, message
|
259
259
|
end
|
260
|
-
method_name = test_description
|
260
|
+
method_name = "test: #{test_description}"
|
261
261
|
define_method(method_name, &block)
|
262
262
|
description(test_description, method_name)
|
263
263
|
attribute(:test, true, {}, method_name)
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# Author:: Nathaniel Talbott.
|
4
4
|
# Copyright::
|
5
5
|
# * Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
|
6
|
-
# * Copyright (c) 2008-
|
6
|
+
# * Copyright (c) 2008-2011 Kouhei Sutou <kou@clear-code.com>
|
7
7
|
# License:: Ruby license.
|
8
8
|
|
9
9
|
require 'test/unit/color-scheme'
|
@@ -37,13 +37,22 @@ module Test
|
|
37
37
|
@progress_row = 0
|
38
38
|
@progress_row_max = @options[:progress_row_max]
|
39
39
|
@progress_row_max ||= guess_progress_row_max
|
40
|
+
@show_detail_immediately = @options[:show_detail_immediately]
|
40
41
|
@already_outputted = false
|
41
42
|
@indent = 0
|
42
43
|
@top_level = true
|
44
|
+
@current_output_level = NORMAL
|
43
45
|
@faults = []
|
44
46
|
end
|
45
47
|
|
46
48
|
private
|
49
|
+
def change_output_level(level)
|
50
|
+
old_output_level = @current_output_level
|
51
|
+
@current_output_level = level
|
52
|
+
yield
|
53
|
+
@current_output_level = old_output_level
|
54
|
+
end
|
55
|
+
|
47
56
|
def setup_mediator
|
48
57
|
super
|
49
58
|
output_setup_end
|
@@ -75,6 +84,7 @@ module Test
|
|
75
84
|
def add_fault(fault)
|
76
85
|
@faults << fault
|
77
86
|
output_progress(fault.single_character_display, fault_color(fault))
|
87
|
+
output_progress_in_detail(fault) if @show_detail_immediately
|
78
88
|
@already_outputted = true if fault.critical?
|
79
89
|
end
|
80
90
|
|
@@ -89,24 +99,66 @@ module Test
|
|
89
99
|
|
90
100
|
def finished(elapsed_time)
|
91
101
|
nl if output?(NORMAL) and !output?(VERBOSE)
|
92
|
-
|
102
|
+
output_faults unless @show_detail_immediately
|
103
|
+
nl(IMPORTANT_FAULTS_ONLY)
|
104
|
+
change_output_level(IMPORTANT_FAULTS_ONLY) do
|
105
|
+
output_statistics(elapsed_time)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def output_faults
|
110
|
+
categorized_faults = categorize_faults
|
111
|
+
change_output_level(IMPORTANT_FAULTS_ONLY) do
|
112
|
+
output_faults_in_detail(categorized_faults[:need_detail_faults])
|
113
|
+
end
|
114
|
+
output_faults_in_short("Omissions", Omission,
|
115
|
+
categorized_faults[:omissions])
|
116
|
+
output_faults_in_short("Notifications", Notification,
|
117
|
+
categorized_faults[:notifications])
|
118
|
+
end
|
119
|
+
|
120
|
+
def max_digit(max_number)
|
121
|
+
(Math.log10(max_number) + 1).truncate
|
122
|
+
end
|
123
|
+
|
124
|
+
def output_faults_in_detail(faults)
|
125
|
+
return if faults.nil?
|
126
|
+
digit = max_digit(faults.size)
|
127
|
+
faults.each_with_index do |fault, index|
|
93
128
|
nl
|
94
|
-
output_single("
|
129
|
+
output_single("%#{digit}d) " % (index + 1))
|
95
130
|
output_fault(fault)
|
96
131
|
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def output_faults_in_short(label, fault_class, faults)
|
135
|
+
return if faults.nil?
|
136
|
+
digit = max_digit(faults.size)
|
97
137
|
nl
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
138
|
+
output_single(label, fault_class_color(fault_class))
|
139
|
+
output(":")
|
140
|
+
faults.each_with_index do |fault, index|
|
141
|
+
output_single("%#{digit}d) " % (index + 1))
|
142
|
+
output_single(fault.message, fault_color(fault))
|
143
|
+
output(" [#{fault.test_name}]")
|
144
|
+
output(fault.location.first)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def categorize_faults
|
149
|
+
@faults.group_by do |fault|
|
150
|
+
categorize_fault(fault)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def categorize_fault(fault)
|
155
|
+
case fault
|
156
|
+
when Omission
|
157
|
+
:omissions
|
158
|
+
when Notification
|
159
|
+
:notifications
|
160
|
+
else
|
161
|
+
:need_detail_faults
|
110
162
|
end
|
111
163
|
end
|
112
164
|
|
@@ -198,6 +250,23 @@ module Test
|
|
198
250
|
fault.long_display
|
199
251
|
end
|
200
252
|
|
253
|
+
def output_statistics(elapsed_time)
|
254
|
+
output("Finished in #{elapsed_time} seconds.")
|
255
|
+
nl
|
256
|
+
output(@result, result_color)
|
257
|
+
output("%g%% passed" % @result.pass_percentage, result_color)
|
258
|
+
unless elapsed_time.zero?
|
259
|
+
nl
|
260
|
+
test_throughput = @result.run_count / elapsed_time
|
261
|
+
assertion_throughput = @result.assertion_count / elapsed_time
|
262
|
+
throughput = [
|
263
|
+
"%.2f tests/s" % test_throughput,
|
264
|
+
"%.2f assertions/s" % assertion_throughput,
|
265
|
+
]
|
266
|
+
output(throughput.join(", "))
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
201
270
|
def test_started(test)
|
202
271
|
return unless output?(VERBOSE)
|
203
272
|
|
@@ -250,17 +319,17 @@ module Test
|
|
250
319
|
end
|
251
320
|
end
|
252
321
|
|
253
|
-
def nl(level=
|
322
|
+
def nl(level=nil)
|
254
323
|
output("", nil, level)
|
255
324
|
end
|
256
|
-
|
257
|
-
def output(something, color=nil, level=
|
325
|
+
|
326
|
+
def output(something, color=nil, level=nil)
|
258
327
|
return unless output?(level)
|
259
328
|
output_single(something, color, level)
|
260
329
|
@output.puts
|
261
330
|
end
|
262
|
-
|
263
|
-
def output_single(something, color=nil, level=
|
331
|
+
|
332
|
+
def output_single(something, color=nil, level=nil)
|
264
333
|
return false unless output?(level)
|
265
334
|
if @use_color and color
|
266
335
|
something = "%s%s%s" % [color.escape_sequence,
|
@@ -283,8 +352,14 @@ module Test
|
|
283
352
|
end
|
284
353
|
end
|
285
354
|
|
355
|
+
def output_progress_in_detail(fault)
|
356
|
+
return if @output_level == SILENT
|
357
|
+
return unless categorize_fault(fault) == :need_detail_faults
|
358
|
+
output_fault(fault)
|
359
|
+
end
|
360
|
+
|
286
361
|
def output?(level)
|
287
|
-
level <= @output_level
|
362
|
+
(level || @current_output_level) <= @output_level
|
288
363
|
end
|
289
364
|
|
290
365
|
def color(name)
|
@@ -295,7 +370,11 @@ module Test
|
|
295
370
|
end
|
296
371
|
|
297
372
|
def fault_color(fault)
|
298
|
-
|
373
|
+
fault_class_color(fault.class)
|
374
|
+
end
|
375
|
+
|
376
|
+
def fault_class_color(fault_class)
|
377
|
+
color(fault_class.name.split(/::/).last.downcase)
|
299
378
|
end
|
300
379
|
|
301
380
|
def result_color
|