mirror of
https://github.com/aasm/aasm
synced 2023-03-27 23:22:41 -04:00
make sure to use parameterised aasm everywhere
This commit is contained in:
parent
b3113ceb9d
commit
cf7ac74664
12 changed files with 86 additions and 58 deletions
|
@ -28,20 +28,20 @@ module AASM
|
|||
def aasm(*args, &block)
|
||||
if args[0].is_a?(Symbol) || args[0].is_a?(String)
|
||||
# using custom name
|
||||
name = args[0].to_sym
|
||||
state_machine_name = args[0].to_sym
|
||||
options = args[1] || {}
|
||||
else
|
||||
# using the default name
|
||||
name = :default
|
||||
# using the default state_machine_name
|
||||
state_machine_name = :default
|
||||
options = args[0] || {}
|
||||
end
|
||||
|
||||
AASM::StateMachine[self][name] ||= AASM::StateMachine.new
|
||||
AASM::StateMachine[self][state_machine_name] ||= AASM::StateMachine.new(state_machine_name)
|
||||
|
||||
@aasm ||= {}
|
||||
@aasm[name] ||= AASM::Base.new(self, name, AASM::StateMachine[self][name], options)
|
||||
@aasm[name].instance_eval(&block) if block # new DSL
|
||||
@aasm[name]
|
||||
@aasm[state_machine_name] ||= AASM::Base.new(self, state_machine_name, AASM::StateMachine[self][state_machine_name], options)
|
||||
@aasm[state_machine_name].instance_eval(&block) if block # new DSL
|
||||
@aasm[state_machine_name]
|
||||
end
|
||||
end # ClassMethods
|
||||
|
||||
|
@ -76,7 +76,7 @@ private
|
|||
event.fire_callbacks(
|
||||
:before,
|
||||
self,
|
||||
*process_args(event, aasm.current_state, *args)
|
||||
*process_args(event, aasm(state_machine_name).current_state, *args)
|
||||
)
|
||||
|
||||
if may_fire_to = event.may_fire?(self, *args)
|
||||
|
@ -146,7 +146,7 @@ private
|
|||
end
|
||||
|
||||
if AASM::StateMachine[self.class][state_machine_name].config.whiny_transitions
|
||||
raise AASM::InvalidTransition.new(self, event_name)
|
||||
raise AASM::InvalidTransition.new(self, event_name, state_machine_name)
|
||||
else
|
||||
false
|
||||
end
|
||||
|
|
|
@ -75,7 +75,7 @@ module AASM
|
|||
|
||||
# define an event
|
||||
def event(name, options={}, &block)
|
||||
@state_machine.events[name] = AASM::Core::Event.new(name, options, &block)
|
||||
@state_machine.add_event(name, options, &block)
|
||||
|
||||
if @klass.instance_methods.include?("may_#{name}?")
|
||||
warn "The event name #{name} is already used!"
|
||||
|
|
|
@ -2,10 +2,11 @@ module AASM::Core
|
|||
class Event
|
||||
include DslHelper
|
||||
|
||||
attr_reader :name, :options
|
||||
attr_reader :name, :state_machine, :options
|
||||
|
||||
def initialize(name, options = {}, &block)
|
||||
def initialize(name, state_machine, options = {}, &block)
|
||||
@name = name
|
||||
@state_machine = state_machine
|
||||
@transitions = []
|
||||
@guards = Array(options[:guard] || options[:guards] || options[:if])
|
||||
@unless = Array(options[:unless]) #TODO: This could use a better name
|
||||
|
@ -61,11 +62,11 @@ module AASM::Core
|
|||
if definitions # define new transitions
|
||||
# Create a separate transition for each from-state to the given state
|
||||
Array(definitions[:from]).each do |s|
|
||||
@transitions << AASM::Core::Transition.new(attach_event_guards(definitions.merge(:from => s.to_sym)), &block)
|
||||
@transitions << AASM::Core::Transition.new(self, attach_event_guards(definitions.merge(:from => s.to_sym)), &block)
|
||||
end
|
||||
# Create a transition if :to is specified without :from (transitions from ANY state)
|
||||
if @transitions.empty? && definitions[:to]
|
||||
@transitions << AASM::Core::Transition.new(attach_event_guards(definitions), &block)
|
||||
@transitions << AASM::Core::Transition.new(self, attach_event_guards(definitions), &block)
|
||||
end
|
||||
end
|
||||
@transitions
|
||||
|
@ -89,7 +90,7 @@ module AASM::Core
|
|||
def _fire(obj, options={}, to_state=nil, *args)
|
||||
result = options[:test_only] ? false : nil
|
||||
if @transitions.map(&:from).any?
|
||||
transitions = @transitions.select { |t| t.from == obj.aasm.current_state }
|
||||
transitions = @transitions.select { |t| t.from == obj.aasm(state_machine.name).current_state }
|
||||
return result if transitions.size == 0
|
||||
else
|
||||
transitions = @transitions
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
module AASM::Core
|
||||
class State
|
||||
attr_reader :name, :options
|
||||
attr_reader :name, :state_machine, :options
|
||||
|
||||
def initialize(name, klass, options={})
|
||||
def initialize(name, klass, state_machine, options={})
|
||||
@name = name
|
||||
@klass = klass
|
||||
@state_machine = state_machine
|
||||
update(options)
|
||||
end
|
||||
|
||||
|
|
|
@ -2,12 +2,13 @@ module AASM::Core
|
|||
class Transition
|
||||
include DslHelper
|
||||
|
||||
attr_reader :from, :to, :opts
|
||||
attr_reader :from, :to, :event, :opts
|
||||
alias_method :options, :opts
|
||||
|
||||
def initialize(opts, &block)
|
||||
def initialize(event, opts, &block)
|
||||
add_options_from_dsl(opts, [:on_transition, :guard, :after], &block) if block
|
||||
|
||||
@event = event
|
||||
@from = opts[:from]
|
||||
@to = opts[:to]
|
||||
@guards = Array(opts[:guards]) + Array(opts[:guard]) + Array(opts[:if])
|
||||
|
@ -44,8 +45,8 @@ module AASM::Core
|
|||
|
||||
def invoke_callbacks_compatible_with_guard(code, record, args, options={})
|
||||
if record.respond_to?(:aasm)
|
||||
record.aasm.from_state = @from if record.aasm.respond_to?(:from_state=)
|
||||
record.aasm.to_state = @to if record.aasm.respond_to?(:to_state=)
|
||||
record.aasm(event.state_machine.name).from_state = @from if record.aasm(event.state_machine.name).respond_to?(:from_state=)
|
||||
record.aasm(event.state_machine.name).to_state = @to if record.aasm(event.state_machine.name).respond_to?(:to_state=)
|
||||
end
|
||||
|
||||
case code
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
module AASM
|
||||
|
||||
class InvalidTransition < RuntimeError
|
||||
attr_reader :object, :event_name
|
||||
def initialize(object, event_name)
|
||||
@object, @event_name = object, event_name
|
||||
attr_reader :object, :event_name, :state_machine_name
|
||||
|
||||
def initialize(object, event_name, state_machine_name)
|
||||
@object, @event_name, @state_machine_name = object, event_name, state_machine_name
|
||||
end
|
||||
|
||||
def message
|
||||
"Event '#{event_name}' cannot transition from '#{object.aasm.current_state}'"
|
||||
"Event '#{event_name}' cannot transition from '#{object.aasm(state_machine_name).current_state}'"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ module AASM
|
|||
end
|
||||
|
||||
def human_state
|
||||
AASM::Localizer.new.human_state_name(@instance.class, current_state)
|
||||
AASM::Localizer.new.human_state_name(@instance.class, state_object_for_name(current_state))
|
||||
end
|
||||
|
||||
def states(options={})
|
||||
|
|
|
@ -21,7 +21,7 @@ module AASM
|
|||
|
||||
def item_for(klass, state, ancestor, options={})
|
||||
separator = options[:old_style] ? '.' : '/'
|
||||
:"#{i18n_scope(klass)}.attributes.#{i18n_klass(ancestor)}.#{klass.aasm.attribute_name}#{separator}#{state}"
|
||||
:"#{i18n_scope(klass)}.attributes.#{i18n_klass(ancestor)}.#{klass.aasm(state.state_machine.name).attribute_name}#{separator}#{state}"
|
||||
end
|
||||
|
||||
def translate_queue(checklist)
|
||||
|
|
|
@ -12,11 +12,12 @@ module AASM
|
|||
|
||||
attr_accessor :states, :events, :initial_state, :config, :name
|
||||
|
||||
def initialize
|
||||
def initialize(name)
|
||||
@initial_state = nil
|
||||
@states = []
|
||||
@events = {}
|
||||
@config = AASM::Configuration.new
|
||||
@name = name
|
||||
end
|
||||
|
||||
# called internally by Ruby 1.9 after clone()
|
||||
|
@ -26,13 +27,17 @@ module AASM
|
|||
@events = @events.dup
|
||||
end
|
||||
|
||||
def add_state(name, klass, options)
|
||||
set_initial_state(name, options)
|
||||
def add_state(state_name, klass, options)
|
||||
set_initial_state(state_name, options)
|
||||
|
||||
# allow reloading, extending or redefining a state
|
||||
@states.delete(name) if @states.include?(name)
|
||||
@states.delete(state_name) if @states.include?(state_name)
|
||||
|
||||
@states << AASM::Core::State.new(name, klass, options)
|
||||
@states << AASM::Core::State.new(state_name, klass, self, options)
|
||||
end
|
||||
|
||||
def add_event(name, options, &block)
|
||||
@events[name] = AASM::Core::Event.new(name, self, options, &block)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'adding an event' do
|
||||
let(:state_machine) { AASM::StateMachine.new(:name) }
|
||||
let(:event) do
|
||||
AASM::Core::Event.new(:close_order, {:success => :success_callback}) do
|
||||
AASM::Core::Event.new(:close_order, state_machine, {:success => :success_callback}) do
|
||||
before :before_callback
|
||||
after :after_callback
|
||||
transitions :to => :closed, :from => [:open, :received]
|
||||
|
@ -35,8 +36,9 @@ describe 'adding an event' do
|
|||
end
|
||||
|
||||
describe 'transition inspection' do
|
||||
let(:state_machine) { AASM::StateMachine.new(:name) }
|
||||
let(:event) do
|
||||
AASM::Core::Event.new(:run) do
|
||||
AASM::Core::Event.new(:run, state_machine) do
|
||||
transitions :to => :running, :from => :sleeping
|
||||
end
|
||||
end
|
||||
|
@ -59,8 +61,9 @@ describe 'transition inspection' do
|
|||
end
|
||||
|
||||
describe 'transition inspection without from' do
|
||||
let(:state_machine) { AASM::StateMachine.new(:name) }
|
||||
let(:event) do
|
||||
AASM::Core::Event.new(:run) do
|
||||
AASM::Core::Event.new(:run, state_machine) do
|
||||
transitions :to => :running
|
||||
end
|
||||
end
|
||||
|
@ -76,15 +79,17 @@ describe 'transition inspection without from' do
|
|||
end
|
||||
|
||||
describe 'firing an event' do
|
||||
let(:state_machine) { AASM::StateMachine.new(:name) }
|
||||
|
||||
it 'should return nil if the transitions are empty' do
|
||||
obj = double('object', :aasm => double('aasm', :current_state => 'open'))
|
||||
|
||||
event = AASM::Core::Event.new(:event)
|
||||
event = AASM::Core::Event.new(:event, state_machine)
|
||||
expect(event.fire(obj)).to be_nil
|
||||
end
|
||||
|
||||
it 'should return the state of the first matching transition it finds' do
|
||||
event = AASM::Core::Event.new(:event) do
|
||||
event = AASM::Core::Event.new(:event, state_machine) do
|
||||
transitions :to => :closed, :from => [:open, :received]
|
||||
end
|
||||
|
||||
|
@ -94,7 +99,7 @@ describe 'firing an event' do
|
|||
end
|
||||
|
||||
it 'should call the guard with the params passed in' do
|
||||
event = AASM::Core::Event.new(:event) do
|
||||
event = AASM::Core::Event.new(:event, state_machine) do
|
||||
transitions :to => :closed, :from => [:open, :received], :guard => :guard_fn
|
||||
end
|
||||
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe AASM::Core::State do
|
||||
let(:state_machine) { AASM::StateMachine.new(:name) }
|
||||
|
||||
before(:each) do
|
||||
@name = :astate
|
||||
@options = { :crazy_custom_key => 'key' }
|
||||
end
|
||||
|
||||
def new_state(options={})
|
||||
AASM::Core::State.new(@name, Conversation, @options.merge(options))
|
||||
AASM::Core::State.new(@name, Conversation, state_machine, @options.merge(options))
|
||||
end
|
||||
|
||||
it 'should set the name' do
|
||||
|
|
|
@ -57,9 +57,12 @@ describe 'blocks' do
|
|||
end
|
||||
|
||||
describe AASM::Core::Transition do
|
||||
let(:state_machine) { AASM::StateMachine.new(:name) }
|
||||
let(:event) { AASM::Core::Event.new(:event, state_machine) }
|
||||
|
||||
it 'should set from, to, and opts attr readers' do
|
||||
opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
|
||||
st = AASM::Core::Transition.new(opts)
|
||||
st = AASM::Core::Transition.new(event, opts)
|
||||
|
||||
expect(st.from).to eq(opts[:from])
|
||||
expect(st.to).to eq(opts[:to])
|
||||
|
@ -71,7 +74,7 @@ describe AASM::Core::Transition do
|
|||
st = AASM::Core::Transition.allocate
|
||||
expect(st).to receive(:warn).with('[DEPRECATION] :on_transition is deprecated, use :after instead')
|
||||
|
||||
st.send :initialize, opts do
|
||||
st.send :initialize, event, opts do
|
||||
guard :gg
|
||||
on_transition :after_callback
|
||||
end
|
||||
|
@ -81,7 +84,7 @@ describe AASM::Core::Transition do
|
|||
|
||||
it 'should set after and guard from dsl' do
|
||||
opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
|
||||
st = AASM::Core::Transition.new(opts) do
|
||||
st = AASM::Core::Transition.new(event, opts) do
|
||||
guard :gg
|
||||
after :after_callback
|
||||
end
|
||||
|
@ -92,7 +95,7 @@ describe AASM::Core::Transition do
|
|||
|
||||
it 'should pass equality check if from and to are the same' do
|
||||
opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
|
||||
st = AASM::Core::Transition.new(opts)
|
||||
st = AASM::Core::Transition.new(event, opts)
|
||||
|
||||
obj = double('object')
|
||||
allow(obj).to receive(:from).and_return(opts[:from])
|
||||
|
@ -103,7 +106,7 @@ describe AASM::Core::Transition do
|
|||
|
||||
it 'should fail equality check if from are not the same' do
|
||||
opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
|
||||
st = AASM::Core::Transition.new(opts)
|
||||
st = AASM::Core::Transition.new(event, opts)
|
||||
|
||||
obj = double('object')
|
||||
allow(obj).to receive(:from).and_return('blah')
|
||||
|
@ -114,7 +117,7 @@ describe AASM::Core::Transition do
|
|||
|
||||
it 'should fail equality check if to are not the same' do
|
||||
opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
|
||||
st = AASM::Core::Transition.new(opts)
|
||||
st = AASM::Core::Transition.new(event, opts)
|
||||
|
||||
obj = double('object')
|
||||
allow(obj).to receive(:from).and_return(opts[:from])
|
||||
|
@ -125,16 +128,19 @@ describe AASM::Core::Transition do
|
|||
end
|
||||
|
||||
describe AASM::Core::Transition, '- when performing guard checks' do
|
||||
let(:state_machine) { AASM::StateMachine.new(:name) }
|
||||
let(:event) { AASM::Core::Event.new(:event, state_machine) }
|
||||
|
||||
it 'should return true of there is no guard' do
|
||||
opts = {:from => 'foo', :to => 'bar'}
|
||||
st = AASM::Core::Transition.new(opts)
|
||||
st = AASM::Core::Transition.new(event, opts)
|
||||
|
||||
expect(st.allowed?(nil)).to be_truthy
|
||||
end
|
||||
|
||||
it 'should call the method on the object if guard is a symbol' do
|
||||
opts = {:from => 'foo', :to => 'bar', :guard => :test}
|
||||
st = AASM::Core::Transition.new(opts)
|
||||
st = AASM::Core::Transition.new(event, opts)
|
||||
|
||||
obj = double('object')
|
||||
expect(obj).to receive(:test)
|
||||
|
@ -144,7 +150,7 @@ describe AASM::Core::Transition, '- when performing guard checks' do
|
|||
|
||||
it 'should call the method on the object if unless is a symbol' do
|
||||
opts = {:from => 'foo', :to => 'bar', :unless => :test}
|
||||
st = AASM::Core::Transition.new(opts)
|
||||
st = AASM::Core::Transition.new(event, opts)
|
||||
|
||||
obj = double('object')
|
||||
expect(obj).to receive(:test)
|
||||
|
@ -154,7 +160,7 @@ describe AASM::Core::Transition, '- when performing guard checks' do
|
|||
|
||||
it 'should call the method on the object if guard is a string' do
|
||||
opts = {:from => 'foo', :to => 'bar', :guard => 'test'}
|
||||
st = AASM::Core::Transition.new(opts)
|
||||
st = AASM::Core::Transition.new(event, opts)
|
||||
|
||||
obj = double('object')
|
||||
expect(obj).to receive(:test)
|
||||
|
@ -164,7 +170,7 @@ describe AASM::Core::Transition, '- when performing guard checks' do
|
|||
|
||||
it 'should call the method on the object if unless is a string' do
|
||||
opts = {:from => 'foo', :to => 'bar', :unless => 'test'}
|
||||
st = AASM::Core::Transition.new(opts)
|
||||
st = AASM::Core::Transition.new(event, opts)
|
||||
|
||||
obj = double('object')
|
||||
expect(obj).to receive(:test)
|
||||
|
@ -174,7 +180,7 @@ describe AASM::Core::Transition, '- when performing guard checks' do
|
|||
|
||||
it 'should call the proc passing the object if the guard is a proc' do
|
||||
opts = {:from => 'foo', :to => 'bar', :guard => Proc.new { test }}
|
||||
st = AASM::Core::Transition.new(opts)
|
||||
st = AASM::Core::Transition.new(event, opts)
|
||||
|
||||
obj = double('object')
|
||||
expect(obj).to receive(:test)
|
||||
|
@ -184,9 +190,12 @@ describe AASM::Core::Transition, '- when performing guard checks' do
|
|||
end
|
||||
|
||||
describe AASM::Core::Transition, '- when executing the transition with a Proc' do
|
||||
let(:state_machine) { AASM::StateMachine.new(:name) }
|
||||
let(:event) { AASM::Core::Event.new(:event, state_machine) }
|
||||
|
||||
it 'should call a Proc on the object with args' do
|
||||
opts = {:from => 'foo', :to => 'bar', :after => Proc.new {|a| test(a) }}
|
||||
st = AASM::Core::Transition.new(opts)
|
||||
st = AASM::Core::Transition.new(event, opts)
|
||||
args = {:arg1 => '1', :arg2 => '2'}
|
||||
obj = double('object', :aasm => 'aasm')
|
||||
|
||||
|
@ -202,7 +211,7 @@ describe AASM::Core::Transition, '- when executing the transition with a Proc' d
|
|||
prc = Proc.new { prc_object = self }
|
||||
|
||||
opts = {:from => 'foo', :to => 'bar', :after => prc }
|
||||
st = AASM::Core::Transition.new(opts)
|
||||
st = AASM::Core::Transition.new(event, opts)
|
||||
args = {:arg1 => '1', :arg2 => '2'}
|
||||
obj = double('object', :aasm => 'aasm')
|
||||
|
||||
|
@ -212,9 +221,12 @@ describe AASM::Core::Transition, '- when executing the transition with a Proc' d
|
|||
end
|
||||
|
||||
describe AASM::Core::Transition, '- when executing the transition with an :after method call' do
|
||||
let(:state_machine) { AASM::StateMachine.new(:name) }
|
||||
let(:event) { AASM::Core::Event.new(:event, state_machine) }
|
||||
|
||||
it 'should accept a String for the method name' do
|
||||
opts = {:from => 'foo', :to => 'bar', :after => 'test'}
|
||||
st = AASM::Core::Transition.new(opts)
|
||||
st = AASM::Core::Transition.new(event, opts)
|
||||
args = {:arg1 => '1', :arg2 => '2'}
|
||||
obj = double('object', :aasm => 'aasm')
|
||||
|
||||
|
@ -225,7 +237,7 @@ describe AASM::Core::Transition, '- when executing the transition with an :after
|
|||
|
||||
it 'should accept a Symbol for the method name' do
|
||||
opts = {:from => 'foo', :to => 'bar', :after => :test}
|
||||
st = AASM::Core::Transition.new(opts)
|
||||
st = AASM::Core::Transition.new(event, opts)
|
||||
args = {:arg1 => '1', :arg2 => '2'}
|
||||
obj = double('object', :aasm => 'aasm')
|
||||
|
||||
|
@ -236,7 +248,7 @@ describe AASM::Core::Transition, '- when executing the transition with an :after
|
|||
|
||||
it 'should pass args if the target method accepts them' do
|
||||
opts = {:from => 'foo', :to => 'bar', :after => :test}
|
||||
st = AASM::Core::Transition.new(opts)
|
||||
st = AASM::Core::Transition.new(event, opts)
|
||||
args = {:arg1 => '1', :arg2 => '2'}
|
||||
obj = double('object', :aasm => 'aasm')
|
||||
|
||||
|
@ -251,7 +263,7 @@ describe AASM::Core::Transition, '- when executing the transition with an :after
|
|||
|
||||
it 'should NOT pass args if the target method does NOT accept them' do
|
||||
opts = {:from => 'foo', :to => 'bar', :after => :test}
|
||||
st = AASM::Core::Transition.new(opts)
|
||||
st = AASM::Core::Transition.new(event, opts)
|
||||
args = {:arg1 => '1', :arg2 => '2'}
|
||||
obj = double('object', :aasm => 'aasm')
|
||||
|
||||
|
@ -266,7 +278,7 @@ describe AASM::Core::Transition, '- when executing the transition with an :after
|
|||
|
||||
it 'should allow accessing the from_state and the to_state' do
|
||||
opts = {:from => 'foo', :to => 'bar', :after => :test}
|
||||
transition = AASM::Core::Transition.new(opts)
|
||||
transition = AASM::Core::Transition.new(event, opts)
|
||||
args = {:arg1 => '1', :arg2 => '2'}
|
||||
obj = double('object', :aasm => AASM::InstanceBase.new('object'))
|
||||
|
||||
|
|
Loading…
Reference in a new issue