From d0172e986336629e13011c0f77b070755f3ebbe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20B=C3=B6ttger?= Date: Tue, 26 May 2015 21:21:04 +1200 Subject: [PATCH] more tests for multiple state machines (callbacks, rest) --- .../callbacks/guard_within_block_multiple.rb | 66 +++ ...e_transitions_transition_guard_multiple.rb | 65 +++ .../callbacks/private_method_multiple.rb | 44 ++ spec/models/callbacks/with_args_multiple.rb | 61 +++ .../callbacks/with_state_arg_multiple.rb | 26 ++ spec/models/foo_multiple.rb | 35 ++ spec/unit/callback_multiple_spec.rb | 420 +++++++++--------- 7 files changed, 507 insertions(+), 210 deletions(-) create mode 100644 spec/models/callbacks/guard_within_block_multiple.rb create mode 100644 spec/models/callbacks/multiple_transitions_transition_guard_multiple.rb create mode 100644 spec/models/callbacks/private_method_multiple.rb create mode 100644 spec/models/callbacks/with_args_multiple.rb create mode 100644 spec/models/callbacks/with_state_arg_multiple.rb create mode 100644 spec/models/foo_multiple.rb diff --git a/spec/models/callbacks/guard_within_block_multiple.rb b/spec/models/callbacks/guard_within_block_multiple.rb new file mode 100644 index 00000000..cb817f78 --- /dev/null +++ b/spec/models/callbacks/guard_within_block_multiple.rb @@ -0,0 +1,66 @@ +module Callbacks + class GuardWithinBlockMultiple + include AASM + + def initialize(options={}) + @fail_event_guard = options[:fail_event_guard] + @fail_transition_guard = options[:fail_transition_guard] + @log = options[:log] + end + + aasm(:left) do + state :open, :initial => true, + :before_enter => :before_enter_open, + :enter => :enter_open, + :after_enter => :after_enter_open, + :before_exit => :before_exit_open, + :exit => :exit_open, + :after_exit => :after_exit_open + + state :closed, + :before_enter => :before_enter_closed, + :enter => :enter_closed, + :after_enter => :after_enter_closed, + :before_exit => :before_exit_closed, + :exit => :exit_closed, + :after_exit => :after_exit_closed + + event :close, :before => :before, :after => :after, :guard => :event_guard do + transitions :to => :closed, :from => [:open], :after => :transitioning do + guard do + transition_guard + end + end + end + + event :open, :before => :before, :after => :after do + transitions :to => :open, :from => :closed + end + end + + def log(text) + puts text if @log + end + + def before_enter_open; log('before_enter_open'); end + def enter_open; log('enter_open'); end + def before_exit_open; log('before_exit_open'); end + def after_enter_open; log('after_enter_open'); end + def exit_open; log('exit_open'); end + def after_exit_open; log('after_exit_open'); end + + def before_enter_closed; log('before_enter_closed'); end + def enter_closed; log('enter_closed'); end + def before_exit_closed; log('before_exit_closed'); end + def exit_closed; log('exit_closed'); end + def after_enter_closed; log('after_enter_closed'); end + def after_exit_closed; log('after_exit_closed'); end + + def event_guard; log('event_guard'); !@fail_event_guard; end + def transition_guard; log('transition_guard'); !@fail_transition_guard; end + def transitioning; log('transitioning'); end + + def before; log('before'); end + def after; log('after'); end + end +end diff --git a/spec/models/callbacks/multiple_transitions_transition_guard_multiple.rb b/spec/models/callbacks/multiple_transitions_transition_guard_multiple.rb new file mode 100644 index 00000000..5c95df49 --- /dev/null +++ b/spec/models/callbacks/multiple_transitions_transition_guard_multiple.rb @@ -0,0 +1,65 @@ +module Callbacks + class MultipleTransitionsTransitionGuardMultiple + include AASM + + def initialize(options={}) + @fail_event_guard = options[:fail_event_guard] + @fail_transition_guard = options[:fail_transition_guard] + @log = options[:log] + end + + aasm(:left) do + state :open, :initial => true, + :before_enter => :before_enter_open, + :enter => :enter_open, + :after_enter => :after_enter_open, + :before_exit => :before_exit_open, + :exit => :exit_open, + :after_exit => :after_exit_open + + state :closed, + :before_enter => :before_enter_closed, + :enter => :enter_closed, + :after_enter => :after_enter_closed, + :before_exit => :before_exit_closed, + :exit => :exit_closed, + :after_exit => :after_exit_closed + + state :failed + + event :close, :before => :before, :after => :after, :guard => :event_guard do + transitions :to => :closed, :from => [:open], :guard => :transition_guard, :after => :transitioning + transitions :to => :failed, :from => [:open] + end + + event :open, :before => :before, :after => :after do + transitions :to => :open, :from => :closed + end + end + + def log(text) + puts text if @log + end + + def before_enter_open; log('before_enter_open'); end + def enter_open; log('enter_open'); end + def before_exit_open; log('before_exit_open'); end + def after_enter_open; log('after_enter_open'); end + def exit_open; log('exit_open'); end + def after_exit_open; log('after_exit_open'); end + + def before_enter_closed; log('before_enter_closed'); end + def enter_closed; log('enter_closed'); end + def before_exit_closed; log('before_exit_closed'); end + def exit_closed; log('exit_closed'); end + def after_enter_closed; log('after_enter_closed'); end + def after_exit_closed; log('after_exit_closed'); end + + def event_guard; log('event_guard'); !@fail_event_guard; end + def transition_guard; log('transition_guard'); !@fail_transition_guard; end + def transitioning; log('transitioning'); end + + def before; log('before'); end + def after; log('after'); end + end +end diff --git a/spec/models/callbacks/private_method_multiple.rb b/spec/models/callbacks/private_method_multiple.rb new file mode 100644 index 00000000..24d963d8 --- /dev/null +++ b/spec/models/callbacks/private_method_multiple.rb @@ -0,0 +1,44 @@ +module Callbacks + class PrivateMethodMultiple + include AASM + + def initialize(options={}) + @fail_event_guard = options[:fail_event_guard] + @fail_transition_guard = options[:fail_transition_guard] + @log = options[:log] + reset_data + end + + def reset_data + @data = [] + end + + def data + @data.join(' ') + end + + aasm(:left) do + state :open, :initial => true + state :closed + + event :close, :after => :after_event do + transitions :to => :closed, :from => [:open] + end + + event :open, :after => :after_event do + transitions :to => :open, :from => :closed + end + end + + def log(text) + @data << text + puts text if @log + end + + def aasm_write_state(*args); log('aasm_write_state'); true; end + + private + + def after_event; log('after_event'); end + end +end diff --git a/spec/models/callbacks/with_args_multiple.rb b/spec/models/callbacks/with_args_multiple.rb new file mode 100644 index 00000000..6ec9fc6b --- /dev/null +++ b/spec/models/callbacks/with_args_multiple.rb @@ -0,0 +1,61 @@ +module Callbacks + class WithArgsMultiple + include AASM + + def initialize(options={}) + @log = options[:log] + reset_data + end + + def reset_data + @data = [] + end + + def data + @data.join(' ') + end + + aasm(:left) do + state :open, :initial => true, + :before_enter => :before_enter_open, + :after_enter => :after_enter_open, + :before_exit => :before_exit_open, + :after_exit => :after_exit_open + + state :closed, + :before_enter => :before_enter_closed, + :after_enter => :after_enter_closed, + :before_exit => :before_exit_closed, + :after_exit => :after_exit_closed + + event :close, :before => :before, :after => :after do + transitions :to => :closed, :from => [:open], :after => :transition_proc + end + + event :open, :before => :before, :after => :after do + transitions :to => :open, :from => :closed + end + end + + def log(text) + @data << text + puts text if @log + end + + def aasm_write_state(*args); log('aasm_write_state'); true; end + + def before_enter_open(*args); log("before_enter_open(#{args.map(&:inspect).join(',')})"); end + def before_exit_open(*args); log("before_exit_open(#{args.map(&:inspect).join(',')})"); end + def after_enter_open(*args); log("after_enter_open(#{args.map(&:inspect).join(',')})"); end + def after_exit_open(*args); log("after_exit_open(#{args.map(&:inspect).join(',')})"); end + + def before_enter_closed(*args); log("before_enter_closed(#{args.map(&:inspect).join(',')})"); end + def before_exit_closed(*args); log("before_enter_closed(#{args.map(&:inspect).join(',')})"); end + def after_enter_closed(*args); log("after_enter_closed(#{args.map(&:inspect).join(',')})"); end + def after_exit_closed(*args); log("after_exit_closed(#{args.map(&:inspect).join(',')})"); end + + def before(arg1, *args); log("before(#{arg1.inspect},#{args.map(&:inspect).join(',')})"); end + def transition_proc(arg1, arg2); log("transition_proc(#{arg1.inspect},#{arg2.inspect})"); end + def after(*args); log("after(#{args.map(&:inspect).join(',')})"); end + end +end diff --git a/spec/models/callbacks/with_state_arg_multiple.rb b/spec/models/callbacks/with_state_arg_multiple.rb new file mode 100644 index 00000000..29b9fedf --- /dev/null +++ b/spec/models/callbacks/with_state_arg_multiple.rb @@ -0,0 +1,26 @@ +module Callbacks + class WithStateArgMultiple + + include AASM + + aasm(:left) do + state :open, :inital => true + state :closed + state :out_to_lunch + + event :close, :before => :before_method, :after => :after_method do + transitions :to => :closed, :from => [:open], :after => :transition_method + transitions :to => :out_to_lunch, :from => [:open], :after => :transition_method2 + end + end + + def before_method(arg); end + + def after_method(arg); end + + def transition_method(arg); end + + def transition_method2(arg); end + + end +end diff --git a/spec/models/foo_multiple.rb b/spec/models/foo_multiple.rb new file mode 100644 index 00000000..c337dcb8 --- /dev/null +++ b/spec/models/foo_multiple.rb @@ -0,0 +1,35 @@ +class FooMultiple + include AASM + aasm(:left) do + state :open, :initial => true, :before_exit => :before_exit + state :closed, :before_enter => :before_enter + state :final + + event :close, :success => :success_callback do + transitions :from => [:open], :to => [:closed] + end + + event :null do + transitions :from => [:open], :to => [:closed, :final], :guard => :always_false + end + end + + def always_false + false + end + + def success_callback + end + + def before_enter + end + def before_exit + end +end + +class FooTwoMultiple < FooMultiple + include AASM + aasm(:left) do + state :foo + end +end diff --git a/spec/unit/callback_multiple_spec.rb b/spec/unit/callback_multiple_spec.rb index 98f849f1..9ffb41d5 100644 --- a/spec/unit/callback_multiple_spec.rb +++ b/spec/unit/callback_multiple_spec.rb @@ -52,17 +52,17 @@ }.to raise_error(AASM::InvalidTransition) end - # it "it handles private callback methods as well" do - # show_debug_log = false + it "handles private callback methods as well" do + show_debug_log = false - # callback = Callbacks::PrivateMethod.new(:log => show_debug_log) - # callback.aasm.current_state + callback = Callbacks::PrivateMethodMultiple.new(:log => show_debug_log) + callback.aasm(:left).current_state - # # puts "------- close!" - # expect { - # callback.close! - # }.to_not raise_error - # end + # puts "------- close!" + expect { + callback.close! + }.to_not raise_error + end context "if the transition guard fails" do it "does not run any state callback if guard is defined inline" do @@ -90,206 +90,206 @@ }.to raise_error(AASM::InvalidTransition) end - # it "does not run transition_guard twice for multiple permitted transitions" do - # show_debug_log = false - # callback = Callbacks::MultipleTransitionsTransitionGuard.new(:log => show_debug_log, :fail_transition_guard => true) - # callback.aasm.current_state - - # unless show_debug_log - # expect(callback).to receive(:before).once.ordered - # expect(callback).to receive(:event_guard).once.ordered.and_return(true) - # expect(callback).to receive(:transition_guard).once.ordered.and_return(false) - # expect(callback).to receive(:event_guard).once.ordered.and_return(true) - # expect(callback).to receive(:before_exit_open).once.ordered - # expect(callback).to receive(:exit_open).once.ordered - # expect(callback).to receive(:aasm_write_state).once.ordered.and_return(true) # this is when the state changes - # expect(callback).to receive(:after_exit_open).once.ordered - # expect(callback).to receive(:after).once.ordered - - # expect(callback).to_not receive(:transitioning) - # expect(callback).to_not receive(:before_enter_closed) - # expect(callback).to_not receive(:enter_closed) - # expect(callback).to_not receive(:after_enter_closed) - # end - - # callback.close! - # expect(callback.aasm.current_state).to eql :failed - # end - - # it "does not run any state callback if guard is defined with block" do - # callback = Callbacks::GuardWithinBlock.new #(:log => true, :fail_transition_guard => true) - # callback.aasm.current_state - - # expect(callback).to receive(:before).once.ordered - # expect(callback).to receive(:event_guard).once.ordered.and_return(true) - # expect(callback).to receive(:transition_guard).once.ordered.and_return(false) - # expect(callback).to_not receive(:before_exit_open) - # expect(callback).to_not receive(:exit_open) - # expect(callback).to_not receive(:transitioning) - # expect(callback).to_not receive(:before_enter_closed) - # expect(callback).to_not receive(:enter_closed) - # expect(callback).to_not receive(:aasm_write_state) - # expect(callback).to_not receive(:after_exit_open) - # expect(callback).to_not receive(:after_enter_closed) - # expect(callback).to_not receive(:after) - - # expect { - # callback.close! - # }.to raise_error(AASM::InvalidTransition) - # end + it "does not run transition_guard twice for multiple permitted transitions" do + show_debug_log = false + callback = Callbacks::MultipleTransitionsTransitionGuardMultiple.new(:log => show_debug_log, :fail_transition_guard => true) + callback.aasm(:left).current_state + + unless show_debug_log + expect(callback).to receive(:before).once.ordered + expect(callback).to receive(:event_guard).once.ordered.and_return(true) + expect(callback).to receive(:transition_guard).once.ordered.and_return(false) + expect(callback).to receive(:event_guard).once.ordered.and_return(true) + expect(callback).to receive(:before_exit_open).once.ordered + expect(callback).to receive(:exit_open).once.ordered + expect(callback).to receive(:aasm_write_state).once.ordered.and_return(true) # this is when the state changes + expect(callback).to receive(:after_exit_open).once.ordered + expect(callback).to receive(:after).once.ordered + + expect(callback).to_not receive(:transitioning) + expect(callback).to_not receive(:before_enter_closed) + expect(callback).to_not receive(:enter_closed) + expect(callback).to_not receive(:after_enter_closed) + end + + callback.close! + expect(callback.aasm(:left).current_state).to eql :failed + end + + it "does not run any state callback if guard is defined with block" do + callback = Callbacks::GuardWithinBlockMultiple.new #(:log => true, :fail_transition_guard => true) + callback.aasm(:left).current_state + + expect(callback).to receive(:before).once.ordered + expect(callback).to receive(:event_guard).once.ordered.and_return(true) + expect(callback).to receive(:transition_guard).once.ordered.and_return(false) + expect(callback).to_not receive(:before_exit_open) + expect(callback).to_not receive(:exit_open) + expect(callback).to_not receive(:transitioning) + expect(callback).to_not receive(:before_enter_closed) + expect(callback).to_not receive(:enter_closed) + expect(callback).to_not receive(:aasm_write_state) + expect(callback).to_not receive(:after_exit_open) + expect(callback).to_not receive(:after_enter_closed) + expect(callback).to_not receive(:after) + + expect { + callback.close! + }.to raise_error(AASM::InvalidTransition) + end + end + + it "should properly pass arguments" do + cb = Callbacks::WithArgsMultiple.new(:log => false) + cb.aasm(:left).current_state + + cb.reset_data + cb.close!(:arg1, :arg2) + expect(cb.data).to eql 'before(:arg1,:arg2) before_exit_open(:arg1,:arg2) transition_proc(:arg1,:arg2) before_enter_closed(:arg1,:arg2) aasm_write_state after_exit_open(:arg1,:arg2) after_enter_closed(:arg1,:arg2) after(:arg1,:arg2)' + end + + it "should call the callbacks given the to-state as argument" do + cb = Callbacks::WithStateArgMultiple.new + expect(cb).to receive(:before_method).with(:arg1).once.ordered + expect(cb).to receive(:transition_method).never + expect(cb).to receive(:transition_method2).with(:arg1).once.ordered + expect(cb).to receive(:after_method).with(:arg1).once.ordered + cb.close!(:out_to_lunch, :arg1) + + cb = Callbacks::WithStateArgMultiple.new + some_object = double('some object') + expect(cb).to receive(:before_method).with(some_object).once.ordered + expect(cb).to receive(:transition_method2).with(some_object).once.ordered + expect(cb).to receive(:after_method).with(some_object).once.ordered + cb.close!(:out_to_lunch, some_object) + end + + it "should call the proper methods just with arguments" do + cb = Callbacks::WithStateArgMultiple.new + expect(cb).to receive(:before_method).with(:arg1).once.ordered + expect(cb).to receive(:transition_method).with(:arg1).once.ordered + expect(cb).to receive(:transition_method).never + expect(cb).to receive(:after_method).with(:arg1).once.ordered + cb.close!(:arg1) + + cb = Callbacks::WithStateArgMultiple.new + some_object = double('some object') + expect(cb).to receive(:before_method).with(some_object).once.ordered + expect(cb).to receive(:transition_method).with(some_object).once.ordered + expect(cb).to receive(:transition_method).never + expect(cb).to receive(:after_method).with(some_object).once.ordered + cb.close!(some_object) + end +end # callbacks for the new DSL + +describe 'event callbacks' do + describe "with an error callback defined" do + before do + class FooMultiple + # this hack is needed to allow testing of parameters, since RSpec + # destroys a method's arity when mocked + attr_accessor :data + + aasm(:left) do + event :safe_close, :success => :success_callback, :error => :error_callback do + transitions :to => :closed, :from => [:open] + end + end + end + + @foo = FooMultiple.new + end + + context "error_callback defined" do + it "should run error_callback if an exception is raised" do + def @foo.error_callback(e) + @data = [e] + end + + allow(@foo).to receive(:before_enter).and_raise(e = StandardError.new) + + @foo.safe_close! + expect(@foo.data).to eql [e] + end + + it "should run error_callback without parameters if callback does not support any" do + def @foo.error_callback(e) + @data = [] + end + + allow(@foo).to receive(:before_enter).and_raise(e = StandardError.new) + + @foo.safe_close!('arg1', 'arg2') + expect(@foo.data).to eql [] + end + + it "should run error_callback with parameters if callback supports them" do + def @foo.error_callback(e, arg1, arg2) + @data = [arg1, arg2] + end + + allow(@foo).to receive(:before_enter).and_raise(e = StandardError.new) + + @foo.safe_close!('arg1', 'arg2') + expect(@foo.data).to eql ['arg1', 'arg2'] + end + end + + it "should raise NoMethodError if exception is raised and error_callback is declared but not defined" do + allow(@foo).to receive(:before_enter).and_raise(StandardError) + expect{@foo.safe_close!}.to raise_error(NoMethodError) + end + + it "should propagate an error if no error callback is declared" do + allow(@foo).to receive(:before_enter).and_raise("Cannot enter safe") + expect{@foo.close!}.to raise_error(StandardError, "Cannot enter safe") + end + end + + describe "with aasm_event_fired defined" do + before do + @foo = FooMultiple.new + def @foo.aasm_event_fired(event, from, to); end + end + + it 'should call it for successful bang fire' do + expect(@foo).to receive(:aasm_event_fired).with(:close, :open, :closed) + @foo.close! + end + + it 'should call it for successful non-bang fire' do + expect(@foo).to receive(:aasm_event_fired) + @foo.close + end + + it 'should not call it for failing bang fire' do + allow(@foo.aasm(:left)).to receive(:set_current_state_with_persistence).and_return(false) + expect(@foo).not_to receive(:aasm_event_fired) + @foo.close! + end + end + + describe "with aasm_event_failed defined" do + before do + @foo = FooMultiple.new + def @foo.aasm_event_failed(event, from); end + end + + it 'should call it when transition failed for bang fire' do + expect(@foo).to receive(:aasm_event_failed).with(:null, :open) + expect {@foo.null!}.to raise_error(AASM::InvalidTransition) + end + + it 'should call it when transition failed for non-bang fire' do + expect(@foo).to receive(:aasm_event_failed).with(:null, :open) + expect {@foo.null}.to raise_error(AASM::InvalidTransition) + end + + it 'should not call it if persist fails for bang fire' do + allow(@foo.aasm(:left)).to receive(:set_current_state_with_persistence).and_return(false) + expect(@foo).to receive(:aasm_event_failed) + @foo.close! + end end - # it "should properly pass arguments" do - # cb = Callbacks::WithArgs.new(:log => false) - # cb.aasm.current_state - - # cb.reset_data - # cb.close!(:arg1, :arg2) - # expect(cb.data).to eql 'before(:arg1,:arg2) before_exit_open(:arg1,:arg2) transition_proc(:arg1,:arg2) before_enter_closed(:arg1,:arg2) aasm_write_state after_exit_open(:arg1,:arg2) after_enter_closed(:arg1,:arg2) after(:arg1,:arg2)' - # end - - # it "should call the callbacks given the to-state as argument" do - # cb = Callbacks::WithStateArg.new - # expect(cb).to receive(:before_method).with(:arg1).once.ordered - # expect(cb).to receive(:transition_method).never - # expect(cb).to receive(:transition_method2).with(:arg1).once.ordered - # expect(cb).to receive(:after_method).with(:arg1).once.ordered - # cb.close!(:out_to_lunch, :arg1) - - # cb = Callbacks::WithStateArg.new - # some_object = double('some object') - # expect(cb).to receive(:before_method).with(some_object).once.ordered - # expect(cb).to receive(:transition_method2).with(some_object).once.ordered - # expect(cb).to receive(:after_method).with(some_object).once.ordered - # cb.close!(:out_to_lunch, some_object) - # end - - # it "should call the proper methods just with arguments" do - # cb = Callbacks::WithStateArg.new - # expect(cb).to receive(:before_method).with(:arg1).once.ordered - # expect(cb).to receive(:transition_method).with(:arg1).once.ordered - # expect(cb).to receive(:transition_method).never - # expect(cb).to receive(:after_method).with(:arg1).once.ordered - # cb.close!(:arg1) - - # cb = Callbacks::WithStateArg.new - # some_object = double('some object') - # expect(cb).to receive(:before_method).with(some_object).once.ordered - # expect(cb).to receive(:transition_method).with(some_object).once.ordered - # expect(cb).to receive(:transition_method).never - # expect(cb).to receive(:after_method).with(some_object).once.ordered - # cb.close!(some_object) - # end -end - -# describe 'event callbacks' do -# describe "with an error callback defined" do -# before do -# class Foo -# # this hack is needed to allow testing of parameters, since RSpec -# # destroys a method's arity when mocked -# attr_accessor :data - -# aasm do -# event :safe_close, :success => :success_callback, :error => :error_callback do -# transitions :to => :closed, :from => [:open] -# end -# end -# end - -# @foo = Foo.new -# end - -# context "error_callback defined" do -# it "should run error_callback if an exception is raised" do -# def @foo.error_callback(e) -# @data = [e] -# end - -# allow(@foo).to receive(:before_enter).and_raise(e = StandardError.new) - -# @foo.safe_close! -# expect(@foo.data).to eql [e] -# end - -# it "should run error_callback without parameters if callback does not support any" do -# def @foo.error_callback(e) -# @data = [] -# end - -# allow(@foo).to receive(:before_enter).and_raise(e = StandardError.new) - -# @foo.safe_close!('arg1', 'arg2') -# expect(@foo.data).to eql [] -# end - -# it "should run error_callback with parameters if callback supports them" do -# def @foo.error_callback(e, arg1, arg2) -# @data = [arg1, arg2] -# end - -# allow(@foo).to receive(:before_enter).and_raise(e = StandardError.new) - -# @foo.safe_close!('arg1', 'arg2') -# expect(@foo.data).to eql ['arg1', 'arg2'] -# end -# end - -# it "should raise NoMethodError if exception is raised and error_callback is declared but not defined" do -# allow(@foo).to receive(:before_enter).and_raise(StandardError) -# expect{@foo.safe_close!}.to raise_error(NoMethodError) -# end - -# it "should propagate an error if no error callback is declared" do -# allow(@foo).to receive(:before_enter).and_raise("Cannot enter safe") -# expect{@foo.close!}.to raise_error(StandardError, "Cannot enter safe") -# end -# end - -# describe "with aasm_event_fired defined" do -# before do -# @foo = Foo.new -# def @foo.aasm_event_fired(event, from, to); end -# end - -# it 'should call it for successful bang fire' do -# expect(@foo).to receive(:aasm_event_fired).with(:close, :open, :closed) -# @foo.close! -# end - -# it 'should call it for successful non-bang fire' do -# expect(@foo).to receive(:aasm_event_fired) -# @foo.close -# end - -# it 'should not call it for failing bang fire' do -# allow(@foo.aasm).to receive(:set_current_state_with_persistence).and_return(false) -# expect(@foo).not_to receive(:aasm_event_fired) -# @foo.close! -# end -# end - -# describe "with aasm_event_failed defined" do -# before do -# @foo = Foo.new -# def @foo.aasm_event_failed(event, from); end -# end - -# it 'should call it when transition failed for bang fire' do -# expect(@foo).to receive(:aasm_event_failed).with(:null, :open) -# expect {@foo.null!}.to raise_error(AASM::InvalidTransition) -# end - -# it 'should call it when transition failed for non-bang fire' do -# expect(@foo).to receive(:aasm_event_failed).with(:null, :open) -# expect {@foo.null}.to raise_error(AASM::InvalidTransition) -# end - -# it 'should not call it if persist fails for bang fire' do -# allow(@foo.aasm).to receive(:set_current_state_with_persistence).and_return(false) -# expect(@foo).to receive(:aasm_event_failed) -# @foo.close! -# end -# end - -# end +end # event callbacks