Bring in transition guards

This commit is contained in:
Scott Barron 2008-02-21 10:46:06 -05:00
parent b4c69afcf2
commit 8c02c47160
4 changed files with 59 additions and 5 deletions

View File

@ -31,7 +31,7 @@ module AASM
define_method("#{name.to_s}!") do
new_state = self.class.aasm_events[name].fire(self)
self.aasm_current_state = new_state
self.aasm_current_state = new_state unless new_state.nil?
nil
end
end

View File

@ -13,11 +13,16 @@ module AASM
def fire(obj)
transitions = @transitions.select { |t| t.from == obj.aasm_current_state }
if transitions.size == 0
raise AASM::InvalidTransition
else
transitions.first.to
raise AASM::InvalidTransition if transitions.size == 0
next_state = nil
transitions.each do |transition|
if transition.perform(obj)
next_state = transition.to
break
end
end
next_state
end
private

View File

@ -8,6 +8,17 @@ module AASM
@opts = opts
end
def perform(obj)
case @guard
when Symbol, String
obj.send(@guard)
when Proc
@guard.call(obj)
else
true
end
end
def ==(obj)
@from == obj.from && @to == obj.to
end

View File

@ -44,3 +44,41 @@ describe AASM::SupportingClasses::StateTransition do
end
end
describe AASM::SupportingClasses::StateTransition, '- when performing guard checks' do
it 'should return true of there is no guard' do
opts = {:from => 'foo', :to => 'bar'}
st = AASM::SupportingClasses::StateTransition.new(opts)
st.perform(nil).should be_true
end
it 'should call the method on the object if guard is a symbol' do
opts = {:from => 'foo', :to => 'bar', :guard => :test}
st = AASM::SupportingClasses::StateTransition.new(opts)
obj = mock('object')
obj.should_receive(:test)
st.perform(obj)
end
it 'should call the method on the object if guard is a string' do
opts = {:from => 'foo', :to => 'bar', :guard => 'test'}
st = AASM::SupportingClasses::StateTransition.new(opts)
obj = mock('object')
obj.should_receive(:test)
st.perform(obj)
end
it 'should call the proc passing the object if the guard is a proc' do
opts = {:from => 'foo', :to => 'bar', :guard => Proc.new {|o| o.test}}
st = AASM::SupportingClasses::StateTransition.new(opts)
obj = mock('object')
obj.should_receive(:test)
st.perform(obj)
end
end