Skip to content

Commit 3baad9e

Browse files
Tetragramatlyrixx
authored andcommitted
method buildTransitionBlockerList returns TransitionBlockerList of expected transition
1 parent c22c5de commit 3baad9e

File tree

3 files changed

+119
-12
lines changed

3 files changed

+119
-12
lines changed

Tests/StateMachineTest.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
namespace Symfony\Component\Workflow\Tests;
44

55
use PHPUnit\Framework\TestCase;
6+
use Symfony\Component\EventDispatcher\EventDispatcher;
7+
use Symfony\Component\Workflow\Event\GuardEvent;
68
use Symfony\Component\Workflow\StateMachine;
9+
use Symfony\Component\Workflow\TransitionBlocker;
710

811
class StateMachineTest extends TestCase
912
{
@@ -38,4 +41,68 @@ public function testCanWithMultipleTransition()
3841
$this->assertTrue($net->can($subject, 't2'));
3942
$this->assertTrue($net->can($subject, 't3'));
4043
}
44+
45+
public function testBuildTransitionBlockerList()
46+
{
47+
$definition = $this->createComplexStateMachineDefinition();
48+
49+
$net = new StateMachine($definition);
50+
$subject = new \stdClass();
51+
52+
$subject->marking = 'a';
53+
$this->assertTrue($net->buildTransitionBlockerList($subject, 't1')->isEmpty());
54+
$subject->marking = 'd';
55+
$this->assertTrue($net->buildTransitionBlockerList($subject, 't1')->isEmpty());
56+
57+
$subject->marking = 'b';
58+
$this->assertFalse($net->buildTransitionBlockerList($subject, 't1')->isEmpty());
59+
}
60+
61+
public function testBuildTransitionBlockerListWithMultipleTransitions()
62+
{
63+
$definition = $this->createComplexStateMachineDefinition();
64+
65+
$net = new StateMachine($definition);
66+
$subject = new \stdClass();
67+
68+
$subject->marking = 'b';
69+
$this->assertTrue($net->buildTransitionBlockerList($subject, 't2')->isEmpty());
70+
$this->assertTrue($net->buildTransitionBlockerList($subject, 't3')->isEmpty());
71+
}
72+
73+
public function testBuildTransitionBlockerListReturnsExpectedReasonOnBranchMerge()
74+
{
75+
$definition = $this->createComplexStateMachineDefinition();
76+
77+
$dispatcher = new EventDispatcher();
78+
$net = new StateMachine($definition, null, $dispatcher);
79+
80+
$dispatcher->addListener('workflow.guard', function (GuardEvent $event) {
81+
$event->addTransitionBlocker(new TransitionBlocker(\sprintf('Transition blocker of place %s', $event->getTransition()->getFroms()[0]), 'blocker'));
82+
});
83+
84+
$subject = new \stdClass();
85+
86+
// There may be multiple transitions with the same name. Make sure that transitions
87+
// that are not enabled by the marking are evaluated.
88+
// see https://github.com/symfony/symfony/issues/28432
89+
90+
// Test if when you are in place "a" applying transition "t1" then returned blocker list contains guard blocker instead blockedByMarking
91+
$subject->marking = 'a';
92+
$transitionBlockerList = $net->buildTransitionBlockerList($subject, 't1');
93+
$this->assertCount(1, $transitionBlockerList);
94+
$blockers = iterator_to_array($transitionBlockerList);
95+
96+
$this->assertSame('Transition blocker of place a', $blockers[0]->getMessage());
97+
$this->assertSame('blocker', $blockers[0]->getCode());
98+
99+
// Test if when you are in place "d" applying transition "t1" then returned blocker list contains guard blocker instead blockedByMarking
100+
$subject->marking = 'd';
101+
$transitionBlockerList = $net->buildTransitionBlockerList($subject, 't1');
102+
$this->assertCount(1, $transitionBlockerList);
103+
$blockers = iterator_to_array($transitionBlockerList);
104+
105+
$this->assertSame('Transition blocker of place d', $blockers[0]->getMessage());
106+
$this->assertSame('blocker', $blockers[0]->getCode());
107+
}
41108
}

Tests/WorkflowTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,32 @@ public function testBuildTransitionBlockerListReturnsUndefinedTransition()
195195
$workflow->buildTransitionBlockerList($subject, '404 Not Found');
196196
}
197197

198+
public function testBuildTransitionBlockerList()
199+
{
200+
$definition = $this->createComplexWorkflowDefinition();
201+
$subject = new \stdClass();
202+
$subject->marking = null;
203+
$workflow = new Workflow($definition, new MultipleStateMarkingStore());
204+
205+
$this->assertTrue($workflow->buildTransitionBlockerList($subject, 't1')->isEmpty());
206+
$this->assertFalse($workflow->buildTransitionBlockerList($subject, 't2')->isEmpty());
207+
208+
$subject->marking = array('b' => 1);
209+
210+
$this->assertFalse($workflow->buildTransitionBlockerList($subject, 't1')->isEmpty());
211+
$this->assertFalse($workflow->buildTransitionBlockerList($subject, 't2')->isEmpty());
212+
213+
$subject->marking = array('b' => 1, 'c' => 1);
214+
215+
$this->assertFalse($workflow->buildTransitionBlockerList($subject, 't1')->isEmpty());
216+
$this->assertTrue($workflow->buildTransitionBlockerList($subject, 't2')->isEmpty());
217+
218+
$subject->marking = array('f' => 1);
219+
220+
$this->assertFalse($workflow->buildTransitionBlockerList($subject, 't5')->isEmpty());
221+
$this->assertTrue($workflow->buildTransitionBlockerList($subject, 't6')->isEmpty());
222+
}
223+
198224
public function testBuildTransitionBlockerListReturnsReasonsProvidedByMarking()
199225
{
200226
$definition = $this->createComplexWorkflowDefinition();

Workflow.php

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,11 @@ public function can($subject, $transitionName)
9292
continue;
9393
}
9494

95-
$transitionBlockerList = $this->buildTransitionBlockerListForTransition($subject, $marking, $transition);
95+
try {
96+
$transitionBlockerList = $this->buildTransitionBlockerListForTransition($subject, $marking, $transition);
97+
} catch (NotEnabledTransitionException $e) {
98+
$transitionBlockerList = $e->getTransitionBlockerList();
99+
}
96100

97101
if ($transitionBlockerList->isEmpty()) {
98102
return true;
@@ -116,10 +120,13 @@ public function buildTransitionBlockerList($subject, string $transitionName): Tr
116120
continue;
117121
}
118122

119-
$transitionBlockerList = $this->buildTransitionBlockerListForTransition($subject, $marking, $transition);
123+
try {
124+
$transitionBlockerList = $this->buildTransitionBlockerListForTransition($subject, $marking, $transition);
120125

121-
if ($transitionBlockerList->isEmpty()) {
122-
continue;
126+
return $transitionBlockerList;
127+
} catch (NotEnabledTransitionException $e) {
128+
// a transition with the same name is defined for other places too
129+
$transitionBlockerList = $e->getTransitionBlockerList();
123130
}
124131
}
125132

@@ -146,11 +153,15 @@ public function apply($subject, $transitionName)
146153
continue;
147154
}
148155

149-
$transitionBlockerList = $this->buildTransitionBlockerListForTransition($subject, $marking, $transition);
150-
if (!$transitionBlockerList->isEmpty()) {
151-
continue;
156+
try {
157+
$transitionBlockerList = $this->buildTransitionBlockerListForTransition($subject, $marking, $transition);
158+
} catch (NotEnabledTransitionException $e) {
159+
$transitionBlockerList = $e->getTransitionBlockerList();
160+
}
161+
162+
if ($transitionBlockerList->isEmpty()) {
163+
$approvedTransitionQueue[] = $transition;
152164
}
153-
$approvedTransitionQueue[] = $transition;
154165
}
155166

156167
foreach ($approvedTransitionQueue as $transition) {
@@ -191,7 +202,12 @@ public function getEnabledTransitions($subject)
191202
$marking = $this->getMarking($subject);
192203

193204
foreach ($this->definition->getTransitions() as $transition) {
194-
$transitionBlockerList = $this->buildTransitionBlockerListForTransition($subject, $marking, $transition);
205+
try {
206+
$transitionBlockerList = $this->buildTransitionBlockerListForTransition($subject, $marking, $transition);
207+
} catch (NotEnabledTransitionException $e) {
208+
$transitionBlockerList = $e->getTransitionBlockerList();
209+
}
210+
195211
if ($transitionBlockerList->isEmpty()) {
196212
$enabledTransitions[] = $transition;
197213
}
@@ -236,9 +252,7 @@ private function buildTransitionBlockerListForTransition($subject, Marking $mark
236252
{
237253
foreach ($transition->getFroms() as $place) {
238254
if (!$marking->has($place)) {
239-
return new TransitionBlockerList(array(
240-
TransitionBlocker::createBlockedByMarking($marking),
241-
));
255+
throw new NotEnabledTransitionException($subject, $transition->getName(), $this, new TransitionBlockerList(array(TransitionBlocker::createBlockedByMarking($marking))));
242256
}
243257
}
244258

0 commit comments

Comments
 (0)