Skip to content

Commit d866209

Browse files
authored
Merge pull request #841 from 7474/unit-tests/loop-else-clearobj-20260307-08a81843f14dd184
[unit-tests] ユニットテスト補完: ElseCmd/ElseIfCmd/EndIfCmd/LoopCmd/NextCmd/ClearObjCmd/SelectCmd/EscapeCmd
2 parents 4d5c1c1 + 9db7ac2 commit d866209

File tree

3 files changed

+484
-3
lines changed

3 files changed

+484
-3
lines changed
Lines changed: 363 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,363 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using SRCCore.CmdDatas;
3+
using SRCCore.CmdDatas.Commands;
4+
using SRCCore.Events;
5+
using SRCCore.TestLib;
6+
using System.Collections.Generic;
7+
8+
namespace SRCCore.CmdDatas.Tests
9+
{
10+
/// <summary>
11+
/// ElseCmd / ElseIfCmd / EndIfCmd / LoopCmd / NextCmd のユニットテスト
12+
/// ヘルプの記載に基づく期待値を検証する
13+
/// </summary>
14+
[TestClass]
15+
public class ElseIfLoopNextCmdTests
16+
{
17+
private SRC CreateSrc()
18+
{
19+
var src = new SRC { GUI = new MockGUI() };
20+
src.Event.EventData = new List<EventDataLine>();
21+
src.Event.EventCmd = new List<CmdData>();
22+
src.Event.EventFileNames = new List<string>();
23+
src.Event.AdditionalEventFileNames = new List<string>();
24+
src.Event.EventQue = new System.Collections.Generic.Queue<string>();
25+
return src;
26+
}
27+
28+
private CmdData[] BuildEvent(SRC src, params string[] lines)
29+
{
30+
var parser = new CmdParser();
31+
var cmds = new CmdData[lines.Length];
32+
for (var i = 0; i < lines.Length; i++)
33+
{
34+
var line = new EventDataLine(i, EventDataSource.Scenario, "test", i, lines[i]);
35+
src.Event.EventData.Add(line);
36+
var cmd = parser.Parse(src, line);
37+
src.Event.EventCmd.Add(cmd);
38+
cmds[i] = cmd;
39+
}
40+
return cmds;
41+
}
42+
43+
private void RunEvent(SRC src, CmdData[] cmds, int startId = 0, int maxSteps = 1000)
44+
{
45+
var current = startId;
46+
for (var step = 0; step < maxSteps && current >= 0 && current < cmds.Length; step++)
47+
{
48+
current = cmds[current].Exec();
49+
}
50+
}
51+
52+
// ──────────────────────────────────────────────
53+
// ElseCmd
54+
// ──────────────────────────────────────────────
55+
56+
[TestMethod]
57+
public void ElseCmd_ReachedAfterTrueBranch_SkipsToEndIf()
58+
{
59+
// ヘルプ: Else コマンドは直前の If や ElseIf が True だった場合、EndIf まで処理をスキップする
60+
var src = CreateSrc();
61+
src.Expression.SetVariableAsDouble("x", 1d);
62+
63+
// If (x > 0) Then
64+
// Set branch "then"
65+
// Else ← reached after true If, should skip to EndIf
66+
// Set branch "else"
67+
// EndIf
68+
var cmds = BuildEvent(src,
69+
"If (x > 0) Then", // ID=0: true
70+
"Set branch \"then\"", // ID=1: executed
71+
"Else", // ID=2: skips to EndIf
72+
"Set branch \"else\"", // ID=3: skipped
73+
"EndIf" // ID=4
74+
);
75+
76+
RunEvent(src, cmds);
77+
78+
Assert.AreEqual("then", src.Expression.GetValueAsString("branch"));
79+
}
80+
81+
[TestMethod]
82+
public void ElseCmd_ReachedAfterFalseBranch_ExecutesElseBody()
83+
{
84+
// ヘルプ: If の条件が偽のとき、Else ブロックの内容が実行される
85+
var src = CreateSrc();
86+
src.Expression.SetVariableAsDouble("x", 0d);
87+
88+
var cmds = BuildEvent(src,
89+
"If (x > 0) Then", // ID=0: false → skip to Else
90+
"Set branch \"then\"", // ID=1: skipped
91+
"Else", // ID=2: entered
92+
"Set branch \"else\"", // ID=3: executed
93+
"EndIf" // ID=4
94+
);
95+
96+
RunEvent(src, cmds);
97+
98+
Assert.AreEqual("else", src.Expression.GetValueAsString("branch"));
99+
}
100+
101+
[TestMethod]
102+
public void ElseCmd_MissingEndIf_ReturnsError()
103+
{
104+
// EndIf なしのElse はエラー
105+
var src = CreateSrc();
106+
src.Expression.SetVariableAsDouble("x", 1d);
107+
108+
var cmds = BuildEvent(src,
109+
"If (x > 0) Then", // ID=0: true
110+
"Set ok 1", // ID=1
111+
"Else" // ID=2: no EndIf → error
112+
);
113+
114+
// Else が実行された時点でエラー
115+
var result = cmds[2].Exec();
116+
Assert.AreEqual(-1, result);
117+
}
118+
119+
// ──────────────────────────────────────────────
120+
// ElseIfCmd
121+
// ──────────────────────────────────────────────
122+
123+
[TestMethod]
124+
public void ElseIfCmd_ConditionTrue_ExecutesBranch()
125+
{
126+
// ヘルプ: ElseIf expression Then でelseif の条件が真のとき、続くブロックを実行する
127+
var src = CreateSrc();
128+
src.Expression.SetVariableAsDouble("x", 2d);
129+
130+
// If (x = 1) Then
131+
// Set result "one"
132+
// ElseIf (x = 2) Then
133+
// Set result "two"
134+
// EndIf
135+
var cmds = BuildEvent(src,
136+
"If (x = 1) Then", // ID=0: false
137+
"Set result \"one\"", // ID=1: skipped
138+
"ElseIf (x = 2) Then", // ID=2: true → execute this branch
139+
"Set result \"two\"", // ID=3: executed
140+
"EndIf" // ID=4
141+
);
142+
143+
RunEvent(src, cmds);
144+
145+
Assert.AreEqual("two", src.Expression.GetValueAsString("result"));
146+
}
147+
148+
[TestMethod]
149+
public void ElseIfCmd_ReachedAfterTrueBranch_SkipsToEndIf()
150+
{
151+
// ヘルプ: 直前の If が True だった場合、ElseIf は EndIf までスキップする
152+
var src = CreateSrc();
153+
src.Expression.SetVariableAsDouble("x", 1d);
154+
155+
var cmds = BuildEvent(src,
156+
"If (x = 1) Then", // ID=0: true
157+
"Set result \"one\"", // ID=1: executed
158+
"ElseIf (x = 2) Then", // ID=2: reached after true → skip
159+
"Set result \"two\"", // ID=3: skipped
160+
"EndIf" // ID=4
161+
);
162+
163+
RunEvent(src, cmds);
164+
165+
Assert.AreEqual("one", src.Expression.GetValueAsString("result"));
166+
}
167+
168+
[TestMethod]
169+
public void ElseIfCmd_MultipleChain_FirstMatchExecuted()
170+
{
171+
// ヘルプ: ElseIf を複数連ねることができ、最初にマッチしたブロックが実行される
172+
var src = CreateSrc();
173+
src.Expression.SetVariableAsDouble("x", 3d);
174+
175+
var cmds = BuildEvent(src,
176+
"If (x = 1) Then", // ID=0: false
177+
"Set result \"one\"", // ID=1: skipped
178+
"ElseIf (x = 2) Then", // ID=2: false
179+
"Set result \"two\"", // ID=3: skipped
180+
"ElseIf (x = 3) Then", // ID=4: true
181+
"Set result \"three\"", // ID=5: executed
182+
"EndIf" // ID=6
183+
);
184+
185+
RunEvent(src, cmds);
186+
187+
Assert.AreEqual("three", src.Expression.GetValueAsString("result"));
188+
}
189+
190+
// ──────────────────────────────────────────────
191+
// EndIfCmd
192+
// ──────────────────────────────────────────────
193+
194+
[TestMethod]
195+
public void EndIfCmd_ReturnsNextId()
196+
{
197+
// EndIf は処理の区切りとして次のコマンドへ進む
198+
var src = CreateSrc();
199+
200+
var cmds = BuildEvent(src,
201+
"If (1 = 1) Then", // ID=0: true
202+
"Set ok 1", // ID=1
203+
"EndIf", // ID=2
204+
"Set after 1" // ID=3
205+
);
206+
207+
RunEvent(src, cmds);
208+
209+
Assert.AreEqual(1d, src.Expression.GetValueAsDouble("ok"));
210+
Assert.AreEqual(1d, src.Expression.GetValueAsDouble("after"));
211+
}
212+
213+
// ──────────────────────────────────────────────
214+
// LoopCmd
215+
// ──────────────────────────────────────────────
216+
217+
[TestMethod]
218+
public void LoopCmd_WithoutCondition_AlwaysLoopsBack()
219+
{
220+
// ヘルプ: Loop だけの場合は無条件で Do に戻る(Break で脱出可能)
221+
var src = CreateSrc();
222+
src.Expression.SetVariableAsDouble("i", 0d);
223+
224+
// Do
225+
// Incr i
226+
// If (i = 3) Then
227+
// Break
228+
// EndIf
229+
// Loop
230+
var cmds = BuildEvent(src,
231+
"Do", // ID=0
232+
"Incr i", // ID=1
233+
"If (i = 3) Then", // ID=2
234+
"Break", // ID=3
235+
"EndIf", // ID=4
236+
"Loop" // ID=5
237+
);
238+
239+
RunEvent(src, cmds);
240+
241+
Assert.AreEqual(3d, src.Expression.GetValueAsDouble("i"));
242+
}
243+
244+
[TestMethod]
245+
public void LoopCmd_WhileConditionFalse_ExitsLoop()
246+
{
247+
// ヘルプ: Loop While expression → expression が偽になったらループ終了
248+
var src = CreateSrc();
249+
src.Expression.SetVariableAsDouble("i", 0d);
250+
251+
var cmds = BuildEvent(src,
252+
"Do", // ID=0
253+
"Incr i", // ID=1
254+
"Loop While (i < 3)" // ID=2: continues while i<3
255+
);
256+
257+
RunEvent(src, cmds);
258+
259+
Assert.AreEqual(3d, src.Expression.GetValueAsDouble("i"));
260+
}
261+
262+
[TestMethod]
263+
public void LoopCmd_UntilConditionTrue_ExitsLoop()
264+
{
265+
// ヘルプ: Loop Until expression → expression が真になったらループ終了
266+
var src = CreateSrc();
267+
src.Expression.SetVariableAsDouble("i", 0d);
268+
269+
var cmds = BuildEvent(src,
270+
"Do", // ID=0
271+
"Incr i", // ID=1
272+
"Loop Until (i >= 3)" // ID=2: exits when i>=3
273+
);
274+
275+
RunEvent(src, cmds);
276+
277+
Assert.AreEqual(3d, src.Expression.GetValueAsDouble("i"));
278+
}
279+
280+
[TestMethod]
281+
public void LoopCmd_WrongArgCount_ReturnsError()
282+
{
283+
// Loop に不正な引数はエラー
284+
var src = CreateSrc();
285+
286+
var cmds = BuildEvent(src,
287+
"Do", // ID=0
288+
"Loop Invalid arg" // ID=1: 不正
289+
);
290+
291+
var result = cmds[1].Exec();
292+
Assert.AreEqual(-1, result);
293+
}
294+
295+
[TestMethod]
296+
public void LoopCmd_MissingDo_ReturnsError()
297+
{
298+
// 対応する Do なしの Loop はエラー
299+
var src = CreateSrc();
300+
301+
var cmds = BuildEvent(src,
302+
"Loop" // ID=0: no Do → error
303+
);
304+
305+
var result = cmds[0].Exec();
306+
Assert.AreEqual(-1, result);
307+
}
308+
309+
// ──────────────────────────────────────────────
310+
// NextCmd
311+
// ──────────────────────────────────────────────
312+
313+
[TestMethod]
314+
public void NextCmd_IncrementsForLoopVariable()
315+
{
316+
// ヘルプ: Next はインデックス変数を1増やして For に戻る
317+
var src = CreateSrc();
318+
319+
var cmds = BuildEvent(src,
320+
"For i = 1 To 3", // ID=0
321+
"Incr count", // ID=1
322+
"Next" // ID=2
323+
);
324+
325+
RunEvent(src, cmds);
326+
327+
Assert.AreEqual(3d, src.Expression.GetValueAsDouble("count"));
328+
}
329+
330+
[TestMethod]
331+
public void NextCmd_ExitsWhenBeyondLimit()
332+
{
333+
// ヘルプ: インデックス変数が To の値を超えたらループ終了し Next の後へ進む
334+
var src = CreateSrc();
335+
336+
var cmds = BuildEvent(src,
337+
"For i = 1 To 2", // ID=0
338+
"Incr count", // ID=1
339+
"Next", // ID=2
340+
"Set after 1" // ID=3
341+
);
342+
343+
RunEvent(src, cmds);
344+
345+
Assert.AreEqual(2d, src.Expression.GetValueAsDouble("count"));
346+
Assert.AreEqual(1d, src.Expression.GetValueAsDouble("after"));
347+
}
348+
349+
[TestMethod]
350+
public void NextCmd_MissingFor_ReturnsError()
351+
{
352+
// 対応する For なしの Next はエラー
353+
var src = CreateSrc();
354+
355+
var cmds = BuildEvent(src,
356+
"Next" // ID=0: no For → error
357+
);
358+
359+
var result = cmds[0].Exec();
360+
Assert.AreEqual(-1, result);
361+
}
362+
}
363+
}

0 commit comments

Comments
 (0)