diff options
author | yugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-08-25 15:02:05 +0000 |
---|---|---|
committer | yugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-08-25 15:02:05 +0000 |
commit | 0dc342de848a642ecce8db697b8fecd83a63e117 (patch) | |
tree | 2b7ed4724aff1f86073e4740134bda9c4aac1a39 /trunk/lib/test/unit/testcase.rb | |
parent | ef70cf7138ab8034b5b806f466e4b484b24f0f88 (diff) |
added tag v1_9_0_4
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_9_0_4@18845 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'trunk/lib/test/unit/testcase.rb')
-rw-r--r-- | trunk/lib/test/unit/testcase.rb | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/trunk/lib/test/unit/testcase.rb b/trunk/lib/test/unit/testcase.rb new file mode 100644 index 0000000000..3cf80d2256 --- /dev/null +++ b/trunk/lib/test/unit/testcase.rb @@ -0,0 +1,163 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/assertions' +require 'test/unit/failure' +require 'test/unit/error' +require 'test/unit/testsuite' +require 'test/unit/assertionfailederror' +require 'test/unit/util/backtracefilter' + +module Test + module Unit + + # Ties everything together. If you subclass and add your own + # test methods, it takes care of making them into tests and + # wrapping those tests into a suite. It also does the + # nitty-gritty of actually running an individual test and + # collecting its results into a Test::Unit::TestResult object. + class TestCase + include Assertions + include Util::BacktraceFilter + + attr_reader :method_name + + STARTED = name + "::STARTED" + FINISHED = name + "::FINISHED" + + ## + # These exceptions are not caught by #run. + + PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, Interrupt, + SystemExit] + + DECENDANT_CLASSES = [] + def self.inherited(decendant) + DECENDANT_CLASSES << decendant + end + + # Creates a new instance of the fixture for running the + # test represented by test_method_name. + def initialize(test_method_name) + unless(respond_to?(test_method_name) && method(test_method_name).arity == 0) + throw :invalid_test + end + @method_name = test_method_name + @test_passed = true + end + + # Rolls up all of the test* methods in the fixture into + # one suite, creating a new instance of the fixture for + # each method. + def self.suite + method_names = public_instance_methods(true).map { |m| m.to_s } + tests = method_names.delete_if {|method_name| method_name !~ /^test./} + suite = TestSuite.new(name) + tests.sort.each do + |test| + catch(:invalid_test) do + suite << new(test) + end + end + if (suite.empty?) + catch(:invalid_test) do + suite << new(:default_test) + end + end + return suite + end + + # Runs the individual test method represented by this + # instance of the fixture, collecting statistics, failures + # and errors in result. + def run(result) + yield(STARTED, name) + @_result = result + begin + setup + __send__(@method_name) + rescue AssertionFailedError => e + add_failure(e.message, e.backtrace) + rescue Exception + raise if PASSTHROUGH_EXCEPTIONS.include? $!.class + add_error($!) + ensure + begin + teardown + rescue AssertionFailedError => e + add_failure(e.message, e.backtrace) + rescue Exception + raise if PASSTHROUGH_EXCEPTIONS.include? $!.class + add_error($!) + end + end + result.add_run + yield(FINISHED, name) + end + + # Called before every test method runs. Can be used + # to set up fixture information. + def setup + end + + # Called after every test method runs. Can be used to tear + # down fixture information. + def teardown + end + + def default_test + flunk("No tests were specified") + end + + # Returns whether this individual test passed or + # not. Primarily for use in teardown so that artifacts + # can be left behind if the test fails. + def passed? + return @test_passed + end + private :passed? + + def size # :nodoc: + 1 + end + + def add_assertion # :nodoc: + @_result.add_assertion + end + private :add_assertion + + def add_failure(message, all_locations=caller()) # :nodoc: + @test_passed = false + @_result.add_failure(Failure.new(name, filter_backtrace(all_locations), message)) + end + private :add_failure + + def add_error(exception) # :nodoc: + @test_passed = false + @_result.add_error(Error.new(name, exception)) + end + private :add_error + + # Returns a human-readable name for the specific test that + # this instance of TestCase represents. + def name + "#{@method_name}(#{self.class.name})" + end + + # Overridden to return #name. + def to_s + name + end + + # It's handy to be able to compare TestCase instances. + def ==(other) + return false unless(other.kind_of?(self.class)) + return false unless(@method_name == other.method_name) + self.class == other.class + end + end + end +end |