test-unit 3.2.9 → 3.5.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/BSDL +24 -0
  3. data/COPYING +41 -44
  4. data/README.md +18 -11
  5. data/Rakefile +0 -23
  6. data/doc/text/getting-started.md +2 -2
  7. data/doc/text/news.md +329 -1
  8. data/lib/test/unit/assertion-failed-error.rb +35 -0
  9. data/lib/test/unit/assertions.rb +453 -161
  10. data/lib/test/unit/attribute.rb +3 -1
  11. data/lib/test/unit/autorunner.rb +78 -30
  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 +3 -3
  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 +26 -15
  20. data/lib/test/unit/data.rb +5 -5
  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 -5
  27. data/lib/test/unit/runner/console.rb +0 -17
  28. data/lib/test/unit/testcase.rb +222 -146
  29. data/lib/test/unit/testsuite.rb +1 -1
  30. data/lib/test/unit/ui/console/testrunner.rb +58 -49
  31. data/lib/test/unit/util/memory-usage.rb +47 -0
  32. data/lib/test/unit/util/observable.rb +2 -2
  33. data/lib/test/unit/util/output.rb +5 -4
  34. data/lib/test/unit/version.rb +1 -1
  35. data/lib/test/unit/warning.rb +3 -0
  36. data/lib/test/unit.rb +177 -161
  37. data/lib/test-unit.rb +2 -17
  38. metadata +14 -91
  39. data/GPL +0 -339
  40. data/LGPL +0 -502
  41. data/test/collector/test-descendant.rb +0 -182
  42. data/test/collector/test-load.rb +0 -442
  43. data/test/collector/test_dir.rb +0 -407
  44. data/test/collector/test_objectspace.rb +0 -102
  45. data/test/fixtures/header-label.csv +0 -3
  46. data/test/fixtures/header-label.tsv +0 -3
  47. data/test/fixtures/header.csv +0 -3
  48. data/test/fixtures/header.tsv +0 -3
  49. data/test/fixtures/no-header.csv +0 -2
  50. data/test/fixtures/no-header.tsv +0 -2
  51. data/test/fixtures/plus.csv +0 -3
  52. data/test/run-test.rb +0 -22
  53. data/test/test-assertions.rb +0 -2180
  54. data/test/test-attribute-matcher.rb +0 -38
  55. data/test/test-attribute.rb +0 -123
  56. data/test/test-code-snippet.rb +0 -37
  57. data/test/test-color-scheme.rb +0 -82
  58. data/test/test-color.rb +0 -47
  59. data/test/test-data.rb +0 -419
  60. data/test/test-diff.rb +0 -518
  61. data/test/test-emacs-runner.rb +0 -60
  62. data/test/test-error.rb +0 -26
  63. data/test/test-failure.rb +0 -33
  64. data/test/test-fault-location-detector.rb +0 -163
  65. data/test/test-fixture.rb +0 -713
  66. data/test/test-notification.rb +0 -33
  67. data/test/test-omission.rb +0 -81
  68. data/test/test-pending.rb +0 -70
  69. data/test/test-priority.rb +0 -173
  70. data/test/test-test-case.rb +0 -1279
  71. data/test/test-test-result.rb +0 -113
  72. data/test/test-test-suite-creator.rb +0 -97
  73. data/test/test-test-suite.rb +0 -151
  74. data/test/testunit-test-util.rb +0 -31
  75. data/test/ui/test_testrunmediator.rb +0 -20
  76. data/test/util/test-method-owner-finder.rb +0 -38
  77. data/test/util/test-output.rb +0 -11
  78. data/test/util/test_backtracefilter.rb +0 -52
  79. data/test/util/test_observable.rb +0 -102
  80. data/test/util/test_procwrapper.rb +0 -36
@@ -199,12 +199,14 @@ module Test
199
199
  ancestor.is_a?(Class) and
200
200
  ancestor < Test::Unit::Attribute
201
201
  end
202
+ return nil if @cached_parent_test_case.nil?
202
203
 
203
204
  @cached_parent_test_case.find_attribute(method_name, name, options)
204
205
  end
205
206
 
206
207
  @@attribute_observers = StringifyKeyHash.new
207
- def register_attribute_observer(attribute_name, observer=Proc.new)
208
+ def register_attribute_observer(attribute_name, observer=nil, &block)
209
+ observer ||= Proc.new(&block)
208
210
  @@attribute_observers[attribute_name] ||= []
209
211
  @@attribute_observers[attribute_name] << observer
210
212
  end
@@ -1,10 +1,10 @@
1
1
  require "English"
2
+ require "optparse"
2
3
 
3
4
  require "test/unit/color-scheme"
4
5
  require "test/unit/priority"
5
6
  require "test/unit/attribute-matcher"
6
7
  require "test/unit/testcase"
7
- require "optparse"
8
8
 
9
9
  module Test
10
10
  module Unit
@@ -15,7 +15,8 @@ module Test
15
15
  PREPARE_HOOKS = []
16
16
 
17
17
  class << self
18
- def register_runner(id, runner_builder=Proc.new)
18
+ def register_runner(id, runner_builder=nil, &block)
19
+ runner_builder ||= Proc.new(&block)
19
20
  RUNNERS[id] = runner_builder
20
21
  RUNNERS[id.to_s] = runner_builder
21
22
  end
@@ -33,7 +34,8 @@ module Test
33
34
  @@default_runner = id
34
35
  end
35
36
 
36
- def register_collector(id, collector_builder=Proc.new)
37
+ def register_collector(id, collector_builder=nil, &block)
38
+ collector_builder ||= Proc.new(&block)
37
39
  COLLECTORS[id] = collector_builder
38
40
  COLLECTORS[id.to_s] = collector_builder
39
41
  end
@@ -46,11 +48,13 @@ module Test
46
48
  ColorScheme[id] = scheme
47
49
  end
48
50
 
49
- def setup_option(option_builder=Proc.new)
51
+ def setup_option(option_builder=nil, &block)
52
+ option_builder ||= Proc.new(&block)
50
53
  ADDITIONAL_OPTIONS << option_builder
51
54
  end
52
55
 
53
- def prepare(hook=Proc.new)
56
+ def prepare(hook=nil, &block)
57
+ hook ||= Proc.new(&block)
54
58
  PREPARE_HOOKS << hook
55
59
  end
56
60
 
@@ -140,6 +144,7 @@ module Test
140
144
  attr_accessor :pattern, :exclude, :base, :workdir
141
145
  attr_accessor :color_scheme, :listeners
142
146
  attr_writer :stop_on_failure
147
+ attr_writer :debug_on_failure
143
148
  attr_writer :runner, :collector
144
149
 
145
150
  def initialize(standalone)
@@ -155,6 +160,7 @@ module Test
155
160
  @workdir = nil
156
161
  @listeners = []
157
162
  @stop_on_failure = false
163
+ @debug_on_failure = false
158
164
  config_file = "test-unit.yml"
159
165
  if File.exist?(config_file)
160
166
  load_config(config_file)
@@ -168,6 +174,10 @@ module Test
168
174
  @stop_on_failure
169
175
  end
170
176
 
177
+ def debug_on_failure?
178
+ @debug_on_failure
179
+ end
180
+
171
181
  def prepare
172
182
  PREPARE_HOOKS.each do |handler|
173
183
  handler.call(self)
@@ -242,54 +252,61 @@ module Test
242
252
 
243
253
  o.on("-n", "--name=NAME", String,
244
254
  "Runs tests matching NAME.",
245
- "Use '/PATTERN/' for NAME to use regular expression.") do |name|
246
- name = (%r{\A/(.*)/\Z} =~ name ? Regexp.new($1) : name)
255
+ "Use '/PATTERN/' for NAME to use regular expression.",
256
+ "Regular expression accepts options.",
257
+ "Example: '/taRget/i' matches 'target' and 'TARGET'") do |name|
258
+ name = prepare_name(name)
247
259
  @filters << lambda do |test|
248
- return true if name === test.method_name
249
- return true if name === test.local_name
250
- false
260
+ match_test_name(test, name)
251
261
  end
252
262
  end
253
263
 
254
264
  o.on("--ignore-name=NAME", String,
255
265
  "Ignores tests matching NAME.",
256
- "Use '/PATTERN/' for NAME to use regular expression.") do |n|
257
- n = (%r{\A/(.*)/\Z} =~ n ? Regexp.new($1) : n)
258
- case n
259
- when Regexp
260
- @filters << proc {|t| n =~ t.method_name ? false : true}
261
- else
262
- @filters << proc {|t| n != t.method_name}
266
+ "Use '/PATTERN/' for NAME to use regular expression.",
267
+ "Regular expression accepts options.",
268
+ "Example: '/taRget/i' matches 'target' and 'TARGET'") do |name|
269
+ name = prepare_name(name)
270
+ @filters << lambda do |test|
271
+ not match_test_name(test, name)
263
272
  end
264
273
  end
265
274
 
266
275
  o.on("-t", "--testcase=TESTCASE", String,
267
276
  "Runs tests in TestCases matching TESTCASE.",
268
- "Use '/PATTERN/' for TESTCASE to use regular expression.") do |n|
269
- n = (%r{\A/(.*)/\Z} =~ n ? Regexp.new($1) : n)
277
+ "Use '/PATTERN/' for TESTCASE to use regular expression.",
278
+ "Regular expression accepts options.",
279
+ "Example: '/taRget/i' matches 'target' and 'TARGET'") do |name|
280
+ name = prepare_name(name)
270
281
  @filters << lambda do |test|
271
- match_test_case_name(test, n)
282
+ match_test_case_name(test, name)
272
283
  end
273
284
  end
274
285
 
275
286
  o.on("--ignore-testcase=TESTCASE", String,
276
287
  "Ignores tests in TestCases matching TESTCASE.",
277
- "Use '/PATTERN/' for TESTCASE to use regular expression.") do |n|
278
- n = (%r{\A/(.*)/\Z} =~ n ? Regexp.new($1) : n)
288
+ "Use '/PATTERN/' for TESTCASE to use regular expression.",
289
+ "Regular expression accepts options.",
290
+ "Example: '/taRget/i' matches 'target' and 'TARGET'") do |name|
291
+ name = prepare_name(name)
279
292
  @filters << lambda do |test|
280
- not match_test_case_name(test, n)
293
+ not match_test_case_name(test, name)
281
294
  end
282
295
  end
283
296
 
284
297
  o.on("--location=LOCATION", String,
285
298
  "Runs tests that defined in LOCATION.",
286
- "LOCATION is one of PATH:LINE, PATH or LINE") do |location|
287
- if /\A\d+\z/ =~ location
299
+ "LOCATION is one of PATH:LINE, PATH or LINE.") do |location|
300
+ case location
301
+ when /\A(\d+)\z/
288
302
  path = nil
289
- line = location.to_i
303
+ line = $1.to_i
304
+ when /:(\d+)\z/
305
+ path = $PREMATCH
306
+ line = $1.to_i
290
307
  else
291
- path, line, = location.split(/:(\d+)/, 2)
292
- line = line.to_i unless line.nil?
308
+ path = location
309
+ line = nil
293
310
  end
294
311
  add_location_filter(path, line)
295
312
  end
@@ -345,7 +362,7 @@ module Test
345
362
  end
346
363
 
347
364
  o.on("--config=FILE",
348
- "Use YAML fomat FILE content as configuration file.") do |file|
365
+ "Use YAML format FILE content as configuration file.") do |file|
349
366
  load_config(file)
350
367
  end
351
368
 
@@ -370,6 +387,12 @@ module Test
370
387
  @stop_on_failure = boolean
371
388
  end
372
389
 
390
+ o.on("--[no-]debug-on-failure",
391
+ "Run debugger if available on failure",
392
+ "(#{AssertionFailedError.debug_on_failure?})") do |boolean|
393
+ AssertionFailedError.debug_on_failure = boolean
394
+ end
395
+
373
396
  ADDITIONAL_OPTIONS.each do |option_builder|
374
397
  option_builder.call(self, o)
375
398
  end
@@ -452,7 +475,7 @@ module Test
452
475
  if key == :arguments
453
476
  @default_arguments.concat(value.split)
454
477
  else
455
- runner_options[key.to_sym] = value
478
+ runner_options[key] = value
456
479
  end
457
480
  end
458
481
  @runner_options = @runner_options.merge(runner_options)
@@ -492,6 +515,31 @@ module Test
492
515
  end
493
516
  end
494
517
 
518
+ def prepare_name(name)
519
+ case name
520
+ when /\A\/(.*)\/([imx]*)\z/
521
+ pattern = $1
522
+ options_raw = $2
523
+ options = 0
524
+ options |= Regexp::IGNORECASE if options_raw.include?("i")
525
+ options |= Regexp::MULTILINE if options_raw.include?("m")
526
+ options |= Regexp::EXTENDED if options_raw.include?("x")
527
+ Regexp.new(pattern, options)
528
+ else
529
+ name
530
+ end
531
+ end
532
+
533
+ def match_test_name(test, pattern)
534
+ return true if pattern === test.method_name
535
+ return true if pattern === test.local_name
536
+ if pattern.is_a?(String)
537
+ return true if pattern === "#{test.class}##{test.method_name}"
538
+ return true if pattern === "#{test.class}##{test.local_name}"
539
+ end
540
+ false
541
+ end
542
+
495
543
  def match_test_case_name(test, pattern)
496
544
  test.class.ancestors.each do |test_class|
497
545
  break if test_class == TestCase
@@ -26,16 +26,16 @@ module Test
26
26
  def read_source(path)
27
27
  return nil unless File.exist?(path)
28
28
  lines = []
29
- File.open(path) do |file|
29
+ File.open(path, "rb") do |file|
30
30
  first_line = file.gets
31
31
  break if first_line.nil?
32
- encoding = detect_encoding(first_line)
33
- if encoding
34
- first_line.force_encoding(encoding)
35
- file.set_encoding(encoding, encoding)
36
- end
32
+ encoding = detect_encoding(first_line) || Encoding::UTF_8
33
+ first_line.force_encoding(encoding)
37
34
  lines << first_line
38
- lines.concat(file.readlines)
35
+ file.each_line do |line|
36
+ line.force_encoding(encoding)
37
+ lines << line
38
+ end
39
39
  end
40
40
  lines
41
41
  end
@@ -11,6 +11,7 @@ module Test
11
11
  def collect(name=NAME)
12
12
  suite = TestSuite.new(name)
13
13
  add_test_cases(suite, TestCase::DESCENDANTS)
14
+ adjust_ractor_tests(suite)
14
15
  suite
15
16
  end
16
17
  end
@@ -25,9 +25,9 @@ module Test
25
25
  basedir = @base
26
26
  $:.push(basedir) if basedir
27
27
  if(from.empty?)
28
- recursive_collect('.', find_test_cases)
28
+ suite = recursive_collect('.', find_test_cases)
29
29
  elsif(from.size == 1)
30
- recursive_collect(from.first, find_test_cases)
30
+ suite = recursive_collect(from.first, find_test_cases)
31
31
  else
32
32
  suites = []
33
33
  from.each do |f|
@@ -38,6 +38,8 @@ module Test
38
38
  sort(suites).each{|s| suite << s}
39
39
  suite
40
40
  end
41
+ adjust_ractor_tests(suite)
42
+ suite
41
43
  ensure
42
44
  $:.delete_at($:.rindex(basedir)) if basedir
43
45
  end
@@ -60,6 +60,8 @@ module Test
60
60
  test_suite = test_suites.first
61
61
  end
62
62
 
63
+ adjust_ractor_tests(test_suite)
64
+
63
65
  test_suite
64
66
  end
65
67
  end
@@ -111,7 +113,7 @@ module Test
111
113
  return if @program_file == expanded_path.to_s
112
114
  add_load_path(expanded_path.dirname) do
113
115
  begin
114
- require(path.basename.to_s)
116
+ require(expanded_path.to_s)
115
117
  rescue LoadError
116
118
  @require_failed_infos << {:path => expanded_path, :exception => $!}
117
119
  end
@@ -131,8 +133,6 @@ module Test
131
133
  return yield if path.nil?
132
134
 
133
135
  path = path.to_s
134
- return yield if $LOAD_PATH.index(path)
135
-
136
136
  begin
137
137
  $LOAD_PATH.unshift(path)
138
138
  yield
@@ -26,6 +26,7 @@ module Test
26
26
  end
27
27
  end
28
28
  sort(sub_suites).each{|s| suite << s}
29
+ adjust_ractor_tests(suite)
29
30
  suite
30
31
  end
31
32
  end
@@ -68,6 +68,37 @@ module Test
68
68
  suite << sub_suite
69
69
  end
70
70
  end
71
+
72
+ def adjust_ractor_tests(suite)
73
+ return if suite.nil?
74
+ ractor_suites = extract_ractor_tests(suite)
75
+ ractor_suites.each do |ractor_suite|
76
+ suite << ractor_suite
77
+ end
78
+ end
79
+
80
+ def extract_ractor_tests(suite)
81
+ ractor_suites = []
82
+ ractor_tests = []
83
+ suite.tests.each do |test|
84
+ case test
85
+ when TestSuite
86
+ ractor_suites.concat(extract_ractor_tests(test))
87
+ else
88
+ next unless test[:ractor]
89
+ ractor_tests << test
90
+ end
91
+ end
92
+ unless ractor_tests.empty?
93
+ suite.delete_tests(ractor_tests)
94
+ ractor_suite = TestSuite.new(suite.name, suite.test_case)
95
+ ractor_tests.each do |ractor_test|
96
+ ractor_suite << ractor_test
97
+ end
98
+ ractor_suites << ractor_suite
99
+ end
100
+ ractor_suites
101
+ end
71
102
  end
72
103
  end
73
104
  end
@@ -5,9 +5,25 @@ module Test
5
5
  class ColorScheme
6
6
  include Enumerable
7
7
 
8
+ TERM_256 = /
9
+ [+-]256color|
10
+ \A(?:
11
+ alacritty|
12
+ iTerm\s?\d*\.app|
13
+ kitty|
14
+ mintty|
15
+ ms-terminal|
16
+ nsterm-build\d+|
17
+ nsterm|
18
+ terminator|
19
+ terminology(?:-[0-9.]+)?|
20
+ termite|
21
+ vscode
22
+ )\z/x
23
+
8
24
  class << self
9
25
  def default
10
- if available_colors == 256
26
+ if available_colors >= 256
11
27
  default_for_256_colors
12
28
  else
13
29
  default_for_8_colors
@@ -140,7 +156,9 @@ module Test
140
156
 
141
157
  def guess_available_colors_from_term_env
142
158
  case ENV["TERM"]
143
- when /-256color\z/
159
+ when /[+-]direct/
160
+ 2**24
161
+ when TERM_256
144
162
  256
145
163
  else
146
164
  nil
@@ -22,17 +22,16 @@ module Test
22
22
  add(data_set)
23
23
  end
24
24
 
25
+ def have_keep?
26
+ each_data_set do |_, options|
27
+ return true if options[:keep]
28
+ end
29
+ false
30
+ end
31
+
25
32
  def keep
26
33
  new_data_sets = self.class.new
27
- all_data_sets = Enumerator.new do |yielder|
28
- block = lambda do |(data_set, options)|
29
- yielder << [data_set, options]
30
- end
31
- @procs.each(&block)
32
- @variables.each(&block)
33
- @value_sets.each(&block)
34
- end
35
- all_data_sets.each do |data_set, options|
34
+ each_data_set do |data_set, options|
36
35
  next if options.nil?
37
36
  next unless options[:keep]
38
37
  new_data_sets.add(data_set, options)
@@ -79,18 +78,24 @@ module Test
79
78
  end
80
79
 
81
80
  private
81
+ def each_data_set(&block)
82
+ @procs.each(&block)
83
+ @variables.each(&block)
84
+ @value_sets.each(&block)
85
+ end
86
+
82
87
  def each_pattern(variables)
83
88
  grouped_variables = variables.group_by do |_, options|
84
89
  options[:group]
85
90
  end
86
- grouped_variables.each do |group, variables|
87
- each_raw_pattern(variables) do |cell|
91
+ grouped_variables.each do |group, group_variables|
92
+ each_raw_pattern(group_variables) do |cell|
88
93
  label = String.new
89
94
  label << "group: #{group.inspect}" unless group.nil?
90
95
  data = {}
91
- cell.each do |variable, pattern|
96
+ cell.each do |variable, pattern, pattern_label|
92
97
  label << ", " unless label.empty?
93
- label << "#{variable}: #{pattern.inspect}"
98
+ label << "#{variable}: #{pattern_label}"
94
99
  data[variable] = pattern
95
100
  end
96
101
  yield(label, data)
@@ -105,8 +110,14 @@ module Test
105
110
  variable
106
111
  end
107
112
  all_patterns = sorted_variables.collect do |(variable, patterns), _|
108
- patterns.collect do |pattern|
109
- [variable, pattern]
113
+ if patterns.is_a?(Hash)
114
+ patterns.collect do |pattern_label, pattern|
115
+ [variable, pattern, pattern_label]
116
+ end
117
+ else
118
+ patterns.collect do |pattern|
119
+ [variable, pattern, pattern.inspect]
120
+ end
110
121
  end
111
122
  end
112
123
  all_patterns[0].product(*all_patterns[1..-1], &block)
@@ -136,7 +136,7 @@ module Test
136
136
  when 1
137
137
  if block_given?
138
138
  data_set = block
139
- options = arguments[1]
139
+ options = arguments[0]
140
140
  else
141
141
  data_set = arguments[0]
142
142
  end
@@ -170,11 +170,11 @@ module Test
170
170
  options ||= {}
171
171
  data_sets = current_attribute(:data)[:value] || DataSets.new
172
172
  data_sets.add(data_set, options)
173
- if options[:keep]
173
+ if options[:keep] or data_sets.have_keep?
174
174
  keep_hook = lambda do |attr|
175
175
  attr.merge(value: attr[:value].keep)
176
176
  end
177
- options = options.merge(keep_hook: keep_hook)
177
+ options = options.merge(keep: true, keep_hook: keep_hook)
178
178
  end
179
179
  attribute(:data, data_sets, options)
180
180
  end
@@ -187,7 +187,7 @@ module Test
187
187
  #
188
188
  # @param [String] file_name full path to test data file.
189
189
  # File format is automatically detected from filename extension.
190
- # @raise [ArgumentError] if +file_name+ is not supported file format.
190
+ # @raise [ArgumentError] if `file_name` is not supported file format.
191
191
  # @see Loader#load
192
192
  #
193
193
  # @example Load data from CSV file
@@ -211,7 +211,7 @@ module Test
211
211
  #
212
212
  # @param [String] file_name full path to test data file.
213
213
  # File format is automatically detected from filename extension.
214
- # @raise [ArgumentError] if +file_name+ is not supported file format.
214
+ # @raise [ArgumentError] if `file_name` is not supported file format.
215
215
  # @see #load_csv
216
216
  # @see #load_tsv
217
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