test-unit 3.2.0 → 3.3.6
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.
- 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
|