Skip to content

Commit 10fba96

Browse files
committed
further tests implemented, updated documentation, Machine::runOnce() added
1 parent b07cafa commit 10fba96

5 files changed

Lines changed: 133 additions & 17 deletions

File tree

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# CHANGELOG
2+
3+
## dev-master
4+
5+
- `MachineTest`: more detailed tests implemented
6+
- added installation procedure to README.md
7+
- added `MachineInterface::runOnce()` and `Machine::runOnce()` to allow just one pass over possible transitions
8+
- started actual CHANGELOG.md
9+
- small fix for example used in documentation (missing `$machine->init()` call)
10+
- implemented tests for assertion classes
11+
- updated and extended documentation (README.md)
12+
13+
## v0.3
14+
15+
- README.md updated
16+
- created CODE_OF_CONDUCT.md
17+
- created CONTRIBUTING.md
18+
19+
## v0.2
20+
21+
- defined php version requirements
22+
- fixed `Machine::setMachineState()` behavior with exactly same state given in param
23+
- implemented basic tests
24+
25+
## v0.1
26+
27+
- basic functionality and architecture implementation, first working version

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@ dynamically and launch. You can define state transition conditions you want base
77
anonymous functions or class methods. Fire events on each state transition with your favorite
88
event dispatcher.
99

10+
## Installation
11+
12+
Easiest way is to use composer:
13+
14+
```bash
15+
$ composer require coff/state-machine-framework
16+
```
17+
18+
Alternatively just clone repository:
19+
```bash
20+
$ git clone https://github.com/coff/php-state-machine-framework.git
21+
```
22+
23+
and then checkout specific tag:
24+
```bash
25+
$ git checkout tags/v0.3
26+
```
1027

1128
## Usage example
1229

src/Machine.php

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -214,30 +214,42 @@ public function assertTransition(Transition $transition): bool
214214
*/
215215
public function run()
216216
{
217-
218217
do {
219-
$result = false;
218+
$result = $this->runOnce();
219+
220+
} while (true == $result);
221+
222+
return $this->machineState;
223+
}
224+
225+
/**
226+
* Makes one pass through transitions available in current state
227+
*
228+
* @return boolean
229+
* @throws TransitionException
230+
*/
231+
public function runOnce(): bool
232+
{
233+
$result = false;
220234

221-
$allowedTrans = $this->getAllowedTransitions();
235+
$allowedTrans = $this->getAllowedTransitions();
222236

223-
/**
224-
* @var StateEnum $nextState
225-
* @var Transition $transition
226-
*/
227-
foreach ($allowedTrans as $nextState => $transition) {
237+
/**
238+
* @var StateEnum $nextState
239+
* @var Transition $transition
240+
*/
241+
foreach ($allowedTrans as $nextState => $transition) {
228242

229-
$result = $transition->assert();
243+
$result = $transition->assert();
230244

231-
if (true === $result) {
232-
$this->machineState = $transition->getToState();
245+
if (true === $result) {
246+
$this->machineState = $transition->getToState();
233247

234-
$this->onTransition($transition);
235-
}
248+
$this->onTransition($transition);
236249
}
250+
}
237251

238-
} while (true == $result);
239-
240-
return $this->machineState;
252+
return $result;
241253
}
242254

243255
/**

src/MachineInterface.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Coff\SMF;
44

5+
use Coff\SMF\Exception\TransitionException;
56
use Coff\SMF\Transition\Transition;
67

78
interface MachineInterface
@@ -48,8 +49,15 @@ public function onTransition(Transition $transition);
4849

4950
/**
5051
* Runs state machine. Performs assertions for all transitions defined for current state.
51-
* @return mixed
5252
*/
5353
public function run();
5454

55+
/**
56+
* Makes one pass through transitions available in current state, makes assertions and eventually changes state
57+
*
58+
* @return boolean
59+
* @throws TransitionException
60+
*/
61+
public function runOnce(): bool;
62+
5563
}

tests/MachineTest.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,29 @@ public function test_isTransitionAllowed_same()
168168
* @depends test_setInitState
169169
* @depends test_allowTransition
170170
* @throws TransitionException
171+
* @throws MachineException
171172
*/
172173
public function test_run_automatic_transition_through_n_states_succ()
173174
{
175+
$this->machine = $this->createPartialMock(SampleMachine::class, ['onTransition']);
176+
174177
$this->machine->setInitState($this->x);
175178

176179
$this->machine->allowTransition($this->x, $this->y, new AlwaysTrueAssertion());
177180
$this->machine->allowTransition($this->y, $this->z, new AlwaysTrueAssertion());
178181

182+
183+
$transition1 = $this->machine->getTransition($this->x, $this->y);
184+
$transition2 = $this->machine->getTransition($this->y, $this->z);
185+
186+
$this->machine->expects($this->at(0))
187+
->method('onTransition')
188+
->with($this->equalTo($transition1));
189+
190+
$this->machine->expects($this->at(1))
191+
->method('onTransition')
192+
->with($this->equalTo($transition2));
193+
179194
$this->machine->run();
180195

181196
$this->assertTrue($this->machine->isMachineState($this->z));
@@ -186,14 +201,51 @@ public function test_run_automatic_transition_through_n_states_succ()
186201
* @depends test_setInitState
187202
* @depends test_allowTransition
188203
* @throws TransitionException
204+
* @throws MachineException
205+
*/
206+
public function test_runOnce_automatic_transition_through_1_state_succ()
207+
{
208+
$this->machine = $this->createPartialMock(SampleMachine::class, ['onTransition']);
209+
210+
$this->machine->setInitState($this->x);
211+
212+
$this->machine->allowTransition($this->x, $this->y, new AlwaysTrueAssertion());
213+
$this->machine->allowTransition($this->y, $this->z, new AlwaysTrueAssertion());
214+
215+
$transition = $this->machine->getTransition($this->x, $this->y);
216+
217+
$this->machine->expects($this->once())
218+
->method('onTransition')
219+
->with($this->equalTo($transition));
220+
221+
222+
$this->machine->runOnce();
223+
224+
$this->assertTrue($this->machine->isMachineState($this->y));
225+
226+
}
227+
228+
/**
229+
* @depends test_setInitState
230+
* @depends test_allowTransition
231+
* @throws TransitionException
232+
* @throws MachineException
189233
*/
190234
public function test_run_automatic_transition_through_n_states_stops()
191235
{
236+
$this->machine = $this->createPartialMock(SampleMachine::class, ['onTransition']);
237+
192238
$this->machine->setInitState($this->x);
193239

194240
$this->machine->allowTransition($this->x, $this->y, new AlwaysTrueAssertion());
195241
$this->machine->allowTransition($this->y, $this->z, new AlwaysFalseAssertion());
196242

243+
$transition1 = $this->machine->getTransition($this->x, $this->y);
244+
245+
$this->machine->expects($this->once())
246+
->method('onTransition')
247+
->with($this->equalTo($transition1));
248+
197249
$this->machine->run();
198250

199251
$this->assertFalse($this->machine->isMachineState($this->z));

0 commit comments

Comments
 (0)