spec/unit/events_spec.rb in finite_machine-0.10.2 vs spec/unit/events_spec.rb in finite_machine-0.11.0

- old
+ new

@@ -167,41 +167,113 @@ expect(fsm.current).to eql(:green) fsm.run expect(fsm.current).to eql(:green) end - it "raises error on invalid transition" do + it "doesn't raise error on invalid transition for non-dangerous version" do + called = [] fsm = FiniteMachine.define do initial :green events { - event :slow, from: :green, to: :yellow - event :stop, from: :yellow, to: :red + event :stop, from: :yellow, to: :red } + callbacks { + on_before :stop do |event| called << 'on_before_stop' end + on_after :stop do |event| called << 'on_before_stop' end + } end - expect(fsm.current).to eql(:green) + expect(fsm.current).to eq(:green) + expect(fsm.stop).to eq(false) + expect(fsm.current).to eq(:green) + expect(called).to match_array(['on_before_stop']) + end - expect { - fsm.stop - }.to raise_error(FiniteMachine::InvalidStateError, - /inappropriate current state 'green'/) + context 'for non-dangerous version' do + it "doesn't raise error on invalid transition and fires callbacks" do + called = [] + fsm = FiniteMachine.define do + initial :green + + events { + event :stop, from: :yellow, to: :red + } + callbacks { + on_before :stop do |event| called << 'on_before_stop' end + on_after :stop do |event| called << 'on_before_stop' end + } + end + + expect(fsm.current).to eq(:green) + expect(fsm.stop).to eq(false) + expect(fsm.current).to eq(:green) + expect(called).to match_array(['on_before_stop']) + end + + it "raises error on invalid transition for dangerous version" do + called = [] + fsm = FiniteMachine.define do + initial :green + + events { + event :slow, from: :green, to: :yellow + event :stop, from: :yellow, to: :red, silent: true + } + callbacks { + on_before :stop do |event| called << 'on_before_stop' end + on_after :stop do |event| called << 'on_before_stop' end + } + end + + expect(fsm.current).to eql(:green) + expect(fsm.stop).to eq(false) + expect(called).to match_array([]) + end end - it "allows to transition to any state" do - fsm = FiniteMachine.define do - initial :green + context 'for dangerous version' do + it "raises error on invalid transition without callbacks" do + called = [] + fsm = FiniteMachine.define do + initial :green - events { - event :slow, from: :green, to: :yellow - event :stop, from: :yellow, to: :red - } + events { + event :start, :red => :yellow, silent: true + } + callbacks { + on_before :start do |event| called << 'on_before_start' end + on_after :start do |event| called << 'on_after_start' end + } + end + + expect(fsm.current).to eq(:green) + expect { fsm.start! }.to raise_error(FiniteMachine::InvalidStateError) + expect(called).to eq([]) + expect(fsm.current).to eq(:green) end - expect(fsm.current).to eql(:green) - expect(fsm.can?(:stop)).to be false - fsm.stop! - expect(fsm.current).to eql(:red) + + it "raises error on invalid transition with callbacks fired" do + called = [] + fsm = FiniteMachine.define do + initial :green + + events { + event :start, :red => :yellow + } + callbacks { + on_before :start do |event| called << 'on_before_start' end + on_after :start do |event| called << 'on_after_start' end + } + end + + expect(fsm.current).to eq(:green) + expect { fsm.start! }.to raise_error(FiniteMachine::InvalidStateError, + /inappropriate current state 'green'/) + expect(called).to eq(['on_before_start']) + expect(fsm.current).to eq(:green) + end end context 'when multiple from states' do it "allows for array from key" do fsm = FiniteMachine.define do @@ -312,20 +384,20 @@ event :drive, :engine_on => :running, if: -> { return false } event :stop, :any => :neutral } callbacks { - on_before(:drive) { } + on_before(:drive) { FiniteMachine::CANCELLED } on_after(:stop) { } } end expect(fsm.current).to eql(:neutral) - expect(fsm.start).to eql(FiniteMachine::SUCCEEDED) - expect(fsm.drive).to eql(FiniteMachine::CANCELLED) - expect(fsm.stop).to eql(FiniteMachine::SUCCEEDED) - expect(fsm.stop).to eql(FiniteMachine::NOTRANSITION) + expect(fsm.start).to eql(true) + expect(fsm.drive).to eql(false) + expect(fsm.stop).to eql(true) + expect(fsm.stop).to eql(true) end it "allows for self transition events" do digits = [] callbacks = [] @@ -356,12 +428,32 @@ expect(digits).to match_array(digits) expect(callbacks).to match_array(["dialing 911"]) end it "detects dangerous event names" do - expect { FiniteMachine.define do + expect { + FiniteMachine.define do + events { + event :trigger, :a => :b + } + end + }.to raise_error(FiniteMachine::AlreadyDefinedError) + end + + it "executes event block" do + fsm = FiniteMachine.define do + initial :red + events { - event :transition, :a => :b + event :start, :red => :green + event :stop, :green => :red } - end }.to raise_error(FiniteMachine::AlreadyDefinedError) + end + + expect(fsm.current).to eq(:red) + called = [] + fsm.start do |from, to| + called << "execute_start_#{from}_#{to}" + end + expect(called).to eq(['execute_start_red_green']) end end