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.
Files changed (41) hide show
  1. checksums.yaml +5 -5
  2. data/COPYING +4 -1
  3. data/README.md +11 -11
  4. data/Rakefile +10 -1
  5. data/doc/text/getting-started.md +246 -0
  6. data/doc/text/news.md +372 -1
  7. data/lib/test/unit.rb +171 -157
  8. data/lib/test/unit/assertions.rb +187 -149
  9. data/lib/test/unit/attribute.rb +71 -2
  10. data/lib/test/unit/autorunner.rb +65 -32
  11. data/lib/test/unit/code-snippet-fetcher.rb +7 -7
  12. data/lib/test/unit/collector/load.rb +8 -13
  13. data/lib/test/unit/data-sets.rb +116 -0
  14. data/lib/test/unit/data.rb +121 -12
  15. data/lib/test/unit/diff.rb +11 -11
  16. data/lib/test/unit/fixture.rb +3 -0
  17. data/lib/test/unit/notification.rb +9 -7
  18. data/lib/test/unit/omission.rb +34 -31
  19. data/lib/test/unit/pending.rb +12 -11
  20. data/lib/test/unit/priority.rb +7 -3
  21. data/lib/test/unit/runner/console.rb +25 -0
  22. data/lib/test/unit/test-suite-creator.rb +22 -8
  23. data/lib/test/unit/testcase.rb +270 -182
  24. data/lib/test/unit/ui/console/testrunner.rb +90 -35
  25. data/lib/test/unit/ui/emacs/testrunner.rb +5 -5
  26. data/lib/test/unit/util/observable.rb +2 -2
  27. data/lib/test/unit/util/output.rb +5 -4
  28. data/lib/test/unit/util/procwrapper.rb +4 -4
  29. data/lib/test/unit/version.rb +1 -1
  30. data/test/collector/test-descendant.rb +4 -0
  31. data/test/collector/test-load.rb +35 -2
  32. data/test/collector/test_dir.rb +5 -4
  33. data/test/collector/test_objectspace.rb +7 -5
  34. data/test/test-assertions.rb +128 -101
  35. data/test/test-code-snippet.rb +42 -0
  36. data/test/test-data.rb +195 -79
  37. data/test/test-priority.rb +19 -8
  38. data/test/test-test-case.rb +111 -3
  39. data/test/test-test-suite.rb +1 -0
  40. data/test/testunit-test-util.rb +2 -0
  41. metadata +38 -37
@@ -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(data_set)
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
- # @yieldreturn [Hash] return test data set as a Hash that
41
- # key is test label and value is test data.
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
- data_set = arguments[0]
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
- data_set = {arguments[0] => arguments[1]}
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 1..2)"
167
+ message = "wrong number arguments(#{n_arguments} for 0..3)"
67
168
  raise ArgumentError, message
68
169
  end
69
- current_data = current_attribute(:data)[:value] || []
70
- attribute(:data, current_data + [data_set])
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 +file_name+ is not supported file format.
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 +file_name+ is not supported file format.
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
@@ -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 the PSF license. See the COPYING file and
8
- # PSFL file.
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| "#{mark}#{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 << "#{mark}#{content}"
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 << "^" * from_width
581
- to_tags << "^" * to_width
580
+ from_tags += "^" * from_width
581
+ to_tags += "^" * to_width
582
582
  when :delete
583
- from_tags << "-" * from_width
583
+ from_tags += "-" * from_width
584
584
  when :insert
585
- to_tags << "+" * to_width
585
+ to_tags += "+" * to_width
586
586
  when :equal
587
- from_tags << " " * from_width
588
- to_tags << " " * to_width
587
+ from_tags += " " * from_width
588
+ to_tags += " " * to_width
589
589
  else
590
590
  raise "unknown tag: #{tag}"
591
591
  end
@@ -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
- # def test_notification
69
- # notify("I'm here!")
70
- # # Reached here
71
- # notify("Special!") if special_case?
72
- # # Reached here too
73
- # end
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
- # :backtrace override backtrace.
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,
@@ -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
- # def test_omission_with_here
74
- # omit do
75
- # # Not ran here
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
- # def test_omission_with_here
100
- # omit_if(true) do
101
- # # Not ran here
96
+ # def test_omission
97
+ # omit_if("".empty?)
98
+ # # Not reached here
102
99
  # end
103
- # omit_if(false) do
104
- # # Reached here
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
- # def test_omission_with_here
126
- # omit_unless(true) do
127
- # # Reached here
123
+ # def test_omission
124
+ # omit_unless("string".empty?)
125
+ # # Not reached here
128
126
  # end
129
- # omit_unless(false) do
130
- # # Not ran here
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
@@ -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
- # def test_pending_with_here
74
- # pend do
75
- # # Ran here
76
- # # Fails if the block doesn't raise any error.
77
- # # Because it means the block is passed unexpectedly.
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?
@@ -148,15 +148,19 @@ module Test
148
148
  end
149
149
 
150
150
  def escape_class_name(class_name)
151
- class_name.gsub(/(?:[: \\\/])/, "_")
151
+ escape_name(class_name)
152
152
  end
153
153
 
154
154
  def escaped_method_name
155
- @test.method_name.to_s.gsub(/(?:[: ]|[!?=]$)/) do |matched|
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