diff options
Diffstat (limited to 'activesupport/lib/active_support/testing/setup_and_teardown.rb')
-rw-r--r-- | activesupport/lib/active_support/testing/setup_and_teardown.rb | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/activesupport/lib/active_support/testing/setup_and_teardown.rb b/activesupport/lib/active_support/testing/setup_and_teardown.rb new file mode 100644 index 0000000000..1639462fae --- /dev/null +++ b/activesupport/lib/active_support/testing/setup_and_teardown.rb @@ -0,0 +1,127 @@ +module ActiveSupport + module Testing + module SetupAndTeardown + def self.included(base) + base.extend ClassMethods + + begin + require 'mocha' + base.alias_method_chain :run, :callbacks_and_mocha + rescue LoadError + base.alias_method_chain :run, :callbacks + end + end + + module ClassMethods + def setup(*method_names, &block) + method_names << block if block_given? + (@setup_callbacks ||= []).concat method_names + end + + def teardown(*method_names, &block) + method_names << block if block_given? + (@teardown_callbacks ||= []).concat method_names + end + + def setup_callback_chain + @setup_callbacks ||= [] + + if superclass.respond_to?(:setup_callback_chain) + superclass.setup_callback_chain + @setup_callbacks + else + @setup_callbacks + end + end + + def teardown_callback_chain + @teardown_callbacks ||= [] + + if superclass.respond_to?(:teardown_callback_chain) + superclass.teardown_callback_chain + @teardown_callbacks + else + @teardown_callbacks + end + end + end + + # This redefinition is unfortunate but test/unit shows us no alternative. + def run_with_callbacks(result) #:nodoc: + return if @method_name.to_s == "default_test" + + yield(Test::Unit::TestCase::STARTED, name) + @_result = result + begin + run_callbacks :setup + setup + __send__(@method_name) + rescue Test::Unit::AssertionFailedError => e + add_failure(e.message, e.backtrace) + rescue *Test::Unit::TestCase::PASSTHROUGH_EXCEPTIONS + raise + rescue Exception + add_error($!) + ensure + begin + teardown + run_callbacks :teardown, :reverse_each + rescue Test::Unit::AssertionFailedError => e + add_failure(e.message, e.backtrace) + rescue *Test::Unit::TestCase::PASSTHROUGH_EXCEPTIONS + raise + rescue Exception + add_error($!) + end + end + result.add_run + yield(Test::Unit::TestCase::FINISHED, name) + end + + # Doubly unfortunate: mocha does the same so we have to hax their hax. + def run_with_callbacks_and_mocha(result) + return if @method_name.to_s == "default_test" + + yield(Test::Unit::TestCase::STARTED, name) + @_result = result + begin + mocha_setup + begin + run_callbacks :setup + setup + __send__(@method_name) + mocha_verify { add_assertion } + rescue Mocha::ExpectationError => e + add_failure(e.message, e.backtrace) + rescue Test::Unit::AssertionFailedError => e + add_failure(e.message, e.backtrace) + rescue StandardError, ScriptError + add_error($!) + ensure + begin + teardown + run_callbacks :teardown, :reverse_each + rescue Test::Unit::AssertionFailedError => e + add_failure(e.message, e.backtrace) + rescue StandardError, ScriptError + add_error($!) + end + end + ensure + mocha_teardown + end + result.add_run + yield(Test::Unit::TestCase::FINISHED, name) + end + + protected + def run_callbacks(kind, enumerator = :each) + self.class.send("#{kind}_callback_chain").send(enumerator) do |callback| + case callback + when Proc; callback.call(self) + when String, Symbol; send!(callback) + else raise ArgumentError, "Unrecognized callback #{callback.inspect}" + end + end + end + end + end +end |