Skip to content

Commit 1838f00

Browse files
committed
Implement ElseIf
1 parent 12e4b6c commit 1838f00

5 files changed

Lines changed: 484 additions & 33 deletions

File tree

FunctionalStateMachine.Core.Tests/StateMachineConditionalTests.cs

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,187 @@ public void If_ElseBranchExecutesWhenPredicateIsFalse()
4343
Assert.Equal("Need:3", ((LogCommand)commands[0]).Message);
4444
}
4545

46+
[Fact]
47+
public void ElseIf_FirstConditionMatches()
48+
{
49+
var machine = StateMachine<State, Trigger, Data, CommandBase>.Create()
50+
.For(State.Ready)
51+
.On<Trigger.PayTrigger>()
52+
.If((data, trigger) => trigger.Amount >= 20m)
53+
.Execute(() => new LogCommand("Premium"))
54+
.ElseIf((data, trigger) => trigger.Amount >= 10m)
55+
.Execute(() => new LogCommand("Standard"))
56+
.ElseIf((data, trigger) => trigger.Amount >= 5m)
57+
.Execute(() => new LogCommand("Basic"))
58+
.Else()
59+
.Execute(() => new LogCommand("Minimum"))
60+
.Done()
61+
.Build();
62+
var currentState = State.Ready;
63+
var currentData = new Data(0m);
64+
65+
var (_, _, commands) = machine.Fire(new Trigger.PayTrigger(25m), currentState, currentData);
66+
67+
Assert.Single(commands);
68+
Assert.Equal("Premium", ((LogCommand)commands[0]).Message);
69+
}
70+
71+
[Fact]
72+
public void ElseIf_SecondConditionMatches()
73+
{
74+
var machine = StateMachine<State, Trigger, Data, CommandBase>.Create()
75+
.For(State.Ready)
76+
.On<Trigger.PayTrigger>()
77+
.If((data, trigger) => trigger.Amount >= 20m)
78+
.Execute(() => new LogCommand("Premium"))
79+
.ElseIf((data, trigger) => trigger.Amount >= 10m)
80+
.Execute(() => new LogCommand("Standard"))
81+
.ElseIf((data, trigger) => trigger.Amount >= 5m)
82+
.Execute(() => new LogCommand("Basic"))
83+
.Else()
84+
.Execute(() => new LogCommand("Minimum"))
85+
.Done()
86+
.Build();
87+
var currentState = State.Ready;
88+
var currentData = new Data(0m);
89+
90+
var (_, _, commands) = machine.Fire(new Trigger.PayTrigger(15m), currentState, currentData);
91+
92+
Assert.Single(commands);
93+
Assert.Equal("Standard", ((LogCommand)commands[0]).Message);
94+
}
95+
96+
[Fact]
97+
public void ElseIf_ThirdConditionMatches()
98+
{
99+
var machine = StateMachine<State, Trigger, Data, CommandBase>.Create()
100+
.For(State.Ready)
101+
.On<Trigger.PayTrigger>()
102+
.If((data, trigger) => trigger.Amount >= 20m)
103+
.Execute(() => new LogCommand("Premium"))
104+
.ElseIf((data, trigger) => trigger.Amount >= 10m)
105+
.Execute(() => new LogCommand("Standard"))
106+
.ElseIf((data, trigger) => trigger.Amount >= 5m)
107+
.Execute(() => new LogCommand("Basic"))
108+
.Else()
109+
.Execute(() => new LogCommand("Minimum"))
110+
.Done()
111+
.Build();
112+
var currentState = State.Ready;
113+
var currentData = new Data(0m);
114+
115+
var (_, _, commands) = machine.Fire(new Trigger.PayTrigger(7m), currentState, currentData);
116+
117+
Assert.Single(commands);
118+
Assert.Equal("Basic", ((LogCommand)commands[0]).Message);
119+
}
120+
121+
[Fact]
122+
public void ElseIf_ElseExecutesWhenNoConditionMatches()
123+
{
124+
var machine = StateMachine<State, Trigger, Data, CommandBase>.Create()
125+
.For(State.Ready)
126+
.On<Trigger.PayTrigger>()
127+
.If((data, trigger) => trigger.Amount >= 20m)
128+
.Execute(() => new LogCommand("Premium"))
129+
.ElseIf((data, trigger) => trigger.Amount >= 10m)
130+
.Execute(() => new LogCommand("Standard"))
131+
.ElseIf((data, trigger) => trigger.Amount >= 5m)
132+
.Execute(() => new LogCommand("Basic"))
133+
.Else()
134+
.Execute(() => new LogCommand("Minimum"))
135+
.Done()
136+
.Build();
137+
var currentState = State.Ready;
138+
var currentData = new Data(0m);
139+
140+
var (_, _, commands) = machine.Fire(new Trigger.PayTrigger(2m), currentState, currentData);
141+
142+
Assert.Single(commands);
143+
Assert.Equal("Minimum", ((LogCommand)commands[0]).Message);
144+
}
145+
146+
[Fact]
147+
public void ElseIf_WithModifyData()
148+
{
149+
var machine = StateMachine<State, Trigger, Data, CommandBase>.Create()
150+
.For(State.Ready)
151+
.On<Trigger.PayTrigger>()
152+
.If((data, trigger) => trigger.Amount >= 20m)
153+
.ModifyData(data => data with { Total = data.Total + 100 })
154+
.Execute(data => new LogCommand($"Total:{data.Total}"))
155+
.ElseIf((data, trigger) => trigger.Amount >= 10m)
156+
.ModifyData(data => data with { Total = data.Total + 50 })
157+
.Execute(data => new LogCommand($"Total:{data.Total}"))
158+
.Else()
159+
.ModifyData(data => data with { Total = data.Total + 10 })
160+
.Execute(data => new LogCommand($"Total:{data.Total}"))
161+
.Done()
162+
.Build();
163+
var currentState = State.Ready;
164+
var currentData = new Data(0m);
165+
166+
var (_, newData, commands) = machine.Fire(new Trigger.PayTrigger(15m), currentState, currentData);
167+
168+
Assert.Single(commands);
169+
Assert.Equal("Total:50", ((LogCommand)commands[0]).Message);
170+
Assert.Equal(50m, newData.Total);
171+
}
172+
173+
[Fact]
174+
public void ElseIf_OnSpecificTriggerType()
175+
{
176+
var machine = StateMachine<State, Trigger, Data, CommandBase>.Create()
177+
.For(State.Ready)
178+
.On<Trigger.PayTrigger>()
179+
.If((data, trigger) => trigger.Amount >= 10m)
180+
.Execute(() => new LogCommand("Large"))
181+
.ElseIf((data, trigger) => trigger.Amount >= 5m)
182+
.Execute(() => new LogCommand("Medium"))
183+
.Else()
184+
.Execute(() => new LogCommand("Small"))
185+
.Done()
186+
.Build();
187+
var currentState = State.Ready;
188+
var currentData = new Data(0m);
189+
190+
var result1 = machine.Fire(new Trigger.PayTrigger(3m), currentState, currentData);
191+
var result2 = machine.Fire(new Trigger.PayTrigger(7m), currentState, currentData);
192+
var result3 = machine.Fire(new Trigger.PayTrigger(15m), currentState, currentData);
193+
194+
Assert.Equal("Small", ((LogCommand)result1.Commands[0]).Message);
195+
Assert.Equal("Medium", ((LogCommand)result2.Commands[0]).Message);
196+
Assert.Equal("Large", ((LogCommand)result3.Commands[0]).Message);
197+
}
198+
199+
[Fact]
200+
public void ElseIf_StopsAtFirstMatch()
201+
{
202+
var executionLog = new List<string>();
203+
204+
var machine = StateMachine<State, Trigger, Data, CommandBase>.Create()
205+
.For(State.Ready)
206+
.On<Trigger.PayTrigger>()
207+
.If((data, trigger) => { executionLog.Add("If"); return trigger.Amount >= 10m; })
208+
.Execute(() => new LogCommand("First"))
209+
.ElseIf((data, trigger) => { executionLog.Add("ElseIf1"); return trigger.Amount >= 5m; })
210+
.Execute(() => new LogCommand("Second"))
211+
.ElseIf((data, trigger) => { executionLog.Add("ElseIf2"); return trigger.Amount >= 1m; })
212+
.Execute(() => new LogCommand("Third"))
213+
.Done()
214+
.Build();
215+
var currentState = State.Ready;
216+
var currentData = new Data(0m);
217+
218+
executionLog.Clear();
219+
var (_, _, commands) = machine.Fire(new Trigger.PayTrigger(7m), currentState, currentData);
220+
221+
Assert.Equal("Second", ((LogCommand)commands[0]).Message);
222+
Assert.Contains("If", executionLog);
223+
Assert.Contains("ElseIf1", executionLog);
224+
Assert.DoesNotContain("ElseIf2", executionLog);
225+
}
226+
46227
private enum State
47228
{
48229
Ready

0 commit comments

Comments
 (0)