77
88namespace Star \Component \State ;
99
10- use PHPUnit \Framework \MockObject \MockObject ;
1110use PHPUnit \Framework \TestCase ;
1211use Star \Component \State \Event \StateEventStore ;
1312use Star \Component \State \Event \TransitionWasFailed ;
1413use Star \Component \State \Event \TransitionWasSuccessful ;
1514use Star \Component \State \Event \TransitionWasRequested ;
15+ use Star \Component \State \Stub \EventRegistrySpy ;
1616use Star \Component \State \Transitions \OneToOneTransition ;
17+ use stdClass ;
18+ use Throwable ;
1719
1820final class StateMachineTest extends TestCase
1921{
2022 private TransitionRegistry $ registry ;
2123 private StateMachine $ machine ;
2224 private TestContext $ context ;
23- /**
24- * @var MockObject|EventRegistry
25- */
26- private $ listeners ;
25+ private EventRegistrySpy $ events ;
2726
2827 public function setUp (): void
2928 {
30- $ this ->listeners = $ this -> createMock (EventRegistry::class );
29+ $ this ->events = new EventRegistrySpy ( );
3130 $ this ->context = new TestContext ();
3231 $ this ->registry = new TransitionRegistry ();
33- $ this ->machine = new StateMachine ('current ' , $ this ->registry , $ this ->listeners );
32+ $ this ->machine = new StateMachine ('current ' , $ this ->registry , $ this ->events );
3433 }
3534
3635 public function test_it_should_not_allow_to_transition_to_a_not_configured_transition (): void
@@ -52,30 +51,22 @@ public function test_it_should_transition_from_one_state_to_the_other(): void
5251
5352 public function test_it_should_trigger_an_event_before_any_transition (): void
5453 {
55- $ this ->listeners
56- ->expects ($ this ->at (0 ))
57- ->method ('dispatch ' )
58- ->with (
59- StateEventStore::BEFORE_TRANSITION ,
60- $ this ->isInstanceOf (TransitionWasRequested::class)
61- );
62-
6354 $ this ->registry ->addTransition (new OneToOneTransition ('name ' , 'current ' , 'next ' ));
6455 $ this ->machine ->transit ('name ' , $ this ->context );
56+ $ name = StateEventStore::BEFORE_TRANSITION ;
57+ $ events = $ this ->events ->getDispatchedEvents ($ name );
58+ self ::assertCount (1 , $ events );
59+ self ::assertContainsOnlyInstancesOf (TransitionWasRequested::class, $ events );
6560 }
6661
6762 public function test_it_should_trigger_an_event_after_any_transition (): void
6863 {
69- $ this ->listeners
70- ->expects ($ this ->at (1 ))
71- ->method ('dispatch ' )
72- ->with (
73- StateEventStore::AFTER_TRANSITION ,
74- $ this ->isInstanceOf (TransitionWasSuccessful::class)
75- );
76-
7764 $ this ->registry ->addTransition (new OneToOneTransition ('name ' , 'current ' , 'next ' ));
7865 $ this ->machine ->transit ('name ' , $ this ->context );
66+ $ name = StateEventStore::AFTER_TRANSITION ;
67+ $ events = $ this ->events ->getDispatchedEvents ($ name );
68+ self ::assertCount (1 , $ events );
69+ self ::assertContainsOnlyInstancesOf (TransitionWasSuccessful::class, $ events );
7970 }
8071
8172 public function test_it_should_throw_exception_with_class_context_when_transition_not_allowed (): void
@@ -87,7 +78,7 @@ public function test_it_should_throw_exception_with_class_context_when_transitio
8778 $ this ->expectExceptionMessage (
8879 "The transition 't' is not allowed when context 'stdClass' is in state 'current'. "
8980 );
90- $ this ->machine ->transit ('t ' , new \ stdClass );
81+ $ this ->machine ->transit ('t ' , new stdClass );
9182 }
9283
9384 public function test_it_should_throw_exception_with_context_as_string_when_transition_not_allowed (): void
@@ -112,7 +103,7 @@ public function test_state_can_have_attribute(): void
112103 public function test_it_should_visit_the_transitions (): void
113104 {
114105 $ registry = $ this ->createMock (StateRegistry::class);
115- $ machine = new StateMachine ('' , $ registry , $ this ->listeners );
106+ $ machine = new StateMachine ('' , $ registry , $ this ->events );
116107 $ visitor = $ this ->createMock (TransitionVisitor::class);
117108
118109 $ registry
@@ -131,20 +122,18 @@ public function test_it_should_throw_exception_when_state_do_not_exists(): void
131122
132123 public function test_it_should_dispatch_an_event_before_a_transition_has_failed (): void
133124 {
134- $ this ->listeners
135- ->expects ($ this ->at (1 ))
136- ->method ('dispatch ' )
137- ->with (
138- StateEventStore::FAILURE_TRANSITION ,
139- $ this ->isInstanceOf (TransitionWasFailed::class)
140- );
141-
142125 $ this ->registry ->addTransition (new OneToOneTransition ('t ' , 'from ' , 'to ' ));
143126 try {
144127 $ this ->machine ->transit ('t ' , 'context ' );
145128 $ this ->fail ('An exception should have been thrown ' );
146- } catch (InvalidStateTransitionException $ exception ) {
129+ } catch (Throwable $ exception ) {
147130 // silence it
131+ self ::assertInstanceOf (InvalidStateTransitionException::class, $ exception );
148132 }
133+
134+ $ name = StateEventStore::FAILURE_TRANSITION ;
135+ $ events = $ this ->events ->getDispatchedEvents ($ name );
136+ self ::assertCount (1 , $ events );
137+ self ::assertContainsOnlyInstancesOf (TransitionWasFailed::class, $ events );
149138 }
150139}
0 commit comments