test-unit 2.3.0 → 2.3.1
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/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
|