Skip to content

Commit 181ce88

Browse files
committed
Add some more tests detecting potential multiple transitions
1 parent bd44bba commit 181ce88

2 files changed

Lines changed: 80 additions & 0 deletions

File tree

FunctionalStateMachine.Core.Tests/StateMachineAnalysisTests.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,64 @@ public void Validate_DetectsMultipleTransitionToInSameTransition()
257257
Assert.Contains("TransitionTo", exception.Message, StringComparison.OrdinalIgnoreCase);
258258
}
259259

260+
[Fact]
261+
public void Validate_DetectsTransitionToAfterConditionalChain()
262+
{
263+
var exception = Assert.Throws<InvalidOperationException>(() =>
264+
{
265+
var machine = StateMachine<State, Trigger, Data, CommandBase>.Create()
266+
.StartWith(State.A)
267+
.For(State.A)
268+
.On<Trigger.T1>()
269+
.If(data => data.Value > 5)
270+
.TransitionTo(State.B)
271+
.Else()
272+
.Execute(() => new Command.Noop())
273+
.Done()
274+
.TransitionTo(State.C)
275+
.For(State.B)
276+
.On<Trigger.T1>()
277+
.TransitionTo(State.A)
278+
.For(State.C)
279+
.On<Trigger.T1>()
280+
.TransitionTo(State.A)
281+
.Build();
282+
});
283+
284+
Assert.Contains("TransitionTo", exception.Message, StringComparison.OrdinalIgnoreCase);
285+
}
286+
287+
[Fact]
288+
public void Validate_DetectsTransitionToInTwoConditionalChains()
289+
{
290+
var exception = Assert.Throws<InvalidOperationException>(() =>
291+
{
292+
var machine = StateMachine<State, Trigger, Data, CommandBase>.Create()
293+
.StartWith(State.A)
294+
.For(State.A)
295+
.On<Trigger.T1>()
296+
.If(data => data.Value > 5)
297+
.TransitionTo(State.B)
298+
.Else()
299+
.Execute(() => new Command.Noop())
300+
.Done()
301+
.If(data => data.Value > 1)
302+
.TransitionTo(State.C)
303+
.Else()
304+
.Execute(() => new Command.Noop())
305+
.Done()
306+
.For(State.B)
307+
.On<Trigger.T1>()
308+
.TransitionTo(State.A)
309+
.For(State.C)
310+
.On<Trigger.T1>()
311+
.TransitionTo(State.A)
312+
.Build();
313+
});
314+
315+
Assert.Contains("TransitionTo", exception.Message, StringComparison.OrdinalIgnoreCase);
316+
}
317+
260318
[Fact]
261319
public void Validate_AllowsComplexReachableStateMachine()
262320
{

docs/conditional-steps.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,28 @@ var machine = StateMachine<State, Trigger, Data, Command>.Create()
7878

7979
With multiple ElseIf conditions, only the first matching branch executes. If no condition matches and there's no Else, nothing happens.
8080

81+
## Multiple conditional chains with TransitionTo
82+
83+
If you use multiple conditional chains within the same transition, only one chain may contain a TransitionTo.
84+
85+
```csharp
86+
var machine = StateMachine<State, Trigger, Data, Command>.Create()
87+
.StartWith(State.Pending)
88+
.For(State.Pending)
89+
.On<Trigger.Submit>()
90+
.If(data => data.IsValid)
91+
.TransitionTo(State.Approved)
92+
.Else()
93+
.Execute(() => new Command.LogRejected())
94+
.Done()
95+
.If(data => data.IsHighPriority)
96+
.TransitionTo(State.Escalated) // ❌ second TransitionTo in same transition
97+
.Else()
98+
.Execute(() => new Command.LogPriority())
99+
.Done()
100+
.Build();
101+
```
102+
81103
## Using with ModifyData
82104

83105
Conditional data modifications work seamlessly:

0 commit comments

Comments
 (0)