test-unit 3.2.5 → 3.4.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +5 -5
  2. data/BSDL +24 -0
  3. data/COPYING +41 -44
  4. data/README.md +8 -11
  5. data/Rakefile +0 -23
  6. data/doc/text/getting-started.md +1 -1
  7. data/doc/text/news.md +366 -0
  8. data/lib/test/unit/assertion-failed-error.rb +35 -0
  9. data/lib/test/unit/assertions.rb +312 -112
  10. data/lib/test/unit/attribute.rb +7 -2
  11. data/lib/test/unit/autorunner.rb +79 -31
  12. data/lib/test/unit/code-snippet-fetcher.rb +7 -7
  13. data/lib/test/unit/collector/descendant.rb +1 -0
  14. data/lib/test/unit/collector/dir.rb +4 -2
  15. data/lib/test/unit/collector/load.rb +10 -13
  16. data/lib/test/unit/collector/objectspace.rb +1 -0
  17. data/lib/test/unit/collector.rb +31 -0
  18. data/lib/test/unit/color-scheme.rb +20 -2
  19. data/lib/test/unit/data-sets.rb +116 -0
  20. data/lib/test/unit/data.rb +121 -12
  21. data/lib/test/unit/diff.rb +2 -3
  22. data/lib/test/unit/fixture.rb +6 -0
  23. data/lib/test/unit/notification.rb +9 -7
  24. data/lib/test/unit/omission.rb +34 -31
  25. data/lib/test/unit/pending.rb +12 -11
  26. data/lib/test/unit/priority.rb +7 -3
  27. data/lib/test/unit/runner/console.rb +8 -0
  28. data/lib/test/unit/test-suite-creator.rb +22 -8
  29. data/lib/test/unit/testcase.rb +216 -146
  30. data/lib/test/unit/testsuite.rb +1 -1
  31. data/lib/test/unit/ui/console/testrunner.rb +92 -32
  32. data/lib/test/unit/util/memory-usage.rb +47 -0
  33. data/lib/test/unit/util/observable.rb +2 -2
  34. data/lib/test/unit/util/output.rb +5 -4
  35. data/lib/test/unit/util/procwrapper.rb +4 -4
  36. data/lib/test/unit/version.rb +1 -1
  37. data/lib/test/unit/warning.rb +3 -0
  38. data/lib/test/unit.rb +177 -161
  39. data/lib/test-unit.rb +2 -17
  40. metadata +13 -88
  41. data/GPL +0 -339
  42. data/LGPL +0 -502
  43. data/test/collector/test-descendant.rb +0 -182
  44. data/test/collector/test-load.rb +0 -442
  45. data/test/collector/test_dir.rb +0 -407
  46. data/test/collector/test_objectspace.rb +0 -102
  47. data/test/fixtures/header-label.csv +0 -3
  48. data/test/fixtures/header-label.tsv +0 -3
  49. data/test/fixtures/header.csv +0 -3
  50. data/test/fixtures/header.tsv +0 -3
  51. data/test/fixtures/no-header.csv +0 -2
  52. data/test/fixtures/no-header.tsv +0 -2
  53. data/test/fixtures/plus.csv +0 -3
  54. data/test/run-test.rb +0 -22
  55. data/test/test-assertions.rb +0 -2180
  56. data/test/test-attribute-matcher.rb +0 -38
  57. data/test/test-attribute.rb +0 -123
  58. data/test/test-code-snippet.rb +0 -37
  59. data/test/test-color-scheme.rb +0 -82
  60. data/test/test-color.rb +0 -47
  61. data/test/test-data.rb +0 -303
  62. data/test/test-diff.rb +0 -518
  63. data/test/test-emacs-runner.rb +0 -60
  64. data/test/test-error.rb +0 -26
  65. data/test/test-failure.rb +0 -33
  66. data/test/test-fault-location-detector.rb +0 -163
  67. data/test/test-fixture.rb +0 -713
  68. data/test/test-notification.rb +0 -33
  69. data/test/test-omission.rb +0 -81
  70. data/test/test-pending.rb +0 -70
  71. data/test/test-priority.rb +0 -173
  72. data/test/test-test-case.rb +0 -1278
  73. data/test/test-test-result.rb +0 -113
  74. data/test/test-test-suite-creator.rb +0 -97
  75. data/test/test-test-suite.rb +0 -151
  76. data/test/testunit-test-util.rb +0 -31
  77. data/test/ui/test_testrunmediator.rb +0 -20
  78. data/test/util/test-method-owner-finder.rb +0 -38
  79. data/test/util/test-output.rb +0 -11
  80. data/test/util/test_backtracefilter.rb +0 -52
  81. data/test/util/test_observable.rb +0 -102
  82. data/test/util/test_procwrapper.rb +0 -36
@@ -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,8 @@
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 license, the
7
- # PSF license and/or LGPLv2.1 or later. See the COPYING file, the PSFL
8
- # file and the LGPL file.
6
+ # It is free software, and is distributed under (the new Ruby license
7
+ # or BSDL) and the PSF license.
9
8
 
10
9
  module Test
11
10
  module Unit
@@ -103,6 +103,7 @@ module Test
103
103
  @test_case = test_case
104
104
  @type = type
105
105
  @default_options = default_options
106
+ @callbacks = {}
106
107
  @before_prepend_callbacks = []
107
108
  @before_append_callbacks = []
108
109
  @after_prepend_callbacks = []
@@ -130,6 +131,11 @@ module Test
130
131
  @test_case.attribute(:source_location,
131
132
  callback.source_location,
132
133
  method_name)
134
+ # For Ruby 2.6 or earlier. callback may be GC-ed. If
135
+ # callback is GC-ed, callback_method_name may be
136
+ # duplicated because callback_method_name uses callback.object_id.
137
+ # See also: https://github.com/test-unit/test-unit/issues/179
138
+ @callbacks[callback] = true
133
139
  @test_case.__send__(:define_method, method_name, &callback)
134
140
  else
135
141
  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,5 @@
1
+ # Copyright (C) 2008-2017 Kouhei Sutou <kou@clear-code.com>
2
+
1
3
  module Test
2
4
  module Unit
3
5
  AutoRunner.register_runner(:console) do |auto_runner|
@@ -54,6 +56,12 @@ module Test
54
56
  "(default is yes)") do |boolean|
55
57
  auto_runner.runner_options[:show_detail_immediately] = boolean
56
58
  end
59
+
60
+ opts.on("--[no-]reverse-output",
61
+ "Shows fault details in reverse.",
62
+ "(default is yes for tty output, no otherwise)") do |boolean|
63
+ auto_runner.runner_options[:reverse_output] = boolean
64
+ end
57
65
  end
58
66
  end
59
67
  end
@@ -5,6 +5,8 @@
5
5
  # * Copyright (c) 2011 Kouhei Sutou <tt><kou@clear-code.com></tt>
6
6
  # License:: Ruby license.
7
7
 
8
+ require "test/unit/data-sets"
9
+
8
10
  module Test
9
11
  module Unit
10
12
  class TestSuiteCreator # :nodoc:
@@ -22,15 +24,11 @@ module Test
22
24
  def create
23
25
  suite = TestSuite.new(@test_case.name, @test_case)
24
26
  collect_test_names.each do |test_name|
25
- data_sets = @test_case.find_attribute(test_name, :data,
26
- :recursive => false)
27
+ data_sets = extract_data_sets(test_name)
27
28
  if data_sets
28
- data_sets.each do |data_set|
29
- data_set = data_set.call if data_set.respond_to?(:call)
30
- data_set.each do |label, data|
31
- append_test(suite, test_name) do |test|
32
- test.assign_test_data(label, data)
33
- end
29
+ data_sets.each do |label, data|
30
+ append_test(suite, test_name) do |test|
31
+ test.assign_test_data(label, data)
34
32
  end
35
33
  end
36
34
  else
@@ -42,6 +40,22 @@ module Test
42
40
  end
43
41
 
44
42
  private
43
+ def extract_data_sets(test_name)
44
+ data_sets = @test_case.find_attribute(test_name,
45
+ :data,
46
+ :recursive => false)
47
+ data_method_name = "data_#{test_name}"
48
+ test = @test_case.new(test_name)
49
+ if test.respond_to?(data_method_name)
50
+ data_method = test.method(data_method_name)
51
+ if data_method.arity <= 0
52
+ data_sets ||= DataSets.new
53
+ data_sets << data_method
54
+ end
55
+ end
56
+ data_sets
57
+ end
58
+
45
59
  def append_test(suite, test_name)
46
60
  test = @test_case.new(test_name)
47
61
  yield(test) if block_given?