2017-07-16 13:11:16 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2009-12-28 19:15:39 -05:00
|
|
|
require "cases/helper"
|
|
|
|
|
|
|
|
class CallbacksTest < ActiveModel::TestCase
|
|
|
|
class CallbackValidator
|
|
|
|
def around_create(model)
|
|
|
|
model.callbacks << :before_around_create
|
|
|
|
yield
|
|
|
|
model.callbacks << :after_around_create
|
2014-12-14 23:16:38 -05:00
|
|
|
false
|
2009-12-28 19:15:39 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class ModelCallbacks
|
|
|
|
attr_reader :callbacks
|
|
|
|
extend ActiveModel::Callbacks
|
|
|
|
|
|
|
|
define_model_callbacks :create
|
2013-05-01 20:10:06 -04:00
|
|
|
define_model_callbacks :initialize, only: :after
|
|
|
|
define_model_callbacks :multiple, only: [:before, :around]
|
|
|
|
define_model_callbacks :empty, only: []
|
2009-12-28 19:15:39 -05:00
|
|
|
|
|
|
|
before_create :before_create
|
|
|
|
around_create CallbackValidator.new
|
|
|
|
|
|
|
|
after_create do |model|
|
|
|
|
model.callbacks << :after_create
|
2014-12-14 23:16:38 -05:00
|
|
|
false
|
2009-12-28 19:15:39 -05:00
|
|
|
end
|
|
|
|
|
2017-01-08 05:45:58 -05:00
|
|
|
after_create { |model| model.callbacks << :final_callback }
|
2009-12-28 19:15:39 -05:00
|
|
|
|
2014-12-14 23:16:38 -05:00
|
|
|
def initialize(options = {})
|
|
|
|
@callbacks = []
|
|
|
|
@valid = options[:valid]
|
2014-12-08 09:53:24 -05:00
|
|
|
@before_create_returns = options.fetch(:before_create_returns, true)
|
|
|
|
@before_create_throws = options[:before_create_throws]
|
2009-12-28 19:15:39 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def before_create
|
|
|
|
@callbacks << :before_create
|
2014-12-08 09:53:24 -05:00
|
|
|
throw(@before_create_throws) if @before_create_throws
|
2014-12-14 23:16:38 -05:00
|
|
|
@before_create_returns
|
2009-12-28 19:15:39 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def create
|
2011-01-09 13:15:05 -05:00
|
|
|
run_callbacks :create do
|
2009-12-28 19:15:39 -05:00
|
|
|
@callbacks << :create
|
|
|
|
@valid
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
test "complete callback chain" do
|
|
|
|
model = ModelCallbacks.new
|
|
|
|
model.create
|
|
|
|
assert_equal model.callbacks, [ :before_create, :before_around_create, :create,
|
|
|
|
:after_around_create, :after_create, :final_callback]
|
|
|
|
end
|
|
|
|
|
2014-12-14 23:16:38 -05:00
|
|
|
test "the callback chain is not halted when around or after callbacks return false" do
|
2009-12-28 19:15:39 -05:00
|
|
|
model = ModelCallbacks.new
|
|
|
|
model.create
|
|
|
|
assert_equal model.callbacks.last, :final_callback
|
|
|
|
end
|
|
|
|
|
2017-02-07 10:13:15 -05:00
|
|
|
test "the callback chain is not halted when a before callback returns false)" do
|
2014-12-14 23:16:38 -05:00
|
|
|
model = ModelCallbacks.new(before_create_returns: false)
|
2017-02-07 10:13:15 -05:00
|
|
|
model.create
|
|
|
|
assert_equal model.callbacks.last, :final_callback
|
2014-12-08 09:53:24 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
test "the callback chain is halted when a callback throws :abort" do
|
|
|
|
model = ModelCallbacks.new(before_create_throws: :abort)
|
2014-12-14 23:16:38 -05:00
|
|
|
model.create
|
2014-12-08 09:53:24 -05:00
|
|
|
assert_equal model.callbacks, [:before_create]
|
2014-12-14 23:16:38 -05:00
|
|
|
end
|
|
|
|
|
2009-12-28 19:15:39 -05:00
|
|
|
test "after callbacks are not executed if the block returns false" do
|
2014-12-14 23:16:38 -05:00
|
|
|
model = ModelCallbacks.new(valid: false)
|
2009-12-28 19:15:39 -05:00
|
|
|
model.create
|
|
|
|
assert_equal model.callbacks, [ :before_create, :before_around_create,
|
|
|
|
:create, :after_around_create]
|
|
|
|
end
|
|
|
|
|
|
|
|
test "only selects which types of callbacks should be created" do
|
2018-01-24 21:14:10 -05:00
|
|
|
assert_not_respond_to ModelCallbacks, :before_initialize
|
|
|
|
assert_not_respond_to ModelCallbacks, :around_initialize
|
2010-05-18 21:47:24 -04:00
|
|
|
assert_respond_to ModelCallbacks, :after_initialize
|
2009-12-28 19:15:39 -05:00
|
|
|
end
|
2010-08-03 17:04:41 -04:00
|
|
|
|
|
|
|
test "only selects which types of callbacks should be created from an array list" do
|
|
|
|
assert_respond_to ModelCallbacks, :before_multiple
|
|
|
|
assert_respond_to ModelCallbacks, :around_multiple
|
2018-01-24 21:14:10 -05:00
|
|
|
assert_not_respond_to ModelCallbacks, :after_multiple
|
2010-08-03 17:04:41 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
test "no callbacks should be created" do
|
2018-01-24 21:14:10 -05:00
|
|
|
assert_not_respond_to ModelCallbacks, :before_empty
|
|
|
|
assert_not_respond_to ModelCallbacks, :around_empty
|
|
|
|
assert_not_respond_to ModelCallbacks, :after_empty
|
2010-08-03 17:04:41 -04:00
|
|
|
end
|
2010-09-25 18:30:56 -04:00
|
|
|
|
|
|
|
class Violin
|
|
|
|
attr_reader :history
|
|
|
|
def initialize
|
|
|
|
@history = []
|
|
|
|
end
|
|
|
|
extend ActiveModel::Callbacks
|
|
|
|
define_model_callbacks :create
|
2016-08-07 19:05:28 -04:00
|
|
|
def callback1; history << "callback1"; end
|
|
|
|
def callback2; history << "callback2"; end
|
2010-09-25 18:30:56 -04:00
|
|
|
def create
|
2018-09-25 13:18:20 -04:00
|
|
|
run_callbacks(:create) { }
|
2010-09-25 18:30:56 -04:00
|
|
|
self
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class Violin1 < Violin
|
|
|
|
after_create :callback1, :callback2
|
|
|
|
end
|
|
|
|
class Violin2 < Violin
|
|
|
|
after_create :callback1
|
|
|
|
after_create :callback2
|
|
|
|
end
|
|
|
|
|
|
|
|
test "after_create callbacks with both callbacks declared in one line" do
|
|
|
|
assert_equal ["callback1", "callback2"], Violin1.new.create.history
|
|
|
|
end
|
2017-02-07 10:13:15 -05:00
|
|
|
|
2013-03-18 07:50:05 -04:00
|
|
|
test "after_create callbacks with both callbacks declared in different lines" do
|
2010-09-25 18:30:56 -04:00
|
|
|
assert_equal ["callback1", "callback2"], Violin2.new.create.history
|
|
|
|
end
|
2009-12-28 19:15:39 -05:00
|
|
|
end
|