test-unit 3.2.0 → 3.3.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/COPYING +4 -1
- data/README.md +11 -11
- data/Rakefile +10 -1
- data/doc/text/getting-started.md +246 -0
- data/doc/text/news.md +372 -1
- data/lib/test/unit.rb +171 -157
- data/lib/test/unit/assertions.rb +187 -149
- data/lib/test/unit/attribute.rb +71 -2
- data/lib/test/unit/autorunner.rb +65 -32
- data/lib/test/unit/code-snippet-fetcher.rb +7 -7
- data/lib/test/unit/collector/load.rb +8 -13
- data/lib/test/unit/data-sets.rb +116 -0
- data/lib/test/unit/data.rb +121 -12
- data/lib/test/unit/diff.rb +11 -11
- data/lib/test/unit/fixture.rb +3 -0
- data/lib/test/unit/notification.rb +9 -7
- data/lib/test/unit/omission.rb +34 -31
- data/lib/test/unit/pending.rb +12 -11
- data/lib/test/unit/priority.rb +7 -3
- data/lib/test/unit/runner/console.rb +25 -0
- data/lib/test/unit/test-suite-creator.rb +22 -8
- data/lib/test/unit/testcase.rb +270 -182
- data/lib/test/unit/ui/console/testrunner.rb +90 -35
- data/lib/test/unit/ui/emacs/testrunner.rb +5 -5
- data/lib/test/unit/util/observable.rb +2 -2
- data/lib/test/unit/util/output.rb +5 -4
- data/lib/test/unit/util/procwrapper.rb +4 -4
- data/lib/test/unit/version.rb +1 -1
- data/test/collector/test-descendant.rb +4 -0
- data/test/collector/test-load.rb +35 -2
- data/test/collector/test_dir.rb +5 -4
- data/test/collector/test_objectspace.rb +7 -5
- data/test/test-assertions.rb +128 -101
- data/test/test-code-snippet.rb +42 -0
- data/test/test-data.rb +195 -79
- data/test/test-priority.rb +19 -8
- data/test/test-test-case.rb +111 -3
- data/test/test-test-suite.rb +1 -0
- data/test/testunit-test-util.rb +2 -0
- metadata +38 -37
data/lib/test/unit/data.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "test/unit/data-sets"
|
2
|
+
|
1
3
|
module Test
|
2
4
|
module Unit
|
3
5
|
module Data
|
@@ -12,9 +14,12 @@ module Test
|
|
12
14
|
#
|
13
15
|
# Define test data in the test code.
|
14
16
|
#
|
15
|
-
# @overload data(label, data)
|
17
|
+
# @overload data(label, data, options={})
|
16
18
|
# @param [String] label specify test case name.
|
17
19
|
# @param data specify test data.
|
20
|
+
# @param [Hash] options specify options.
|
21
|
+
# @option options [Boolean] :keep whether or not to use
|
22
|
+
# this data in the following test methods
|
18
23
|
#
|
19
24
|
# @example data(label, data)
|
20
25
|
# data("empty string", [true, ""])
|
@@ -24,9 +29,39 @@ module Test
|
|
24
29
|
# assert_equal(expected, target.empty?)
|
25
30
|
# end
|
26
31
|
#
|
27
|
-
# @overload data(
|
32
|
+
# @overload data(variable, patterns, options={})
|
33
|
+
# @param [Symbol] variable specify test pattern variable name.
|
34
|
+
# @param [Array] patterns specify test patterns for the variable.
|
35
|
+
# @param [Hash] options specify options.
|
36
|
+
# @option options [Boolean] :keep whether or not to use
|
37
|
+
# this data in the following test methods
|
38
|
+
# @option options [Object] :group the test pattern group.
|
39
|
+
# Test matrix is generated for each test pattern group separately.
|
40
|
+
#
|
41
|
+
# @example data(variable, patterns)
|
42
|
+
# data(:x, [1, 2, 3])
|
43
|
+
# data(:y, ["a", "b"])
|
44
|
+
# def test_patterns(data)
|
45
|
+
# # 3 * 2 times executed
|
46
|
+
# # 3: the number of patterns of :x
|
47
|
+
# # 2: the number of patterns of :y
|
48
|
+
# p data
|
49
|
+
# # => {:x => 1, :y => "a"}
|
50
|
+
# # => {:x => 1, :y => "b"}
|
51
|
+
# # => {:x => 2, :y => "a"}
|
52
|
+
# # => {:x => 2, :y => "b"}
|
53
|
+
# # => {:x => 3, :y => "a"}
|
54
|
+
# # => {:x => 3, :y => "b"}
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# Generates test matrix from variable and patterns pairs.
|
58
|
+
#
|
59
|
+
# @overload data(data_set, options={})
|
28
60
|
# @param [Hash] data_set specify test data as a Hash that
|
29
61
|
# key is test label and value is test data.
|
62
|
+
# @param [Hash] options specify options.
|
63
|
+
# @option options [Boolean] :keep whether or not to use
|
64
|
+
# this data in the following test methods
|
30
65
|
#
|
31
66
|
# @example data(data_set)
|
32
67
|
# data("empty string" => [true, ""],
|
@@ -36,9 +71,12 @@ module Test
|
|
36
71
|
# assert_equal(expected, target.empty?)
|
37
72
|
# end
|
38
73
|
#
|
39
|
-
# @overload data(&block)
|
40
|
-
# @
|
41
|
-
#
|
74
|
+
# @overload data(options={}, &block)
|
75
|
+
# @param [Hash] options specify options.
|
76
|
+
# @option options [Boolean] :keep whether or not to use
|
77
|
+
# this data in the following test methods
|
78
|
+
# @yieldreturn [Hash<String, Object>] return test data set
|
79
|
+
# as a Hash that key is test label and value is test data.
|
42
80
|
#
|
43
81
|
# @example data(&block)
|
44
82
|
# data do
|
@@ -52,22 +90,93 @@ module Test
|
|
52
90
|
# assert_equal(expected, target.empty?)
|
53
91
|
# end
|
54
92
|
#
|
93
|
+
# @overload data(options={}, &block)
|
94
|
+
# @param [Hash] options specify options.
|
95
|
+
# @option options [Boolean] :keep whether or not to use
|
96
|
+
# this data in the following test methods
|
97
|
+
# @yieldreturn [Array<Symbol, Array>] return test data set
|
98
|
+
# as an Array of variable and patterns.
|
99
|
+
#
|
100
|
+
# @example data(&block)
|
101
|
+
# data do
|
102
|
+
# patterns = 3.times.to_a
|
103
|
+
# [:x, patterns]
|
104
|
+
# end
|
105
|
+
# data do
|
106
|
+
# patterns = []
|
107
|
+
# character = "a"
|
108
|
+
# 2.times.each do
|
109
|
+
# patterns << character
|
110
|
+
# character = character.succ
|
111
|
+
# end
|
112
|
+
# [:y, patterns]
|
113
|
+
# end
|
114
|
+
# def test_patterns(data)
|
115
|
+
# # 3 * 2 times executed
|
116
|
+
# # 3: the number of patterns of :x
|
117
|
+
# # 2: the number of patterns of :y
|
118
|
+
# p data
|
119
|
+
# # => {:x => 0, :y => "a"}
|
120
|
+
# # => {:x => 0, :y => "b"}
|
121
|
+
# # => {:x => 1, :y => "a"}
|
122
|
+
# # => {:x => 1, :y => "b"}
|
123
|
+
# # => {:x => 2, :y => "a"}
|
124
|
+
# # => {:x => 2, :y => "b"}
|
125
|
+
# end
|
126
|
+
#
|
127
|
+
# Generates test matrix from variable and patterns pairs.
|
128
|
+
#
|
55
129
|
def data(*arguments, &block)
|
130
|
+
options = nil
|
56
131
|
n_arguments = arguments.size
|
57
132
|
case n_arguments
|
58
133
|
when 0
|
59
134
|
raise ArgumentError, "no block is given" unless block_given?
|
60
135
|
data_set = block
|
61
136
|
when 1
|
62
|
-
|
137
|
+
if block_given?
|
138
|
+
data_set = block
|
139
|
+
options = arguments[1]
|
140
|
+
else
|
141
|
+
data_set = arguments[0]
|
142
|
+
end
|
63
143
|
when 2
|
64
|
-
|
144
|
+
case arguments[0]
|
145
|
+
when String
|
146
|
+
data_set = {arguments[0] => arguments[1]}
|
147
|
+
when Hash
|
148
|
+
data_set = arguments[0]
|
149
|
+
options = arguments[1]
|
150
|
+
else
|
151
|
+
variable = arguments[0]
|
152
|
+
patterns = arguments[1]
|
153
|
+
data_set = [variable, patterns]
|
154
|
+
end
|
155
|
+
when 3
|
156
|
+
case arguments[0]
|
157
|
+
when String
|
158
|
+
data_set = {arguments[0] => arguments[1]}
|
159
|
+
options = arguments[2]
|
160
|
+
else
|
161
|
+
variable = arguments[0]
|
162
|
+
patterns = arguments[1]
|
163
|
+
data_set = [variable, patterns]
|
164
|
+
options = arguments[2]
|
165
|
+
end
|
65
166
|
else
|
66
|
-
message = "wrong number arguments(#{n_arguments} for
|
167
|
+
message = "wrong number arguments(#{n_arguments} for 0..3)"
|
67
168
|
raise ArgumentError, message
|
68
169
|
end
|
69
|
-
|
70
|
-
|
170
|
+
options ||= {}
|
171
|
+
data_sets = current_attribute(:data)[:value] || DataSets.new
|
172
|
+
data_sets.add(data_set, options)
|
173
|
+
if options[:keep]
|
174
|
+
keep_hook = lambda do |attr|
|
175
|
+
attr.merge(value: attr[:value].keep)
|
176
|
+
end
|
177
|
+
options = options.merge(keep_hook: keep_hook)
|
178
|
+
end
|
179
|
+
attribute(:data, data_sets, options)
|
71
180
|
end
|
72
181
|
|
73
182
|
# This method provides Data-Driven-Test functionality.
|
@@ -78,7 +187,7 @@ module Test
|
|
78
187
|
#
|
79
188
|
# @param [String] file_name full path to test data file.
|
80
189
|
# File format is automatically detected from filename extension.
|
81
|
-
# @raise [ArgumentError] if
|
190
|
+
# @raise [ArgumentError] if `file_name` is not supported file format.
|
82
191
|
# @see Loader#load
|
83
192
|
#
|
84
193
|
# @example Load data from CSV file
|
@@ -102,7 +211,7 @@ module Test
|
|
102
211
|
#
|
103
212
|
# @param [String] file_name full path to test data file.
|
104
213
|
# File format is automatically detected from filename extension.
|
105
|
-
# @raise [ArgumentError] if
|
214
|
+
# @raise [ArgumentError] if `file_name` is not supported file format.
|
106
215
|
# @see #load_csv
|
107
216
|
# @see #load_tsv
|
108
217
|
# @api private
|
data/lib/test/unit/diff.rb
CHANGED
@@ -3,9 +3,9 @@
|
|
3
3
|
# Copyright (c) 2001-2008 Python Software Foundation; All Rights Reserved
|
4
4
|
# Copyright (c) 2008-2011 Kouhei Sutou; All Rights Reserved
|
5
5
|
#
|
6
|
-
# It is free software, and is distributed under the Ruby
|
7
|
-
# license and/or
|
8
|
-
#
|
6
|
+
# It is free software, and is distributed under the Ruby license, the
|
7
|
+
# PSF license and/or LGPLv2.1 or later. See the COPYING file, the PSFL
|
8
|
+
# file and the LGPL file.
|
9
9
|
|
10
10
|
module Test
|
11
11
|
module Unit
|
@@ -269,7 +269,7 @@ module Test
|
|
269
269
|
|
270
270
|
private
|
271
271
|
def tag(mark, contents)
|
272
|
-
contents.collect {|content|
|
272
|
+
contents.collect {|content| mark + content}
|
273
273
|
end
|
274
274
|
end
|
275
275
|
|
@@ -450,7 +450,7 @@ module Test
|
|
450
450
|
|
451
451
|
def tag(mark, contents)
|
452
452
|
contents.each do |content|
|
453
|
-
@result <<
|
453
|
+
@result << (mark + content)
|
454
454
|
end
|
455
455
|
end
|
456
456
|
|
@@ -577,15 +577,15 @@ module Test
|
|
577
577
|
to_width = compute_width(to_line, to_start, to_end)
|
578
578
|
case tag
|
579
579
|
when :replace
|
580
|
-
from_tags
|
581
|
-
to_tags
|
580
|
+
from_tags += "^" * from_width
|
581
|
+
to_tags += "^" * to_width
|
582
582
|
when :delete
|
583
|
-
from_tags
|
583
|
+
from_tags += "-" * from_width
|
584
584
|
when :insert
|
585
|
-
to_tags
|
585
|
+
to_tags += "+" * to_width
|
586
586
|
when :equal
|
587
|
-
from_tags
|
588
|
-
to_tags
|
587
|
+
from_tags += " " * from_width
|
588
|
+
to_tags += " " * to_width
|
589
589
|
else
|
590
590
|
raise "unknown tag: #{tag}"
|
591
591
|
end
|
data/lib/test/unit/fixture.rb
CHANGED
@@ -127,6 +127,9 @@ module Test
|
|
127
127
|
if method_name_or_callback.respond_to?(:call)
|
128
128
|
callback = method_name_or_callback
|
129
129
|
method_name = callback_method_name(callback)
|
130
|
+
@test_case.attribute(:source_location,
|
131
|
+
callback.source_location,
|
132
|
+
method_name)
|
130
133
|
@test_case.__send__(:define_method, method_name, &callback)
|
131
134
|
else
|
132
135
|
method_name = method_name_or_callback
|
@@ -65,15 +65,17 @@ module Test
|
|
65
65
|
# Notify some information.
|
66
66
|
#
|
67
67
|
# Example:
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
68
|
+
#
|
69
|
+
# def test_notification
|
70
|
+
# notify("I'm here!")
|
71
|
+
# # Reached here
|
72
|
+
# notify("Special!") if special_case?
|
73
|
+
# # Reached here too
|
74
|
+
# end
|
74
75
|
#
|
75
76
|
# options:
|
76
|
-
#
|
77
|
+
#
|
78
|
+
# :backtrace override backtrace.
|
77
79
|
def notify(message, options={}, &block)
|
78
80
|
backtrace = filter_backtrace(options[:backtrace] || caller)
|
79
81
|
notification = Notification.new(name, backtrace, message,
|
data/lib/test/unit/omission.rb
CHANGED
@@ -65,17 +65,18 @@ module Test
|
|
65
65
|
# Omit the test or part of the test.
|
66
66
|
#
|
67
67
|
# Example:
|
68
|
-
# def test_omission
|
69
|
-
# omit
|
70
|
-
# # Not reached here
|
71
|
-
# end
|
72
68
|
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
# # Not
|
69
|
+
# def test_omission
|
70
|
+
# omit
|
71
|
+
# # Not reached here
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# def test_omission_with_here
|
75
|
+
# omit do
|
76
|
+
# # Not ran here
|
77
|
+
# end
|
78
|
+
# # Reached here
|
76
79
|
# end
|
77
|
-
# # Reached here
|
78
|
-
# end
|
79
80
|
def omit(message=nil, &block)
|
80
81
|
message ||= "omitted."
|
81
82
|
if block_given?
|
@@ -91,20 +92,21 @@ module Test
|
|
91
92
|
# true.
|
92
93
|
#
|
93
94
|
# Example:
|
94
|
-
# def test_omission
|
95
|
-
# omit_if("".empty?)
|
96
|
-
# # Not reached here
|
97
|
-
# end
|
98
95
|
#
|
99
|
-
#
|
100
|
-
#
|
101
|
-
# # Not
|
96
|
+
# def test_omission
|
97
|
+
# omit_if("".empty?)
|
98
|
+
# # Not reached here
|
102
99
|
# end
|
103
|
-
#
|
104
|
-
#
|
100
|
+
#
|
101
|
+
# def test_omission_with_here
|
102
|
+
# omit_if(true) do
|
103
|
+
# # Not ran here
|
104
|
+
# end
|
105
|
+
# omit_if(false) do
|
106
|
+
# # Reached here
|
107
|
+
# end
|
108
|
+
# # Reached here too
|
105
109
|
# end
|
106
|
-
# # Reached here too
|
107
|
-
# end
|
108
110
|
def omit_if(condition, *args, &block)
|
109
111
|
if condition
|
110
112
|
omit(*args, &block)
|
@@ -117,20 +119,21 @@ module Test
|
|
117
119
|
# not true.
|
118
120
|
#
|
119
121
|
# Example:
|
120
|
-
# def test_omission
|
121
|
-
# omit_unless("string".empty?)
|
122
|
-
# # Not reached here
|
123
|
-
# end
|
124
122
|
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
# #
|
123
|
+
# def test_omission
|
124
|
+
# omit_unless("string".empty?)
|
125
|
+
# # Not reached here
|
128
126
|
# end
|
129
|
-
#
|
130
|
-
#
|
127
|
+
#
|
128
|
+
# def test_omission_with_here
|
129
|
+
# omit_unless(true) do
|
130
|
+
# # Reached here
|
131
|
+
# end
|
132
|
+
# omit_unless(false) do
|
133
|
+
# # Not ran here
|
134
|
+
# end
|
135
|
+
# # Reached here too
|
131
136
|
# end
|
132
|
-
# # Reached here too
|
133
|
-
# end
|
134
137
|
def omit_unless(condition, *args, &block)
|
135
138
|
if condition
|
136
139
|
block.call if block
|
data/lib/test/unit/pending.rb
CHANGED
@@ -65,19 +65,20 @@ module Test
|
|
65
65
|
# Marks the test or part of the test is pending.
|
66
66
|
#
|
67
67
|
# Example:
|
68
|
-
# def test_pending
|
69
|
-
# pend
|
70
|
-
# # Not reached here
|
71
|
-
# end
|
72
68
|
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
# #
|
76
|
-
#
|
77
|
-
#
|
69
|
+
# def test_pending
|
70
|
+
# pend
|
71
|
+
# # Not reached here
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# def test_pending_with_here
|
75
|
+
# pend do
|
76
|
+
# # Ran here
|
77
|
+
# # Fails if the block doesn't raise any error.
|
78
|
+
# # Because it means the block is passed unexpectedly.
|
79
|
+
# end
|
80
|
+
# # Reached here
|
78
81
|
# end
|
79
|
-
# # Reached here
|
80
|
-
# end
|
81
82
|
def pend(message=nil, &block)
|
82
83
|
message ||= "pended."
|
83
84
|
if block_given?
|
data/lib/test/unit/priority.rb
CHANGED
@@ -148,15 +148,19 @@ module Test
|
|
148
148
|
end
|
149
149
|
|
150
150
|
def escape_class_name(class_name)
|
151
|
-
class_name
|
151
|
+
escape_name(class_name)
|
152
152
|
end
|
153
153
|
|
154
154
|
def escaped_method_name
|
155
|
-
@test.method_name.to_s
|
155
|
+
escape_name(@test.method_name.to_s)
|
156
|
+
end
|
157
|
+
|
158
|
+
def escape_name(name)
|
159
|
+
name.gsub(/(?:[: \/!?=])/) do |matched|
|
156
160
|
case matched
|
157
161
|
when ":"
|
158
162
|
"_colon_"
|
159
|
-
when " "
|
163
|
+
when " ", "/"
|
160
164
|
"_"
|
161
165
|
when "!"
|
162
166
|
".destructive"
|
@@ -1,3 +1,22 @@
|
|
1
|
+
# Copyright (C) 2008-2017 Kouhei Sutou <kou@clear-code.com>
|
2
|
+
#
|
3
|
+
# License: Ruby OR LGPL-2.1+
|
4
|
+
#
|
5
|
+
# This library is free software; you can redistribute it and/or
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
7
|
+
# License as published by the Free Software Foundation; either
|
8
|
+
# version 2.1 of the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This library is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
# Lesser General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
16
|
+
# License along with this library; if not, write to the Free Software
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
18
|
+
# 02110-1301 USA
|
19
|
+
|
1
20
|
module Test
|
2
21
|
module Unit
|
3
22
|
AutoRunner.register_runner(:console) do |auto_runner|
|
@@ -54,6 +73,12 @@ module Test
|
|
54
73
|
"(default is yes)") do |boolean|
|
55
74
|
auto_runner.runner_options[:show_detail_immediately] = boolean
|
56
75
|
end
|
76
|
+
|
77
|
+
opts.on("--[no-]reverse-output",
|
78
|
+
"Shows fault details in reverse.",
|
79
|
+
"(default is yes for tty output, no otherwise)") do |boolean|
|
80
|
+
auto_runner.runner_options[:reverse_output] = boolean
|
81
|
+
end
|
57
82
|
end
|
58
83
|
end
|
59
84
|
end
|