1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
#--
#
# Author:: Nathaniel Talbott.
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
# License:: Ruby license.
require_relative '../util/observable'
require_relative '../testresult'
require_relative '../worker-context'
module Test
module Unit
module UI
# Provides an interface to write any given UI against,
# hopefully making it easy to write new UIs.
class TestRunnerMediator
RESET = name + "::RESET"
STARTED = name + "::STARTED"
FINISHED = name + "::FINISHED"
include Util::Observable
# Creates a new TestRunnerMediator initialized to run
# the passed suite.
def initialize(suite, options={})
@suite = suite
@options = options
@test_suite_runner_class = @options[:test_suite_runner_class]
@test_suite_runner_class ||= TestSuiteRunner
end
# Runs the suite the TestRunnerMediator was created
# with.
def run
AutoRunner.need_auto_run = false
result = create_result
options = @options.dup
# We should not keep @suite in @options because @options may
# be live longer than this instance. For example,
# AutoRunner's @runner_options is @options in this instance
# and AutoRunner is live longer than this instance. We can
# dup @options to avoid @suite's life time longer.
options[:test_suite] = @suite
options[:event_listener] = lambda do |channel, value|
notify_listeners(channel, value)
end
Test::Unit.run_at_start_hooks
start_time = Time.now
begin
with_listener(result) do
@test_suite_runner_class.run_all_tests(result, options) do |run_context|
catch do |stop_tag|
result.stop_tag = stop_tag
notify_listeners(RESET, @suite.size)
notify_listeners(STARTED, result)
run_suite(result, run_context: run_context)
end
end
end
ensure
elapsed_time = Time.now - start_time
notify_listeners(FINISHED, elapsed_time)
end
Test::Unit.run_at_exit_hooks
result
end
# Just for backward compatibility for NetBeans.
# NetBeans should not use monkey patching. NetBeans
# should use runner change public API.
#
# See GitHub#38
# https://github.com/test-unit/test-unit/issues/38
def run_suite(result=nil, run_context: nil)
if result.nil?
run
else
worker_context = WorkerContext.new(nil, run_context, result)
@suite.run(worker_context) do |channel, value|
notify_listeners(channel, value)
end
end
end
private
# A factory method to create the result the mediator
# should run with. Can be overridden by subclasses if
# one wants to use a different result.
def create_result
TestResult.new
end
def measure_time
begin_time = Time.now
yield
Time.now - begin_time
end
def with_listener(result)
finished_listener = result.add_listener(TestResult::FINISHED) do |*args|
notify_listeners(TestResult::FINISHED, *args)
end
changed_listener = result.add_listener(TestResult::CHANGED) do |*args|
notify_listeners(TestResult::CHANGED, *args)
end
pass_assertion_listener = result.add_listener(TestResult::PASS_ASSERTION) do |*args|
notify_listeners(TestResult::PASS_ASSERTION, *args)
end
fault_listener = result.add_listener(TestResult::FAULT) do |*args|
notify_listeners(TestResult::FAULT, *args)
end
begin
yield
ensure
result.remove_listener(TestResult::FAULT, fault_listener)
result.remove_listener(TestResult::CHANGED, changed_listener)
result.remove_listener(TestResult::FINISHED, finished_listener)
result.remove_listener(TestResult::PASS_ASSERTION,
pass_assertion_listener)
end
end
end
end
end
end
|