diff options
Diffstat (limited to 'activesupport/test/rescuable_test.rb')
-rw-r--r-- | activesupport/test/rescuable_test.rb | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/activesupport/test/rescuable_test.rb b/activesupport/test/rescuable_test.rb new file mode 100644 index 0000000000..b1b8a25c5b --- /dev/null +++ b/activesupport/test/rescuable_test.rb @@ -0,0 +1,176 @@ +# frozen_string_literal: true + +require "abstract_unit" + +class WraithAttack < StandardError +end + +class MadRonon < StandardError +end + +class CoolError < StandardError +end + +module WeirdError + def self.===(other) + Exception === other && other.respond_to?(:weird?) + end +end + +class Stargate + # Nest this so the 'NuclearExplosion' handler needs a lexical const_get + # to find it. + class NuclearExplosion < StandardError; end + + attr_accessor :result + + include ActiveSupport::Rescuable + + rescue_from WraithAttack, with: :sos_first + + rescue_from WraithAttack, with: :sos + + rescue_from "NuclearExplosion" do + @result = "alldead" + end + + rescue_from MadRonon do |e| + @result = e.message + end + + rescue_from WeirdError do + @result = "weird" + end + + def dispatch(method) + send(method) + rescue Exception => e + unless rescue_with_handler(e) + @result = "unhandled" + end + end + + def attack + raise WraithAttack + end + + def nuke + raise NuclearExplosion + end + + def ronanize + raise MadRonon.new("dex") + end + + def crash + raise "unhandled RuntimeError" + end + + def looped_crash + ex1 = StandardError.new("error 1") + ex2 = StandardError.new("error 2") + begin + begin + raise ex1 + rescue + # sets the cause on ex2 to be ex1 + raise ex2 + end + rescue + # sets the cause on ex1 to be ex2 + raise ex1 + end + end + + def fall_back_to_cause + # This exception is the cause and has a handler. + ronanize + rescue + # This is the exception we'll handle that doesn't have a cause. + raise "unhandled RuntimeError with a handleable cause" + end + + def weird + StandardError.new.tap do |exc| + def exc.weird? + true + end + + raise exc + end + end + + def sos + @result = "killed" + end + + def sos_first + @result = "sos_first" + end +end + +class CoolStargate < Stargate + attr_accessor :result + + include ActiveSupport::Rescuable + + rescue_from CoolError, with: :sos_cool_error + + def sos_cool_error + @result = "sos_cool_error" + end +end + +class RescuableTest < ActiveSupport::TestCase + def setup + @stargate = Stargate.new + @cool_stargate = CoolStargate.new + end + + def test_rescue_from_with_method + @stargate.dispatch :attack + assert_equal "killed", @stargate.result + end + + def test_rescue_from_with_block + @stargate.dispatch :nuke + assert_equal "alldead", @stargate.result + end + + def test_rescue_from_with_block_with_args + @stargate.dispatch :ronanize + assert_equal "dex", @stargate.result + end + + def test_rescue_from_error_dispatchers_with_case_operator + @stargate.dispatch :weird + assert_equal "weird", @stargate.result + end + + def test_rescues_defined_later_are_added_at_end_of_the_rescue_handlers_array + expected = ["WraithAttack", "WraithAttack", "NuclearExplosion", "MadRonon", "WeirdError"] + result = @stargate.send(:rescue_handlers).collect(&:first) + assert_equal expected, result + end + + def test_children_should_inherit_rescue_definitions_from_parents_and_child_rescue_should_be_appended + expected = ["WraithAttack", "WraithAttack", "NuclearExplosion", "MadRonon", "WeirdError", "CoolError"] + result = @cool_stargate.send(:rescue_handlers).collect(&:first) + assert_equal expected, result + end + + def test_rescue_falls_back_to_exception_cause + @stargate.dispatch :fall_back_to_cause + assert_equal "dex", @stargate.result + end + + def test_unhandled_exceptions + @stargate.dispatch(:crash) + assert_equal "unhandled", @stargate.result + end + + def test_rescue_handles_loops_in_exception_cause_chain + @stargate.dispatch :looped_crash + assert_equal "unhandled", @stargate.result + end +end |