diff options
author | claudiob <claudiob@gmail.com> | 2014-10-16 16:21:24 -0700 |
---|---|---|
committer | claudiob <claudiob@gmail.com> | 2015-01-02 15:31:55 -0800 |
commit | 2386daabe7f8c979b453010dc0de3e1f6bbf859d (patch) | |
tree | 74ab7a4ffc32cda7126e3ce8950d21af0c4c4b90 /activesupport/test | |
parent | 93dd5028a0cd0363d9f4bfc97d9ce70f0f3e88c8 (diff) | |
download | rails-2386daabe7f8c979b453010dc0de3e1f6bbf859d.tar.gz rails-2386daabe7f8c979b453010dc0de3e1f6bbf859d.tar.bz2 rails-2386daabe7f8c979b453010dc0de3e1f6bbf859d.zip |
Throw :abort halts default CallbackChains
This commit changes arguments and default value of CallbackChain's :terminator
option.
After this commit, Chains of callbacks defined **without** an explicit
`:terminator` option will be halted as soon as a `before_` callback throws
`:abort`.
Chains of callbacks defined **with** a `:terminator` option will maintain their
existing behavior of halting as soon as a `before_` callback matches the
terminator's expectation. For instance, ActiveModel's callbacks will still
halt the chain when a `before_` callback returns `false`.
Diffstat (limited to 'activesupport/test')
-rw-r--r-- | activesupport/test/callbacks_test.rb | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/activesupport/test/callbacks_test.rb b/activesupport/test/callbacks_test.rb index d19e5fd6e7..73b00e80f6 100644 --- a/activesupport/test/callbacks_test.rb +++ b/activesupport/test/callbacks_test.rb @@ -511,8 +511,6 @@ module CallbacksTest set_callback :save, :before, :third set_callback :save, :after, :first set_callback :save, :around, :around_it - set_callback :save, :after, :second - set_callback :save, :around, :around_it set_callback :save, :after, :third end @@ -552,16 +550,27 @@ module CallbacksTest end class CallbackTerminator < AbstractCallbackTerminator - define_callbacks :save, terminator: ->(_,result) { result == :halt } + define_callbacks :save, terminator: ->(_, result_lambda) { result_lambda.call == :halt } set_save_callbacks end class CallbackTerminatorSkippingAfterCallbacks < AbstractCallbackTerminator - define_callbacks :save, terminator: ->(_,result) { result == :halt }, + define_callbacks :save, terminator: ->(_, result_lambda) { result_lambda.call == :halt }, skip_after_callbacks_if_terminated: true set_save_callbacks end + class CallbackDefaultTerminator < AbstractCallbackTerminator + define_callbacks :save + + def second + @history << "second" + throw(:abort) + end + + set_save_callbacks + end + class CallbackObject def before(caller) caller.record << "before" @@ -701,7 +710,7 @@ module CallbacksTest def test_termination_skips_following_before_and_around_callbacks terminator = CallbackTerminator.new terminator.save - assert_equal ["first", "second", "third", "second", "first"], terminator.history + assert_equal ["first", "second", "third", "first"], terminator.history end def test_termination_invokes_hook @@ -725,6 +734,26 @@ module CallbacksTest end end + class CallbackDefaultTerminatorTest < ActiveSupport::TestCase + def test_default_termination + terminator = CallbackDefaultTerminator.new + terminator.save + assert_equal ["first", "second", "third", "first"], terminator.history + end + + def test_default_termination_invokes_hook + terminator = CallbackDefaultTerminator.new + terminator.save + assert_equal :second, terminator.halted + end + + def test_block_never_called_if_abort_is_thrown + obj = CallbackDefaultTerminator.new + obj.save + assert !obj.saved + end + end + class HyphenatedKeyTest < ActiveSupport::TestCase def test_save obj = HyphenatedCallbacks.new |