/** * @return StateMachineInterface */ public function build() { $stateMachineBuilder = new StateMachineBuilder('registration'); $stateMachineBuilder->addState('input'); $stateMachineBuilder->addState('confirmation'); $stateMachineBuilder->addState('success'); $stateMachineBuilder->setStartState('input'); $stateMachineBuilder->addTransition('input', 'confirmation', 'confirmation'); $stateMachineBuilder->addTransition('confirmation', 'success', 'success'); $stateMachineBuilder->addTransition('confirmation', 'input', 'input'); $stateMachineBuilder->setEndState('success', StateInterface::STATE_FINAL); return $stateMachineBuilder->getStateMachine(); }
/** * Configures a state. * * @param array $state * @throws \Piece\Flow\PageFlow\ProtectedEventException */ protected function configureState(array $state) { for ($i = 0, $count = count(@$state['transition']); $i < $count; ++$i) { if (in_array($state['transition'][$i]['event'], array(EventInterface::EVENT_ENTRY, EventInterface::EVENT_EXIT, EventInterface::EVENT_START, EventInterface::EVENT_DO))) { throw new ProtectedEventException("The event [ {$state['transition'][$i]['event']} ] cannot be used in flow definitions."); } $this->stateMachineBuilder->addTransition($state['name'], $state['transition'][$i]['event'], $state['transition'][$i]['nextState'], $this->wrapEventTriggerAction(@$state['transition'][$i]['action']), $this->wrapAction(@$state['transition'][$i]['guard'])); } if (!empty($state['entry'])) { $this->stateMachineBuilder->setEntryAction($state['name'], $this->wrapAction(@$state['entry'])); } if (!empty($state['exit'])) { $this->stateMachineBuilder->setExitAction($state['name'], $this->wrapAction(@$state['exit'])); } if (!empty($state['activity'])) { $this->stateMachineBuilder->setActivity($state['name'], $this->wrapEventTriggerAction(@$state['activity'])); } }
/** * @test */ public function raisesAnExceptionIfTheGuardIsNotCallableWhenAddingATransition() { $stateMachineBuilder = new StateMachineBuilder(); $stateMachineBuilder->addState('foo'); $stateMachineBuilder->addState('baz'); try { $stateMachineBuilder->addTransition('foo', 'bar', 'baz', null, array($this, 'nonExistingMethod')); } catch (ActionNotCallableException $e) { $this->assertThat($e->getMessage(), $this->stringStartsWith('The guard')); return; } $this->fail('An expected exception has not been raised.'); }
/** * @test */ public function dispatchesSystemEventsToListenersIfTheEventDispatcherHasBeenSet() { $events = array(); $eventDispatcher = new EventDispatcher(); $eventDispatcher->addListener(StateMachineEvents::EVENT_PROCESS, function (StateMachineEvent $event, $eventName, EventDispatcherInterface $eventDispatcher) use(&$events) { $events[] = array('name' => $eventName, 'event' => $event); }); $eventDispatcher->addListener(StateMachineEvents::EVENT_EXIT, function (StateMachineEvent $event, $eventName, EventDispatcherInterface $eventDispatcher) use(&$events) { $events[] = array('name' => $eventName, 'event' => $event); }); $eventDispatcher->addListener(StateMachineEvents::EVENT_TRANSITION, function (StateMachineEvent $event, $eventName, EventDispatcherInterface $eventDispatcher) use(&$events) { $events[] = array('name' => $eventName, 'event' => $event); }); $eventDispatcher->addListener(StateMachineEvents::EVENT_ENTRY, function (StateMachineEvent $event, $eventName, EventDispatcherInterface $eventDispatcher) use(&$events) { $events[] = array('name' => $eventName, 'event' => $event); }); $eventDispatcher->addListener(StateMachineEvents::EVENT_DO, function (StateMachineEvent $event, $eventName, EventDispatcherInterface $eventDispatcher) use(&$events) { $events[] = array('name' => $eventName, 'event' => $event); }); $stateMachineBuilder = new StateMachineBuilder(); $stateMachineBuilder->addState('locked'); $stateMachineBuilder->addState('unlocked'); $stateMachineBuilder->setStartState('locked'); $stateMachineBuilder->addTransition('locked', 'insertCoin', 'unlocked'); $stateMachineBuilder->addTransition('unlocked', 'pass', 'locked'); $stateMachine = $stateMachineBuilder->getStateMachine(); $stateMachine->setEventDispatcher($eventDispatcher); $stateMachine->start(); $stateMachine->triggerEvent('insertCoin'); $this->assertThat(count($events), $this->equalTo(10)); $this->assertThat($events[0]['name'], $this->equalTo(StateMachineEvents::EVENT_PROCESS)); $this->assertThat($events[0]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[0]['event']->getState()->getStateId(), $this->equalTo(StateInterface::STATE_INITIAL)); $this->assertThat($events[0]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\TransitionEventInterface')); $this->assertThat($events[0]['event']->getEvent()->getEventId(), $this->equalTo(EventInterface::EVENT_START)); $this->assertThat($events[1]['name'], $this->equalTo(StateMachineEvents::EVENT_EXIT)); $this->assertThat($events[1]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[1]['event']->getState()->getStateId(), $this->equalTo(StateInterface::STATE_INITIAL)); $this->assertThat($events[1]['event']->getEvent(), $this->isNull()); $this->assertThat($events[2]['name'], $this->equalTo(StateMachineEvents::EVENT_TRANSITION)); $this->assertThat($events[2]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[2]['event']->getState()->getStateId(), $this->equalTo(StateInterface::STATE_INITIAL)); $this->assertThat($events[2]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\TransitionEventInterface')); $this->assertThat($events[2]['event']->getEvent()->getEventId(), $this->equalTo(EventInterface::EVENT_START)); $this->assertThat($events[3]['name'], $this->equalTo(StateMachineEvents::EVENT_ENTRY)); $this->assertThat($events[3]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[3]['event']->getState()->getStateId(), $this->equalTo('locked')); $this->assertThat($events[3]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\EventInterface')); $this->assertThat($events[3]['event']->getEvent()->getEventId(), $this->equalTo(EventInterface::EVENT_ENTRY)); $this->assertThat($events[4]['name'], $this->equalTo(StateMachineEvents::EVENT_DO)); $this->assertThat($events[4]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[4]['event']->getState()->getStateId(), $this->equalTo('locked')); $this->assertThat($events[4]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\EventInterface')); $this->assertThat($events[4]['event']->getEvent()->getEventId(), $this->equalTo(EventInterface::EVENT_DO)); $this->assertThat($events[5]['name'], $this->equalTo(StateMachineEvents::EVENT_PROCESS)); $this->assertThat($events[5]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[5]['event']->getState()->getStateId(), $this->equalTo('locked')); $this->assertThat($events[5]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\TransitionEventInterface')); $this->assertThat($events[5]['event']->getEvent()->getEventId(), $this->equalTo('insertCoin')); $this->assertThat($events[6]['name'], $this->equalTo(StateMachineEvents::EVENT_EXIT)); $this->assertThat($events[6]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[6]['event']->getState()->getStateId(), $this->equalTo('locked')); $this->assertThat($events[6]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\EventInterface')); $this->assertThat($events[6]['event']->getEvent()->getEventId(), $this->equalTo(EventInterface::EVENT_EXIT)); $this->assertThat($events[7]['name'], $this->equalTo(StateMachineEvents::EVENT_TRANSITION)); $this->assertThat($events[7]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[7]['event']->getState()->getStateId(), $this->equalTo('locked')); $this->assertThat($events[7]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\TransitionEventInterface')); $this->assertThat($events[7]['event']->getEvent()->getEventId(), $this->equalTo('insertCoin')); $this->assertThat($events[8]['name'], $this->equalTo(StateMachineEvents::EVENT_ENTRY)); $this->assertThat($events[8]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[8]['event']->getState()->getStateId(), $this->equalTo('unlocked')); $this->assertThat($events[8]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\EventInterface')); $this->assertThat($events[8]['event']->getEvent()->getEventId(), $this->equalTo(EventInterface::EVENT_ENTRY)); $this->assertThat($events[9]['name'], $this->equalTo(StateMachineEvents::EVENT_DO)); $this->assertThat($events[9]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[9]['event']->getState()->getStateId(), $this->equalTo('unlocked')); $this->assertThat($events[9]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\EventInterface')); $this->assertThat($events[9]['event']->getEvent()->getEventId(), $this->equalTo(EventInterface::EVENT_DO)); }