mirror of
https://github.com/aasm/aasm
synced 2023-03-27 23:22:41 -04:00
fire guards only once per transition #184
This commit is contained in:
parent
8ce7062aa8
commit
aac1ece778
6 changed files with 20 additions and 18 deletions
|
@ -4,6 +4,10 @@
|
||||||
|
|
||||||
* `aasm_human_event_name` is deprecated, use `aasm.human_event_name` instead
|
* `aasm_human_event_name` is deprecated, use `aasm.human_event_name` instead
|
||||||
|
|
||||||
|
## 4.0.1
|
||||||
|
|
||||||
|
* fire guards only once per transition (see [issue #184](https://github.com/aasm/aasm/issues/184) for details)
|
||||||
|
|
||||||
## 4.0.0
|
## 4.0.0
|
||||||
|
|
||||||
* support `if` and `unless` guard syntax: (see [issue #179](https://github.com/aasm/aasm/issues/179) and [issue #181](https://github.com/aasm/aasm/issues/181)), thanks to [@bigtunacan](https://github.com/bigtunacan)
|
* support `if` and `unless` guard syntax: (see [issue #179](https://github.com/aasm/aasm/issues/179) and [issue #181](https://github.com/aasm/aasm/issues/181)), thanks to [@bigtunacan](https://github.com/bigtunacan)
|
||||||
|
|
|
@ -141,14 +141,12 @@ Here you can see a list of all possible callbacks, together with their order of
|
||||||
```ruby
|
```ruby
|
||||||
begin
|
begin
|
||||||
event before
|
event before
|
||||||
event guards # test run
|
event guards
|
||||||
transition guards # test run
|
transition guards
|
||||||
old_state before_exit
|
old_state before_exit
|
||||||
old_state exit
|
old_state exit
|
||||||
new_state before_enter
|
new_state before_enter
|
||||||
new_state enter
|
new_state enter
|
||||||
event guards
|
|
||||||
transition guards
|
|
||||||
...update state...
|
...update state...
|
||||||
transition after
|
transition after
|
||||||
event success # if persist successful
|
event success # if persist successful
|
||||||
|
|
|
@ -86,11 +86,11 @@ private
|
||||||
*process_args(event, aasm.current_state, *args)
|
*process_args(event, aasm.current_state, *args)
|
||||||
)
|
)
|
||||||
|
|
||||||
if event.may_fire?(self, *args)
|
if may_fire_to = event.may_fire?(self, *args)
|
||||||
old_state.fire_callbacks(:before_exit, self)
|
old_state.fire_callbacks(:before_exit, self)
|
||||||
old_state.fire_callbacks(:exit, self) # TODO: remove for AASM 4?
|
old_state.fire_callbacks(:exit, self) # TODO: remove for AASM 4?
|
||||||
|
|
||||||
if new_state_name = event.fire(self, *args)
|
if new_state_name = event.fire(self, {:may_fire => may_fire_to}, *args)
|
||||||
aasm_fired(event, old_state, new_state_name, options, *args, &block)
|
aasm_fired(event, old_state, new_state_name, options, *args, &block)
|
||||||
else
|
else
|
||||||
aasm_failed(event_name, old_state)
|
aasm_failed(event_name, old_state)
|
||||||
|
|
|
@ -19,11 +19,11 @@ module AASM
|
||||||
# executes the transition guards to determine if a transition is even
|
# executes the transition guards to determine if a transition is even
|
||||||
# an option given current conditions.
|
# an option given current conditions.
|
||||||
def may_fire?(obj, to_state=nil, *args)
|
def may_fire?(obj, to_state=nil, *args)
|
||||||
_fire(obj, true, to_state, *args) # true indicates test firing
|
_fire(obj, {:test_only => true}, to_state, *args) # true indicates test firing
|
||||||
end
|
end
|
||||||
|
|
||||||
def fire(obj, to_state=nil, *args)
|
def fire(obj, options={}, to_state=nil, *args)
|
||||||
_fire(obj, false, to_state, *args) # false indicates this is not a test (fire!)
|
_fire(obj, options, to_state, *args) # false indicates this is not a test (fire!)
|
||||||
end
|
end
|
||||||
|
|
||||||
def transitions_from_state?(state)
|
def transitions_from_state?(state)
|
||||||
|
@ -86,8 +86,8 @@ module AASM
|
||||||
end
|
end
|
||||||
|
|
||||||
# Execute if test == false, otherwise return true/false depending on whether it would fire
|
# Execute if test == false, otherwise return true/false depending on whether it would fire
|
||||||
def _fire(obj, test, to_state=nil, *args)
|
def _fire(obj, options={}, to_state=nil, *args)
|
||||||
result = test ? false : nil
|
result = options[:test_only] ? false : nil
|
||||||
if @transitions.map(&:from).any?
|
if @transitions.map(&:from).any?
|
||||||
transitions = @transitions.select { |t| t.from == obj.aasm.current_state }
|
transitions = @transitions.select { |t| t.from == obj.aasm.current_state }
|
||||||
return result if transitions.size == 0
|
return result if transitions.size == 0
|
||||||
|
@ -106,11 +106,11 @@ module AASM
|
||||||
|
|
||||||
transitions.each do |transition|
|
transitions.each do |transition|
|
||||||
next if to_state and !Array(transition.to).include?(to_state)
|
next if to_state and !Array(transition.to).include?(to_state)
|
||||||
if transition.allowed?(obj, *args)
|
if Array(transition.to).include?(options[:may_fire]) || transition.allowed?(obj, *args)
|
||||||
if test
|
result = to_state || Array(transition.to).first
|
||||||
result = true
|
if options[:test_only]
|
||||||
|
# result = true
|
||||||
else
|
else
|
||||||
result = to_state || Array(transition.to).first
|
|
||||||
transition.execute(obj, *args)
|
transition.execute(obj, *args)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ describe 'callbacks for the new DSL' do
|
||||||
expect(callback).to receive(:transition_guard).once.ordered.and_return(true)
|
expect(callback).to receive(:transition_guard).once.ordered.and_return(true)
|
||||||
expect(callback).to receive(:before_exit_open).once.ordered # these should be before the state changes
|
expect(callback).to receive(:before_exit_open).once.ordered # these should be before the state changes
|
||||||
expect(callback).to receive(:exit_open).once.ordered
|
expect(callback).to receive(:exit_open).once.ordered
|
||||||
expect(callback).to receive(:event_guard).once.ordered.and_return(true)
|
# expect(callback).to receive(:event_guard).once.ordered.and_return(true)
|
||||||
expect(callback).to receive(:transition_guard).once.ordered.and_return(true)
|
# expect(callback).to receive(:transition_guard).once.ordered.and_return(true)
|
||||||
expect(callback).to receive(:transitioning).once.ordered
|
expect(callback).to receive(:transitioning).once.ordered
|
||||||
expect(callback).to receive(:before_enter_closed).once.ordered
|
expect(callback).to receive(:before_enter_closed).once.ordered
|
||||||
expect(callback).to receive(:enter_closed).once.ordered
|
expect(callback).to receive(:enter_closed).once.ordered
|
||||||
|
|
|
@ -101,7 +101,7 @@ describe 'firing an event' do
|
||||||
obj = double('object', :aasm => double('aasm', :current_state => :open))
|
obj = double('object', :aasm => double('aasm', :current_state => :open))
|
||||||
expect(obj).to receive(:guard_fn).with('arg1', 'arg2').and_return(true)
|
expect(obj).to receive(:guard_fn).with('arg1', 'arg2').and_return(true)
|
||||||
|
|
||||||
expect(event.fire(obj, nil, 'arg1', 'arg2')).to eq(:closed)
|
expect(event.fire(obj, {}, nil, 'arg1', 'arg2')).to eq(:closed)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue