Exemplo n.º 1
0
 /**
  * {@inheritdoc}
  *
  * @throws TransitionPatternMismatch
  */
 public static function new(string $transition) : Transition
 {
     $isMatch = preg_match(self::getPattern(), $transition, $matches);
     $withExpectedNamedCaptures = isset($matches['current_state'], $matches['input'], $matches['next_state']);
     if (!$isMatch || !$withExpectedNamedCaptures) {
         throw new TransitionPatternMismatch($transition, self::$pattern);
     }
     return new self(FlyweightState::named($matches['current_state']), FlyweightInput::named($matches['input']), FlyweightState::named($matches['next_state']));
 }
 /**
  * @dataProvider movesProvider
  *
  * @param string $currentStateName
  * @param array $inputNames
  * @param string $expectedStateName
  */
 public function testResolvesStateTransitionsProperly(string $currentStateName, array $inputNames, string $expectedStateName)
 {
     $table = new ChessMatchTransitionTable();
     $currentState = FlyweightState::named($currentStateName);
     $expectedState = FlyweightState::named($expectedStateName);
     foreach ($inputNames as $inputName) {
         $currentState = $table->resolve($currentState, FlyweightInput::named($inputName));
     }
     $this->assertSame($expectedState, $currentState);
 }
 public function testCanCreateTransitionsUsingConstructor()
 {
     $currentState = FlyweightState::named('FOO');
     $input = FlyweightInput::named('BAR');
     $nextState = FlyweightState::named('BAZ');
     $transition = new DefaultTransition($currentState, $input, $nextState);
     $this->assertInstanceOf(Transition::class, $transition);
     $this->assertSame($currentState, $transition->getCurrentState());
     $this->assertSame($input, $transition->getInput());
     $this->assertSame($nextState, $transition->getNextState());
 }
 public function testAdditionalExceptionPropertiesAreAccessibleViaGeters()
 {
     $input = FlyweightInput::named('BAR');
     $object = new StatefulObject();
     $object->setCurrentState(FlyweightState::named('FOO'));
     $context = new Context();
     $nextState = FlyweightState::named('FOOBAR');
     $previous = new \Exception();
     $exception = new StateTransitionFailed($input, $object, $context, $nextState, $previous);
     $this->assertSame($input, $exception->getInput());
     $this->assertSame($object, $exception->getObject());
     $this->assertSame($context, $exception->getContext());
     $this->assertSame($nextState, $exception->getNextState());
     $this->assertSame($previous, $exception->getPrevious());
 }
Exemplo n.º 5
0
 public function testExceptionsInListenersPropagateOutToApplication()
 {
     $this->expectException(\Exception::class);
     $this->expectExceptionMessage('kaboom!');
     $object = new StatefulObject();
     $object->setCurrentState(FlyweightState::named('WHITES_TURN'));
     $originalException = new \Exception('kaboom!');
     $statemachine = new Statemachine(new ChessMatchTransitionTable());
     $statemachine->before(FlyweightInput::named('WHITE_MOVES'), FlyweightState::named('WHITES_TURN'), CallbackListener::fromCallable(function (Event $event) use($originalException) {
         throw $originalException;
     }));
     $statemachine->trigger(FlyweightInput::named('WHITE_MOVES'), $object);
 }
Exemplo n.º 6
0
 /**
  * Returns events to be emitted whenever a state transition is attempted
  *
  * @param Input $input
  * @param State $currentState
  *
  * @return Generator
  */
 private function eventProvider(Input $input, State $currentState) : Generator
 {
     $anyInput = FlyweightInput::any();
     $anyState = FlyweightState::any();
     (yield Event::named($this->getEventName('before', $input, $currentState)));
     (yield Event::named($this->getEventName('before', $anyInput, $currentState)));
     (yield Event::named($this->getEventName('before', $input, $anyState)));
     (yield Event::named($this->getEventName('before', $anyInput, $anyState)));
     (yield Event::named($this->getEventName('on', $anyInput, $anyState)));
     (yield Event::named($this->getEventName('after', $input, $currentState)));
     (yield Event::named($this->getEventName('after', $anyInput, $currentState)));
     (yield Event::named($this->getEventName('after', $input, $anyState)));
     (yield Event::named($this->getEventName('after', $anyInput, $anyState)));
 }