require 'more/spec_helper' describe "Callbacks" do before :all do module CallbacksSpec; end class CallbacksSpec::Basic inherit RubyExt::Callbacks set_callback :save, :before, :before_save set_callback :save, :around, :around_save set_callback :save, :after, :after_save protected def around_save around_save_called yield end end end after(:all){remove_constants :CallbacksSpec} it "basic" do o = CallbacksSpec::Basic.new o.should_receive :before_save o.should_receive :around_save_called o.should_receive :after_save o.run_callbacks(:save){"result"}.should == "result" end it "should be possible to call before & after separatelly (in this mode :around is not available)" do o = CallbacksSpec::Basic.new o.should_receive :before_save o.run_before_callbacks(:save) o.should_receive :after_save o.run_after_callbacks(:save) end it "blocks" do class CallbacksSpec::Blocks inherit RubyExt::Callbacks set_callback(:save, :before){|controller| controller.result << :before} set_callback :save, :around do |controller, block| begin controller.result << :around_begin block.call ensure controller.result << :around_end end end set_callback(:save, :after){|controller| controller.result << :after} def result @result ||= [] end end o = CallbacksSpec::Blocks.new o.run_callbacks(:save){"result"}.should == "result" o.result.should == [:before, :around_begin, :after, :around_end] end it "execution order" do class CallbacksSpec::ExecutionOrder inherit RubyExt::Callbacks # order is important, don't change it set_callback :save, :before, :before1 set_callback :save, :after, :after1 set_callback :save, :around, :around1 set_callback :save, :before, :before2 protected def around1 around1_called yield end end o = CallbacksSpec::ExecutionOrder.new o.should_receive(:before1).ordered.once o.should_receive(:around1_called).ordered.once o.should_receive(:before2).ordered.once o.should_receive(:after1).ordered.once o.run_callbacks :save end it "inheritance" do class CallbacksSpec::Inheritance < CallbacksSpec::Basic set_callback :save, :before, :before_save2 end o = CallbacksSpec::Inheritance.new o.should_receive :before_save o.should_receive :before_save2 o.should_receive :around_save_called o.should_receive :after_save o.run_callbacks(:save){"result"}.should == "result" end it 'terminator' do class CallbacksSpec::Terminator inherit RubyExt::Callbacks set_callback :save, :before, :before_save, terminator: false set_callback :save, :before, :before_save2 def method run_callbacks :save do "result" end end protected def before_save false end end o = CallbacksSpec::Terminator.new o.should_not_receive :before_save2 o.run_callbacks(:save){"result"}.should_not == "result" end it 'conditions' do class CallbacksSpec::Conditions inherit RubyExt::Callbacks set_callback :save, :before, :before_save, only: :another_method end o = CallbacksSpec::Conditions.new o.should_not_receive :before_save o.run_callbacks(:save, method: :method){"result"}.should == 'result' o = CallbacksSpec::Conditions.new o.should_receive :before_save o.run_callbacks(:save, method: :another_method){"result"}.should == 'result' end it "if, unless conditions" do c = RubyExt::Callbacks::AbstractCallback.new c.conditions = {if: lambda{|target, inf| true}} c.run?(nil, {}).should be_true c.conditions = {if: lambda{|target, inf| false}} c.run?(nil, {}).should be_false c.conditions = {unless: lambda{|target, inf| true}} c.run?(nil, {}).should be_false c.conditions = {unless: lambda{|target, inf| false}} c.run?(nil, {}).should be_true end it "only, except conditions" do c = RubyExt::Callbacks::AbstractCallback.new c.conditions = {only: :a} c.run?(nil, {method: :a}).should be_true c.conditions = {only: :b} c.run?(nil, {method: :a}).should be_false c.conditions = {except: :a} c.run?(nil, {method: :a}).should be_false c.conditions = {except: :b} c.run?(nil, {method: :a}).should be_true c.conditions = {only: :a} c.run?(nil, {method: :a}).should be_true end it "around callback should be able to change result value" do class CallbacksSpec::ChangeResult inherit RubyExt::Callbacks set_callback :save, :around, :around_save def around_save yield 'another result' end end o = CallbacksSpec::ChangeResult.new o.run_callbacks(:save){"result"}.should == 'another result' end end