mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Add test for :skip_after_callbacks_if_terminated
`define_callbacks` from `ActiveSupport::Callbacks` accepts the `:skip_after_callbacks_if_terminated` option since #4866 but the option is not tested anywhere. This commit adds tests and fixes documentation for the option, making it clear that halting a callback chain only stops following `before_` and `around_` callbacks by default.
This commit is contained in:
parent
7607687c91
commit
8c1889c926
2 changed files with 38 additions and 19 deletions
|
@ -659,16 +659,17 @@ module ActiveSupport
|
||||||
# ===== Options
|
# ===== Options
|
||||||
#
|
#
|
||||||
# * <tt>:terminator</tt> - Determines when a before filter will halt the
|
# * <tt>:terminator</tt> - Determines when a before filter will halt the
|
||||||
# callback chain, preventing following callbacks from being called and
|
# callback chain, preventing following before and around callbacks from
|
||||||
# the event from being triggered. This should be a lambda to be executed.
|
# being called and the event from being triggered.
|
||||||
|
# This should be a lambda to be executed.
|
||||||
# The current object and the return result of the callback will be called
|
# The current object and the return result of the callback will be called
|
||||||
# with the lambda.
|
# with the lambda.
|
||||||
#
|
#
|
||||||
# define_callbacks :validate, terminator: ->(target, result) { result == false }
|
# define_callbacks :validate, terminator: ->(target, result) { result == false }
|
||||||
#
|
#
|
||||||
# In this example, if any before validate callbacks returns +false+,
|
# In this example, if any before validate callbacks returns +false+,
|
||||||
# other callbacks are not executed. Defaults to +false+, meaning no value
|
# any successive before and around callback is not executed.
|
||||||
# halts the chain.
|
# Defaults to +false+, meaning no value halts the chain.
|
||||||
#
|
#
|
||||||
# * <tt>:skip_after_callbacks_if_terminated</tt> - Determines if after
|
# * <tt>:skip_after_callbacks_if_terminated</tt> - Determines if after
|
||||||
# callbacks should be terminated by the <tt>:terminator</tt> option. By
|
# callbacks should be terminated by the <tt>:terminator</tt> option. By
|
||||||
|
|
|
@ -49,7 +49,7 @@ module CallbacksTest
|
||||||
def self.before(model)
|
def self.before(model)
|
||||||
model.history << [:before_save, :class]
|
model.history << [:before_save, :class]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.after(model)
|
def self.after(model)
|
||||||
model.history << [:after_save, :class]
|
model.history << [:after_save, :class]
|
||||||
end
|
end
|
||||||
|
@ -501,21 +501,20 @@ module CallbacksTest
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class CallbackTerminator
|
class AbstractCallbackTerminator
|
||||||
include ActiveSupport::Callbacks
|
include ActiveSupport::Callbacks
|
||||||
|
|
||||||
define_callbacks :save, :terminator => ->(_,result) { result == :halt }
|
def self.set_save_callbacks
|
||||||
|
set_callback :save, :before, :first
|
||||||
set_callback :save, :before, :first
|
set_callback :save, :before, :second
|
||||||
set_callback :save, :before, :second
|
set_callback :save, :around, :around_it
|
||||||
set_callback :save, :around, :around_it
|
set_callback :save, :before, :third
|
||||||
set_callback :save, :before, :third
|
set_callback :save, :after, :first
|
||||||
set_callback :save, :after, :first
|
set_callback :save, :around, :around_it
|
||||||
set_callback :save, :around, :around_it
|
set_callback :save, :after, :second
|
||||||
set_callback :save, :after, :second
|
set_callback :save, :around, :around_it
|
||||||
set_callback :save, :around, :around_it
|
set_callback :save, :after, :third
|
||||||
set_callback :save, :after, :third
|
end
|
||||||
|
|
||||||
|
|
||||||
attr_reader :history, :saved, :halted
|
attr_reader :history, :saved, :halted
|
||||||
def initialize
|
def initialize
|
||||||
|
@ -552,6 +551,17 @@ module CallbacksTest
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class CallbackTerminator < AbstractCallbackTerminator
|
||||||
|
define_callbacks :save, terminator: ->(_,result) { result == :halt }
|
||||||
|
set_save_callbacks
|
||||||
|
end
|
||||||
|
|
||||||
|
class CallbackTerminatorSkippingAfterCallbacks < AbstractCallbackTerminator
|
||||||
|
define_callbacks :save, terminator: ->(_,result) { result == :halt },
|
||||||
|
skip_after_callbacks_if_terminated: true
|
||||||
|
set_save_callbacks
|
||||||
|
end
|
||||||
|
|
||||||
class CallbackObject
|
class CallbackObject
|
||||||
def before(caller)
|
def before(caller)
|
||||||
caller.record << "before"
|
caller.record << "before"
|
||||||
|
@ -688,7 +698,7 @@ module CallbacksTest
|
||||||
end
|
end
|
||||||
|
|
||||||
class CallbackTerminatorTest < ActiveSupport::TestCase
|
class CallbackTerminatorTest < ActiveSupport::TestCase
|
||||||
def test_termination
|
def test_termination_skips_following_before_and_around_callbacks
|
||||||
terminator = CallbackTerminator.new
|
terminator = CallbackTerminator.new
|
||||||
terminator.save
|
terminator.save
|
||||||
assert_equal ["first", "second", "third", "second", "first"], terminator.history
|
assert_equal ["first", "second", "third", "second", "first"], terminator.history
|
||||||
|
@ -707,6 +717,14 @@ module CallbacksTest
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class CallbackTerminatorSkippingAfterCallbacksTest < ActiveSupport::TestCase
|
||||||
|
def test_termination_skips_after_callbacks
|
||||||
|
terminator = CallbackTerminatorSkippingAfterCallbacks.new
|
||||||
|
terminator.save
|
||||||
|
assert_equal ["first", "second"], terminator.history
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class HyphenatedKeyTest < ActiveSupport::TestCase
|
class HyphenatedKeyTest < ActiveSupport::TestCase
|
||||||
def test_save
|
def test_save
|
||||||
obj = HyphenatedCallbacks.new
|
obj = HyphenatedCallbacks.new
|
||||||
|
|
Loading…
Reference in a new issue