Completed
Push — master ( 310596...ecf895 )
by Hannes
02:21
created

StateMachine::transitionTo()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3
Metric Value
dl 0
loc 18
ccs 9
cts 9
cp 1
rs 9.4285
cc 3
eloc 10
nc 3
nop 1
crap 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace byrokrat\autogiro\Parser;
6
7
use byrokrat\autogiro\Exception\InvalidStateException;
8
9
/**
10
 * Handle states and state transitions
11
 */
12
class StateMachine
13
{
14
    /**
15
     * Default init state
16
     */
17
    const STATE_INIT = 'state_init';
18
19
    /**
20
     * Done state
21
     */
22
    const STATE_DONE = 'state_done';
23
24
    /**
25
     * @var string The current state
26
     */
27
    private $currentState;
28
29
    /**
30
     * @var array Map of valid transitions
31
     */
32
    private $validTransitions;
33
34
    /**
35
     * Load initial state and define valid transitions
36
     *
37
     * Transitions are defined in an array of arrays where pre transition states
38
     * are keys in the outer array and the values of the inner arrays represent
39
     * valid post transitions states.
40
     *
41
     * @param string $initialState
42
     * @param array  $validTransitions
43
     */
44 4
    public function __construct(array $validTransitions, string $initialState = self::STATE_INIT)
45
    {
46 4
        $this->validTransitions = $validTransitions;
47 4
        $this->currentState = $initialState;
48 4
    }
49
50
    /**
51
     * Set machine in a new state
52
     *
53
     * @throws InvalidStateException If transition is not valid
54
     */
55 3
    public function transitionTo(string $newState)
56
    {
57 3
        if (!array_key_exists($this->currentState, $this->validTransitions)) {
58 1
            throw new InvalidStateException("Unexpected transaction code $newState (expecting END)");
59
        }
60
61 2
        if (!in_array($newState, $this->validTransitions[$this->currentState])) {
62 1
            throw new InvalidStateException(
63
                sprintf(
64 1
                    'Unexpected transaction code %s (expecting one of [%s])',
65
                    $newState,
66 1
                    implode($this->validTransitions[$this->currentState], ', ')
67
                )
68
            );
69
        }
70
71 1
        $this->currentState = $newState;
72 1
    }
73
74
    /**
75
     * Get current state
76
     */
77 2
    public function getState(): string
78
    {
79 2
        return $this->currentState;
80
    }
81
}
82