mirror of
https://github.com/Stone-Red-Code/YesNt-Interpreter.git
synced 2026-09-04 00:56:31 +02:00
Add tests for loop exit, local/global scope, concurrency, and string escapes
This commit is contained in:
@@ -200,6 +200,24 @@ public class CodeFlowTests
|
|||||||
YesNtAssert.IsLastLineEqual(lines, "ok");
|
YesNtAssert.IsLastLineEqual(lines, "ok");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GotoInsideLoopExitsLoopTest()
|
||||||
|
{
|
||||||
|
List<string> lines =
|
||||||
|
[
|
||||||
|
"var hit = no",
|
||||||
|
"while 1 == 1:",
|
||||||
|
"var hit = yes",
|
||||||
|
"goto done",
|
||||||
|
"end_while",
|
||||||
|
"label done:",
|
||||||
|
"${hit}"
|
||||||
|
];
|
||||||
|
|
||||||
|
YesNtAssert.IsLastLineEqual(lines, "yes");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void LabelWithoutColonFailsTest()
|
public void LabelWithoutColonFailsTest()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -132,6 +132,25 @@ public class FunctionStatementsTests
|
|||||||
YesNtAssert.ContainsTerminationMessage(lines, "Nested functions are not allowed");
|
YesNtAssert.ContainsTerminationMessage(lines, "Nested functions are not allowed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void LocalVariableDoesNotLeakToCallerTest()
|
||||||
|
{
|
||||||
|
List<string> lines =
|
||||||
|
[
|
||||||
|
"goto main",
|
||||||
|
"func modify:",
|
||||||
|
"var x = inner",
|
||||||
|
"return",
|
||||||
|
"label main:",
|
||||||
|
"var x = outer",
|
||||||
|
"call modify",
|
||||||
|
"${x}"
|
||||||
|
];
|
||||||
|
|
||||||
|
YesNtAssert.IsLastLineEqual(lines, "outer");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void ClearCallStackRunsTest()
|
public void ClearCallStackRunsTest()
|
||||||
{
|
{
|
||||||
@@ -144,5 +163,66 @@ public class FunctionStatementsTests
|
|||||||
|
|
||||||
YesNtAssert.IsLastLineEqual(lines, "ok");
|
YesNtAssert.IsLastLineEqual(lines, "ok");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Error path tests ---
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AccessInWithoutArgFailsTest()
|
||||||
|
{
|
||||||
|
List<string> lines =
|
||||||
|
[
|
||||||
|
"goto main",
|
||||||
|
"func noin:",
|
||||||
|
"var x = %in",
|
||||||
|
"return",
|
||||||
|
"label main:",
|
||||||
|
"call noin"
|
||||||
|
];
|
||||||
|
|
||||||
|
YesNtAssert.ContainsTerminationMessage(lines, "No in argument in stack");
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Nested scope tests ---
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GlobalModifiedInsideFunctionIsVisibleAfterReturnTest()
|
||||||
|
{
|
||||||
|
List<string> lines =
|
||||||
|
[
|
||||||
|
"goto main",
|
||||||
|
"func setglobal:",
|
||||||
|
"global shared = modified",
|
||||||
|
"return",
|
||||||
|
"label main:",
|
||||||
|
"global shared = original",
|
||||||
|
"call setglobal",
|
||||||
|
"${shared}"
|
||||||
|
];
|
||||||
|
|
||||||
|
YesNtAssert.IsLastLineEqual(lines, "modified");
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NestedFunctionCallsHaveIndependentLocalScopesTest()
|
||||||
|
{
|
||||||
|
List<string> lines =
|
||||||
|
[
|
||||||
|
"goto main",
|
||||||
|
"func outer:",
|
||||||
|
"var x = outer_val",
|
||||||
|
"call inner",
|
||||||
|
"push_out ${x}",
|
||||||
|
"return",
|
||||||
|
"func inner:",
|
||||||
|
"var x = inner_val",
|
||||||
|
"return",
|
||||||
|
"label main:",
|
||||||
|
"call outer",
|
||||||
|
"var result = %out",
|
||||||
|
"${result}"
|
||||||
|
];
|
||||||
|
|
||||||
|
YesNtAssert.IsLastLineEqual(lines, "outer_val");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,32 @@ public class ProcessingStatementsTests
|
|||||||
YesNtAssert.IsLastLineEqual(lines, "hello\nworld");
|
YesNtAssert.IsLastLineEqual(lines, "hello\nworld");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void CalcRespectsPrecedenceTest()
|
||||||
|
{
|
||||||
|
YesNtAssert.IsLineEqual("2 + 3 * 4 calc", "14");
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void CalcParenthesesOverridePrecedenceTest()
|
||||||
|
{
|
||||||
|
YesNtAssert.IsLineEqual("(2 + 3) * 4 calc", "20");
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void SleepZeroIsValidTest()
|
||||||
|
{
|
||||||
|
List<string> lines =
|
||||||
|
[
|
||||||
|
"sleep 0",
|
||||||
|
"var result = ok",
|
||||||
|
"${result}"
|
||||||
|
];
|
||||||
|
|
||||||
|
YesNtAssert.IsLastLineEqual(lines, "ok");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void SleepInvalidValueFailsTest()
|
public void SleepInvalidValueFailsTest()
|
||||||
{
|
{
|
||||||
@@ -152,5 +178,26 @@ public class ProcessingStatementsTests
|
|||||||
|
|
||||||
YesNtAssert.IsLastLineEqual(lines, "1", timeout: 3000);
|
YesNtAssert.IsLastLineEqual(lines, "1", timeout: 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MultipleTasksRunConcurrentlyTest()
|
||||||
|
{
|
||||||
|
List<string> lines =
|
||||||
|
[
|
||||||
|
"global a = 0",
|
||||||
|
"global b = 0",
|
||||||
|
"global a = 1 task",
|
||||||
|
"global b = 2 task",
|
||||||
|
"while ${a} == 0:",
|
||||||
|
"sleep 10",
|
||||||
|
"end_while",
|
||||||
|
"while ${b} == 0:",
|
||||||
|
"sleep 10",
|
||||||
|
"end_while",
|
||||||
|
"${b}"
|
||||||
|
];
|
||||||
|
|
||||||
|
YesNtAssert.IsLastLineEqual(lines, "2", timeout: 3000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,48 @@ public class StringLiteralStatementsTests
|
|||||||
YesNtAssert.IsLastLineEqual(lines, "hello world");
|
YesNtAssert.IsLastLineEqual(lines, "hello world");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void EmptyStringLiteralHasLengthZeroTest()
|
||||||
|
{
|
||||||
|
List<string> lines =
|
||||||
|
[
|
||||||
|
"var x = \"\"",
|
||||||
|
"length ${x}",
|
||||||
|
"var len = %out",
|
||||||
|
"${len}"
|
||||||
|
];
|
||||||
|
|
||||||
|
YesNtAssert.IsLastLineEqual(lines, "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void EscapedBackslashProducesLiteralBackslashTest()
|
||||||
|
{
|
||||||
|
List<string> lines =
|
||||||
|
[
|
||||||
|
"var msg = \"\\\\n\"", // YesNt source: "\\n" → \n (backslash + n, 2 chars)
|
||||||
|
"length ${msg}",
|
||||||
|
"var len = %out",
|
||||||
|
"${len}"
|
||||||
|
];
|
||||||
|
|
||||||
|
YesNtAssert.IsLastLineEqual(lines, "2");
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void UnknownEscapeSequenceBecomesCharTest()
|
||||||
|
{
|
||||||
|
List<string> lines =
|
||||||
|
[
|
||||||
|
"var msg = \"\\q\"", // YesNt source: "\q" → q (1 char)
|
||||||
|
"length ${msg}",
|
||||||
|
"var len = %out",
|
||||||
|
"${len}"
|
||||||
|
];
|
||||||
|
|
||||||
|
YesNtAssert.IsLastLineEqual(lines, "1");
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void UnterminatedStringLiteralFailsTest()
|
public void UnterminatedStringLiteralFailsTest()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -91,6 +91,34 @@ public class VariableStatementsTests
|
|||||||
YesNtAssert.ContainsTerminationMessage(lines, "Invalid syntax");
|
YesNtAssert.ContainsTerminationMessage(lines, "Invalid syntax");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void OverwriteVariableTest()
|
||||||
|
{
|
||||||
|
List<string> lines =
|
||||||
|
[
|
||||||
|
"var x = first",
|
||||||
|
"var x = second",
|
||||||
|
"${x}"
|
||||||
|
];
|
||||||
|
|
||||||
|
YesNtAssert.IsLastLineEqual(lines, "second");
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void EmptyStringVariableHasLengthZeroTest()
|
||||||
|
{
|
||||||
|
List<string> lines =
|
||||||
|
[
|
||||||
|
"var x = \"\"",
|
||||||
|
"length ${x}",
|
||||||
|
"var len = %out",
|
||||||
|
"${len}"
|
||||||
|
];
|
||||||
|
|
||||||
|
YesNtAssert.IsLastLineEqual(lines, "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MissingVariableReferenceFailsTest()
|
public void MissingVariableReferenceFailsTest()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user