1
0
Fork 0
mirror of https://github.com/aasm/aasm synced 2023-03-27 23:22:41 -04:00

adding support for :permitted => false on both events and states inspection

This commit is contained in:
hspazio 2016-05-14 22:40:45 +01:00
parent 841715aeae
commit 282fefd768
2 changed files with 38 additions and 13 deletions

View file

@ -34,19 +34,22 @@ module AASM
end
def states(options={})
if options[:permitted]
permitted_events = events(:permitted => true)
if options.has_key?(:permitted)
selected_events = events(:permitted => options[:permitted])
# An array of arrays. Each inner array represents the transitions that
# transition from the current state for an event
event_transitions = permitted_events.map {|e| e.transitions_from_state(current_state) }
event_transitions = selected_events.map {|e| e.transitions_from_state(current_state) }
# An array of symbols that are possible :to transition states
# An array of :to transition states
to_state_names = event_transitions.map do |transitions|
return nil if transitions.empty?
# Return the :to state of the first transition that is allowed or nil
transition = transitions.find { |t| t.allowed?(@instance) }
# Return the :to state of the first transition that is allowed (or not) or nil
if options[:permitted]
transition = transitions.find { |t| t.allowed?(@instance) }
else
transition = transitions.find { |t| !t.allowed?(@instance) }
end
transition ? transition.to : nil
end.flatten.compact.uniq
@ -64,10 +67,14 @@ module AASM
options[:reject] = Array(options[:reject])
events.reject! { |e| options[:reject].include?(e.name) }
if options[:permitted]
if options.has_key?(:permitted)
# filters the results of events_for_current_state so that only those that
# are really currently possible (given transition guards) are shown.
events.select! { |e| @instance.send("may_#{e.name}?") }
if options[:permitted]
events.select! { |e| @instance.send("may_#{e.name}?") }
else
events.select! { |e| !@instance.send("may_#{e.name}?") }
end
end
events

View file

@ -25,10 +25,15 @@ describe 'inspection for common cases' do
expect(states).to include(:closed)
expect(states).to include(:final)
states = foo.aasm.states(:permitted => true)
expect(states).to include(:closed)
expect(states).not_to include(:open)
expect(states).not_to include(:final)
permitted_states = foo.aasm.states(:permitted => true)
expect(permitted_states).to include(:closed)
expect(permitted_states).not_to include(:open)
expect(permitted_states).not_to include(:final)
blocked_states = foo.aasm.states(:permitted => false)
expect(blocked_states).to include(:closed)
expect(blocked_states).not_to include(:open)
expect(blocked_states).to include(:final)
foo.close
expect(foo.aasm.states(:permitted => true)).to be_empty
@ -124,3 +129,16 @@ describe 'permitted events' do
expect(foo.aasm.events(:permitted => true, reject: [:close])).not_to include(:close)
end
end
describe 'not permitted events' do
let(:foo) {Foo.new}
it 'work' do
expect(foo.aasm.events(:permitted => false)).to include(:null)
expect(foo.aasm.events(:permitted => false)).not_to include(:close)
end
it 'should not include events in the reject option' do
expect(foo.aasm.events(:permitted => false, reject: :null)).to eq([])
end
end