test-unit 3.5.7 → 3.7.0

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/Rakefile +12 -6
  4. data/bin/test-unit +5 -0
  5. data/doc/text/getting-started.md +24 -150
  6. data/doc/text/how-to.md +4 -4
  7. data/doc/text/news.md +218 -0
  8. data/lib/test/unit/assertions.rb +8 -8
  9. data/lib/test/unit/auto-runner-loader.rb +2 -2
  10. data/lib/test/unit/autorunner.rb +77 -13
  11. data/lib/test/unit/collector/descendant.rb +1 -1
  12. data/lib/test/unit/collector/dir.rb +2 -2
  13. data/lib/test/unit/collector/load.rb +8 -6
  14. data/lib/test/unit/collector/objectspace.rb +1 -1
  15. data/lib/test/unit/collector/xml.rb +1 -1
  16. data/lib/test/unit/color-scheme.rb +1 -1
  17. data/lib/test/unit/data.rb +1 -1
  18. data/lib/test/unit/error.rb +1 -1
  19. data/lib/test/unit/failure.rb +1 -1
  20. data/lib/test/unit/fault-location-detector.rb +6 -2
  21. data/lib/test/unit/notification.rb +1 -1
  22. data/lib/test/unit/omission.rb +1 -1
  23. data/lib/test/unit/pending.rb +1 -1
  24. data/lib/test/unit/priority.rb +1 -1
  25. data/lib/test/unit/runner/console.rb +23 -4
  26. data/lib/test/unit/runner/emacs.rb +1 -1
  27. data/lib/test/unit/runner/xml.rb +1 -1
  28. data/lib/test/unit/sub-test-result.rb +59 -0
  29. data/lib/test/unit/test-run-context.rb +16 -0
  30. data/lib/test/unit/test-suite-creator.rb +1 -1
  31. data/lib/test/unit/test-suite-runner.rb +130 -0
  32. data/lib/test/unit/test-suite-thread-runner.rb +84 -0
  33. data/lib/test/unit/test-thread-run-context.rb +20 -0
  34. data/lib/test/unit/testcase.rb +65 -20
  35. data/lib/test/unit/testresult.rb +9 -9
  36. data/lib/test/unit/testsuite.rb +22 -85
  37. data/lib/test/unit/ui/console/testrunner.rb +165 -36
  38. data/lib/test/unit/ui/emacs/testrunner.rb +1 -1
  39. data/lib/test/unit/ui/testrunner.rb +2 -2
  40. data/lib/test/unit/ui/testrunnermediator.rb +16 -11
  41. data/lib/test/unit/ui/xml/testrunner.rb +3 -2
  42. data/lib/test/unit/util/observable.rb +4 -8
  43. data/lib/test/unit/version.rb +1 -1
  44. data/lib/test/unit.rb +6 -6
  45. data/lib/test-unit.rb +2 -2
  46. metadata +12 -78
@@ -1,10 +1,12 @@
1
1
  require "English"
2
2
  require "optparse"
3
3
 
4
- require "test/unit/color-scheme"
5
- require "test/unit/priority"
6
- require "test/unit/attribute-matcher"
7
- require "test/unit/testcase"
4
+ require_relative "color-scheme"
5
+ require_relative "priority"
6
+ require_relative "attribute-matcher"
7
+ require_relative "testcase"
8
+ require_relative "test-suite-thread-runner"
9
+ require_relative "version"
8
10
 
9
11
  module Test
10
12
  module Unit
@@ -85,14 +87,14 @@ module Test
85
87
  end
86
88
 
87
89
  register_collector(:descendant) do |auto_runner|
88
- require "test/unit/collector/descendant"
90
+ require_relative "collector/descendant"
89
91
  collector = Collector::Descendant.new
90
92
  collector.filter = auto_runner.filters
91
93
  collector.collect($0.sub(/\.rb\Z/, ""))
92
94
  end
93
95
 
94
96
  register_collector(:load) do |auto_runner|
95
- require "test/unit/collector/load"
97
+ require_relative "collector/load"
96
98
  collector = Collector::Load.new
97
99
  unless auto_runner.pattern.empty?
98
100
  collector.patterns.replace(auto_runner.pattern)
@@ -108,7 +110,7 @@ module Test
108
110
 
109
111
  # JUST TEST!
110
112
  # register_collector(:xml) do |auto_runner|
111
- # require "test/unit/collector/xml"
113
+ # require_relative "collector/xml"
112
114
  # collector = Collector::XML.new
113
115
  # collector.filter = auto_runner.filters
114
116
  # collector.collect(auto_runner.to_run[0])
@@ -116,7 +118,7 @@ module Test
116
118
 
117
119
  # deprecated
118
120
  register_collector(:object_space) do |auto_runner|
119
- require "test/unit/collector/objectspace"
121
+ require_relative "collector/objectspace"
120
122
  c = Collector::ObjectSpace.new
121
123
  c.filter = auto_runner.filters
122
124
  c.collect($0.sub(/\.rb\Z/, ""))
@@ -124,7 +126,7 @@ module Test
124
126
 
125
127
  # deprecated
126
128
  register_collector(:dir) do |auto_runner|
127
- require "test/unit/collector/dir"
129
+ require_relative "collector/dir"
128
130
  c = Collector::Dir.new
129
131
  c.filter = auto_runner.filters
130
132
  unless auto_runner.pattern.empty?
@@ -145,6 +147,7 @@ module Test
145
147
  attr_accessor :color_scheme, :listeners
146
148
  attr_writer :stop_on_failure
147
149
  attr_writer :debug_on_failure
150
+ attr_writer :gc_stress
148
151
  attr_writer :runner, :collector
149
152
 
150
153
  def initialize(standalone)
@@ -161,12 +164,18 @@ module Test
161
164
  @listeners = []
162
165
  @stop_on_failure = false
163
166
  @debug_on_failure = false
167
+ @gc_stress = false
168
+ @test_suite_runner_class = TestSuiteRunner
164
169
  config_file = "test-unit.yml"
165
170
  if File.exist?(config_file)
166
171
  load_config(config_file)
167
172
  else
168
173
  load_global_config
169
174
  end
175
+ plain_text_config_file = ".test-unit"
176
+ if File.exist?(plain_text_config_file)
177
+ load_plain_text_config(plain_text_config_file)
178
+ end
170
179
  yield(self) if block_given?
171
180
  end
172
181
 
@@ -198,6 +207,8 @@ module Test
198
207
 
199
208
  def options
200
209
  @options ||= OptionParser.new do |o|
210
+ o.version = VERSION
211
+
201
212
  o.banner = "Test::Unit automatic runner."
202
213
  o.banner += "\nUsage: #{$0} [options] [-- untouched arguments]"
203
214
 
@@ -393,6 +404,32 @@ module Test
393
404
  AssertionFailedError.debug_on_failure = boolean
394
405
  end
395
406
 
407
+ o.on("--[no-]gc-stress",
408
+ "Enable GC.stress only while each test is running",
409
+ "(#{@gc_stress})") do |boolean|
410
+ @gc_stress = boolean
411
+ end
412
+
413
+ parallel_options = [
414
+ :thread,
415
+ ]
416
+ o.on("--[no-]parallel=[thread]", parallel_options,
417
+ "Runs tests in parallel",
418
+ "(#{parallel_options.first})") do |parallel|
419
+ case parallel
420
+ when nil, :thread
421
+ @test_suite_runner_class = TestSuiteThreadRunner
422
+ else
423
+ @test_suite_runner_class = TestSuiteRunner
424
+ end
425
+ end
426
+
427
+ o.on("--n-workers=N", Integer,
428
+ "The number of parallelism",
429
+ "(#{TestSuiteRunner.n_workers})") do |n|
430
+ TestSuiteRunner.n_workers = n
431
+ end
432
+
396
433
  ADDITIONAL_OPTIONS.each do |option_builder|
397
434
  option_builder.call(self, o)
398
435
  end
@@ -437,7 +474,7 @@ module Test
437
474
  n = 1
438
475
  end
439
476
  i += 1
440
- keyword.sub(/^(.{#{n}})([A-Za-z]+)(?=\w*$)/, '\\1[\\2]')
477
+ keyword.sub(/^(.{#{n}})([A-Za-z-]+)(?=\w*$)/, '\\1[\\2]')
441
478
  end.join(", ")
442
479
  end
443
480
 
@@ -454,6 +491,10 @@ module Test
454
491
  if @stop_on_failure
455
492
  @runner_options[:listeners] << StopOnFailureListener.new
456
493
  end
494
+ if @gc_stress
495
+ @runner_options[:listeners] << GCStressListener.new
496
+ end
497
+ @runner_options[:test_suite_runner_class] = @test_suite_runner_class
457
498
  change_work_directory do
458
499
  runner.run(suite, @runner_options).passed?
459
500
  end
@@ -481,6 +522,15 @@ module Test
481
522
  @runner_options = @runner_options.merge(runner_options)
482
523
  end
483
524
 
525
+ def load_plain_text_config(file)
526
+ require "shellwords"
527
+ File.readlines(file, chomp: true).each do |line|
528
+ next if line.empty?
529
+ args = Shellwords.shellsplit(line)
530
+ @default_arguments.concat(args)
531
+ end
532
+ end
533
+
484
534
  private
485
535
  def default_runner
486
536
  runner = self.class.default_runner
@@ -572,10 +622,24 @@ module Test
572
622
  end
573
623
  end
574
624
  end
625
+
626
+ class GCStressListener
627
+ def attach_to_mediator(mediator)
628
+ mediator.add_listener(TestCase::STARTED) do |test|
629
+ GC.start
630
+ GC.stress = true
631
+ end
632
+
633
+ mediator.add_listener(TestCase::FINISHED) do |test|
634
+ GC.start
635
+ GC.stress = false
636
+ end
637
+ end
638
+ end
575
639
  end
576
640
  end
577
641
  end
578
642
 
579
- require "test/unit/runner/console"
580
- require "test/unit/runner/emacs"
581
- require "test/unit/runner/xml"
643
+ require_relative "runner/console"
644
+ require_relative "runner/emacs"
645
+ require_relative "runner/xml"
@@ -1,4 +1,4 @@
1
- require 'test/unit/collector'
1
+ require_relative '../collector'
2
2
 
3
3
  module Test
4
4
  module Unit
@@ -1,5 +1,5 @@
1
- require 'test/unit/testsuite'
2
- require 'test/unit/collector'
1
+ require_relative '../testsuite'
2
+ require_relative '../collector'
3
3
 
4
4
  module Test
5
5
  module Unit
@@ -1,7 +1,7 @@
1
1
  require 'pathname'
2
2
 
3
- require 'test/unit/testsuite'
4
- require 'test/unit/collector'
3
+ require_relative '../testsuite'
4
+ require_relative '../collector'
5
5
 
6
6
  module Test
7
7
  module Unit
@@ -39,7 +39,8 @@ module Test
39
39
  froms = @default_test_paths if froms.empty?
40
40
  froms = ["."] if froms.empty?
41
41
  test_suites = []
42
- already_gathered = find_test_cases
42
+ already_gathered = {}
43
+ find_test_cases(already_gathered)
43
44
  froms.each do |from|
44
45
  from = resolve_path(from)
45
46
  if from.directory?
@@ -66,12 +67,13 @@ module Test
66
67
  end
67
68
  end
68
69
 
69
- def find_test_cases(ignore=[])
70
+ def find_test_cases(already_gathered)
70
71
  test_cases = []
71
72
  TestCase::DESCENDANTS.each do |test_case|
72
- test_cases << test_case unless ignore.include?(test_case)
73
+ next if already_gathered.key?(test_case)
74
+ test_cases << test_case
75
+ already_gathered[test_case] = true
73
76
  end
74
- ignore.concat(test_cases)
75
77
  test_cases
76
78
  end
77
79
 
@@ -2,7 +2,7 @@
2
2
  # Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
3
3
  # License:: Ruby license.
4
4
 
5
- require 'test/unit/collector'
5
+ require_relative '../collector'
6
6
 
7
7
  module Test
8
8
  module Unit
@@ -7,7 +7,7 @@
7
7
 
8
8
  # just test!!! don't use it yet!!!
9
9
 
10
- require 'test/unit/collector'
10
+ require_relative '../collector'
11
11
 
12
12
  require 'rexml/document'
13
13
  require 'rexml/streamlistener'
@@ -1,4 +1,4 @@
1
- require 'test/unit/color'
1
+ require_relative 'color'
2
2
 
3
3
  module Test
4
4
  module Unit
@@ -1,4 +1,4 @@
1
- require "test/unit/data-sets"
1
+ require_relative "data-sets"
2
2
 
3
3
  module Test
4
4
  module Unit
@@ -4,7 +4,7 @@
4
4
  # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
5
5
  # License:: Ruby license.
6
6
 
7
- require 'test/unit/util/backtracefilter'
7
+ require_relative 'util/backtracefilter'
8
8
 
9
9
  module Test
10
10
  module Unit
@@ -32,7 +32,7 @@ module Test
32
32
  @inspected_actual = options[:inspected_actual]
33
33
  @user_message = options[:user_message]
34
34
  end
35
-
35
+
36
36
  # Returns a single character representation of a failure.
37
37
  def single_character_display
38
38
  SINGLE_CHARACTER
@@ -18,7 +18,7 @@ module Test
18
18
  return nil if match_data.nil?
19
19
  file, line_number, context = match_data.to_a[1..-1]
20
20
  line_number = line_number.to_i
21
- if /\Ain `(.+?)'/ =~ context
21
+ if /\Ain [`'](.+?)'/ =~ context
22
22
  method_name = $1
23
23
  if /\Ablock (?:\(.+?\) )?in / =~ method_name
24
24
  method_name = $POSTMATCH
@@ -71,7 +71,11 @@ module Test
71
71
  end
72
72
 
73
73
  def target_method?(method_name)
74
- @fault_method_name == method_name
74
+ return false if method_name.nil?
75
+ # method_name may be test_XXX or MyTest#test_XXX (Ruby >= 3.4).
76
+ return true if @fault_method_name == method_name
77
+ return true if method_name.end_with?("\##{@fault_method_name}")
78
+ false
75
79
  end
76
80
 
77
81
  def guess_indent_level(line)
@@ -1,4 +1,4 @@
1
- require 'test/unit/util/backtracefilter'
1
+ require_relative 'util/backtracefilter'
2
2
 
3
3
  module Test
4
4
  module Unit
@@ -1,4 +1,4 @@
1
- require 'test/unit/util/backtracefilter'
1
+ require_relative 'util/backtracefilter'
2
2
 
3
3
  module Test
4
4
  module Unit
@@ -1,4 +1,4 @@
1
- require 'test/unit/util/backtracefilter'
1
+ require_relative 'util/backtracefilter'
2
2
 
3
3
  module Test
4
4
  module Unit
@@ -180,7 +180,7 @@ module Test
180
180
  end
181
181
  end
182
182
 
183
- def priority_setup
183
+ def priority_setup(&_)
184
184
  return unless Priority.enabled?
185
185
  Checker.new(self).setup
186
186
  end
@@ -1,14 +1,15 @@
1
- # Copyright (C) 2008-2017 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2008-2023 Sutou Kouhei <kou@clear-code.com>
2
2
 
3
3
  module Test
4
4
  module Unit
5
5
  AutoRunner.register_runner(:console) do |auto_runner|
6
- require 'test/unit/ui/console/testrunner'
6
+ require_relative '../ui/console/testrunner'
7
7
  Test::Unit::UI::Console::TestRunner
8
8
  end
9
9
 
10
10
  AutoRunner.setup_option do |auto_runner, opts|
11
- require 'test/unit/ui/console/outputlevel'
11
+ require_relative '../ui/console/outputlevel'
12
+ require_relative '../ui/console/testrunner'
12
13
 
13
14
  output_levels = [
14
15
  ["silent", UI::Console::OutputLevel::SILENT],
@@ -18,7 +19,7 @@ module Test
18
19
  ["verbose", UI::Console::OutputLevel::VERBOSE],
19
20
  ]
20
21
  opts.on('-v', '--verbose=[LEVEL]', output_levels,
21
- "Set the output level (default is verbose).",
22
+ "Set the output level (default is normal).",
22
23
  "(#{auto_runner.keyword_display(output_levels)})") do |level|
23
24
  level ||= output_levels.assoc("verbose")[1]
24
25
  auto_runner.runner_options[:output_level] = level
@@ -51,6 +52,17 @@ module Test
51
52
  auto_runner.runner_options[:progress_row_max] = max
52
53
  end
53
54
 
55
+ progress_styles = [
56
+ ["inplace", :inplace],
57
+ ["mark", :mark],
58
+ ["fault-only", :fault_only],
59
+ ]
60
+ opts.on("--progress-style=STYLE", progress_styles,
61
+ "Uses STYLE as progress style",
62
+ "(#{auto_runner.keyword_display(progress_styles)})") do |style|
63
+ auto_runner.runner_options[:progress_style] = style
64
+ end
65
+
54
66
  opts.on("--no-show-detail-immediately",
55
67
  "Shows not passed test details immediately.",
56
68
  "(default is yes)") do |boolean|
@@ -62,6 +74,13 @@ module Test
62
74
  "(default is yes for tty output, no otherwise)") do |boolean|
63
75
  auto_runner.runner_options[:reverse_output] = boolean
64
76
  end
77
+
78
+ n_report_slow_tests = UI::Console::TestRunner::N_REPORT_SLOW_TESTS
79
+ opts.on("--[no-]report-slow-tests",
80
+ "Shows the top #{n_report_slow_tests} slow tests in the summary output",
81
+ "(false)") do |boolean|
82
+ auto_runner.runner_options[:report_slow_tests] = boolean
83
+ end
65
84
  end
66
85
  end
67
86
  end
@@ -1,7 +1,7 @@
1
1
  module Test
2
2
  module Unit
3
3
  AutoRunner.register_runner(:emacs) do |auto_runner|
4
- require 'test/unit/ui/emacs/testrunner'
4
+ require_relative '../ui/emacs/testrunner'
5
5
  Test::Unit::UI::Emacs::TestRunner
6
6
  end
7
7
  end
@@ -1,7 +1,7 @@
1
1
  module Test
2
2
  module Unit
3
3
  AutoRunner.register_runner(:xml) do |auto_runner|
4
- require 'test/unit/ui/xml/testrunner'
4
+ require_relative '../ui/xml/testrunner'
5
5
  Test::Unit::UI::XML::TestRunner
6
6
  end
7
7
 
@@ -0,0 +1,59 @@
1
+ #--
2
+ #
3
+ # Author:: Tsutomu Katsube.
4
+ # Copyright:: Copyright (c) 2024 Tsutomu Katsube. All rights reserved.
5
+ # License:: Ruby license.
6
+
7
+ module Test
8
+ module Unit
9
+ class SubTestResult
10
+ attr_accessor :stop_tag
11
+
12
+ def initialize(parent_test_result)
13
+ @parent_test_result = parent_test_result
14
+ @stop_tag = nil
15
+ end
16
+
17
+ def add_run(result=self)
18
+ @parent_test_result.add_run(result)
19
+ end
20
+
21
+ def add_pass
22
+ @parent_test_result.add_pass
23
+ end
24
+
25
+ # Records an individual assertion.
26
+ def add_assertion
27
+ @parent_test_result.add_assertion
28
+ end
29
+
30
+ def add_error(error)
31
+ @parent_test_result.add_error(error)
32
+ end
33
+
34
+ def add_failure(failure)
35
+ @parent_test_result.add_failure(failure)
36
+ end
37
+
38
+ def add_pending(pending)
39
+ @parent_test_result.add_pending(pending)
40
+ end
41
+
42
+ def add_omission(omission)
43
+ @parent_test_result.add_omission(omission)
44
+ end
45
+
46
+ def add_notification(notification)
47
+ @parent_test_result.add_notification(notification)
48
+ end
49
+
50
+ def passed?
51
+ @parent_test_result.passed?
52
+ end
53
+
54
+ def stop
55
+ throw @stop_tag
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,16 @@
1
+ #--
2
+ #
3
+ # Author:: Tsutomu Katsube.
4
+ # Copyright:: Copyright (c) 2025 Tsutomu Katsube. All rights reserved.
5
+ # License:: Ruby license.
6
+
7
+ module Test
8
+ module Unit
9
+ class TestRunContext
10
+ attr_reader :runner_class
11
+ def initialize(runner_class)
12
+ @runner_class = runner_class
13
+ end
14
+ end
15
+ end
16
+ end
@@ -5,7 +5,7 @@
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"
8
+ require_relative "data-sets"
9
9
 
10
10
  module Test
11
11
  module Unit
@@ -0,0 +1,130 @@
1
+ #--
2
+ #
3
+ # Author:: Nathaniel Talbott.
4
+ # Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
5
+ # Copyright:: Copyright (c) 2008-2011 Kouhei Sutou. All rights reserved.
6
+ # Copyright:: Copyright (c) 2024 Tsutomu Katsube. All rights reserved.
7
+ # License:: Ruby license.
8
+
9
+ require "etc"
10
+
11
+ require_relative "test-run-context"
12
+
13
+ module Test
14
+ module Unit
15
+ class TestSuiteRunner
16
+ @n_workers = Etc.respond_to?(:nprocessors) ? Etc.nprocessors : 1
17
+ class << self
18
+ def run_all_tests
19
+ yield(TestRunContext.new(self))
20
+ end
21
+
22
+ def n_workers
23
+ @n_workers
24
+ end
25
+
26
+ def n_workers=(n)
27
+ @n_workers = n
28
+ end
29
+ end
30
+
31
+ def initialize(test_suite)
32
+ @test_suite = test_suite
33
+ end
34
+
35
+ def run(result, run_context: nil, &progress_block)
36
+ yield(TestSuite::STARTED, @test_suite.name)
37
+ yield(TestSuite::STARTED_OBJECT, @test_suite)
38
+ run_startup(result)
39
+ run_tests(result, run_context: run_context, &progress_block)
40
+ ensure
41
+ begin
42
+ run_shutdown(result)
43
+ ensure
44
+ yield(TestSuite::FINISHED, @test_suite.name)
45
+ yield(TestSuite::FINISHED_OBJECT, @test_suite)
46
+ end
47
+ end
48
+
49
+ private
50
+ def run_startup(result)
51
+ test_case = @test_suite.test_case
52
+ return if test_case.nil? or !test_case.respond_to?(:startup)
53
+ begin
54
+ test_case.startup
55
+ rescue Exception
56
+ raise unless handle_exception($!, result)
57
+ end
58
+ end
59
+
60
+ def run_tests(result, run_context: nil, &progress_block)
61
+ @test_suite.tests.each do |test|
62
+ run_test(test, result, run_context: run_context, &progress_block)
63
+ end
64
+ end
65
+
66
+ def run_test(test, result, run_context: nil)
67
+ finished_is_yielded = false
68
+ finished_object_is_yielded = false
69
+ previous_event_name = nil
70
+ event_listener = lambda do |event_name, *args|
71
+ case previous_event_name
72
+ when Test::Unit::TestCase::STARTED
73
+ if event_name != Test::Unit::TestCase::STARTED_OBJECT
74
+ yield(Test::Unit::TestCase::STARTED_OBJECT, test)
75
+ end
76
+ when Test::Unit::TestCase::FINISHED
77
+ if event_name != Test::Unit::TestCase::FINISHED_OBJECT
78
+ yield(Test::Unit::TestCase::FINISHED_OBJECT, test)
79
+ end
80
+ finished_object_is_yielded = true
81
+ end
82
+
83
+ case event_name
84
+ when Test::Unit::TestCase::STARTED
85
+ finished_is_yielded = false
86
+ finished_object_is_yielded = false
87
+ when Test::Unit::TestCase::FINISHED
88
+ finished_is_yielded = true
89
+ end
90
+
91
+ previous_event_name = event_name
92
+ yield(event_name, *args)
93
+ end
94
+
95
+ if test.method(:run).arity == -2
96
+ test.run(result, run_context: run_context, &event_listener)
97
+ else
98
+ # For backward compatibility. There are scripts that overrides
99
+ # Test::Unit::TestCase#run without keyword arguments.
100
+ test.run(result, &event_listener)
101
+ end
102
+
103
+ if finished_is_yielded and not finished_object_is_yielded
104
+ yield(Test::Unit::TestCase::FINISHED_OBJECT, test)
105
+ end
106
+ end
107
+
108
+ def run_shutdown(result)
109
+ test_case = @test_suite.test_case
110
+ return if test_case.nil? or !test_case.respond_to?(:shutdown)
111
+ begin
112
+ test_case.shutdown
113
+ rescue Exception
114
+ raise unless handle_exception($!, result)
115
+ end
116
+ end
117
+
118
+ def handle_exception(exception, result)
119
+ case exception
120
+ when *ErrorHandler::PASS_THROUGH_EXCEPTIONS
121
+ false
122
+ else
123
+ result.add_error(Error.new(@test_suite.test_case.name, exception))
124
+ true
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+