mirror of
https://github.com/Stone-Red-Code/YesNt-Interpreter.git
synced 2026-09-04 00:56:31 +02:00
Add new tests for console, function, system, variable, and code flow statements
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YesNt.Interpreter.Tests;
|
||||
|
||||
[TestClass]
|
||||
public class CodeFlowStatementsTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void ExitStopsExecutionTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"let result = before",
|
||||
"exit",
|
||||
"let result = after",
|
||||
"${result}"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Planned termination by code");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void AbortAllStopsExecutionTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"abort_all",
|
||||
"let result = after",
|
||||
"${result}"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Canceling all tasks");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ThrowTerminatesWithErrorFlagTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"throw bad"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "with the message: bad");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ErrorTerminatesWithMessageTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"error soft"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "with the message: soft");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MissingLabelFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"goto nowhere"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Label \"nowhere\" not found");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MissingFunctionFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"call nowhere"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Function \"nowhere\" not found");
|
||||
}
|
||||
}
|
||||
@@ -136,4 +136,136 @@ public class CodeFlowTests
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "4");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IfElseTrueSkipsElseBranchTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"let result = 0",
|
||||
"if 2 > 1:",
|
||||
"let result = 1",
|
||||
"else:",
|
||||
"let result = 2",
|
||||
"end_if",
|
||||
"${result}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "1");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IfWithoutElseFalseSkipsBodyTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"let result = 5",
|
||||
"if 1 == 2:",
|
||||
"let result = 1",
|
||||
"end_if",
|
||||
"${result}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "5");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IfGotoTrueTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"let result = 0",
|
||||
"if 1 == 1 goto done",
|
||||
"let result = 2",
|
||||
"label done:",
|
||||
"let result = ${result} + 1 calc",
|
||||
"${result}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "1");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IfCallTrueTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"func set_result:",
|
||||
"global result = ok",
|
||||
"return",
|
||||
"if 1 == 1 call set_result",
|
||||
"${result}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "ok");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LabelWithoutColonFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"label loop"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Invalid statement");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FunctionWithoutColonFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"func missing"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Invalid statement");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MissingEndIfFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"if 1 == 2:",
|
||||
"let result = 1"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "No matching end_if found");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ElseWithoutIfFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"else:"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "No matching end_if found");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MissingEndWhileFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"let i = 0",
|
||||
"while ${i} > 1:",
|
||||
"let i = ${i} + 1 calc"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "No matching end_while found");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void EndWhileWithoutWhileFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"end_while"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "No matching while found");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using YesNt.Interpreter.Runtime;
|
||||
|
||||
namespace YesNt.Interpreter.Tests;
|
||||
|
||||
[TestClass]
|
||||
public class ConsoleStatementsTests
|
||||
{
|
||||
private static readonly object ConsoleLock = new object();
|
||||
|
||||
[TestMethod]
|
||||
public void PrintLineWritesOutputTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"print_line hello"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsDebugOutput(lines, "hello");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void PrintWritesOutputTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"print hello"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsDebugOutput(lines, "hello");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ClearThrowsInNonInteractiveConsoleTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"clear"
|
||||
];
|
||||
|
||||
_ = Assert.ThrowsException<IOException>(() => YesNtAssert.GetLastLine(lines));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ReadLineReplacesTokenTest()
|
||||
{
|
||||
lock (ConsoleLock)
|
||||
{
|
||||
TextReader originalIn = Console.In;
|
||||
|
||||
try
|
||||
{
|
||||
Console.SetIn(new StringReader("typed value" + Environment.NewLine));
|
||||
|
||||
List<string> lines =
|
||||
[
|
||||
"let value = %read_line",
|
||||
"${value}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "typed value");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetIn(originalIn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ReadKeyCanBeInterruptedByStopTest()
|
||||
{
|
||||
YesNtInterpreter interpreter = new YesNtInterpreter();
|
||||
interpreter.Initialize();
|
||||
|
||||
AutoResetEvent onDone = new AutoResetEvent(false);
|
||||
StringBuilder output = new StringBuilder();
|
||||
|
||||
interpreter.OnDebugOutput += (s) => _ = output.Append(s);
|
||||
interpreter.OnLineExecuted += (e) =>
|
||||
{
|
||||
if (e is null)
|
||||
{
|
||||
_ = onDone.Set();
|
||||
}
|
||||
};
|
||||
|
||||
List<string> lines =
|
||||
[
|
||||
"let value = %read_key"
|
||||
];
|
||||
|
||||
_ = Task.Run(() => interpreter.Execute(lines, true));
|
||||
|
||||
Thread.Sleep(100);
|
||||
interpreter.Stop();
|
||||
|
||||
_ = onDone.WaitOne(TimeSpan.FromSeconds(3));
|
||||
|
||||
StringAssert.Contains(output.ToString(), "Terminated by external process");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YesNt.Interpreter.Tests;
|
||||
|
||||
[TestClass]
|
||||
public class FunctionStatementsTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void FunctionCallWithInParameterTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"goto main",
|
||||
"func echo:",
|
||||
"global result = %in",
|
||||
"return",
|
||||
"label main:",
|
||||
"call echo with hello",
|
||||
"${result}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "hello");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void HasInAndHasOutTokensTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"goto main",
|
||||
"func probe:",
|
||||
"global hasInBefore = %has_in",
|
||||
"let consume = %in",
|
||||
"global hasInAfter = %has_in",
|
||||
"push_out ${hasInBefore}",
|
||||
"push_out ${hasInAfter}",
|
||||
"return",
|
||||
"label main:",
|
||||
"call probe with x",
|
||||
"let hasOut = %has_out",
|
||||
"${hasOut}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "True");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void OutParameterReadTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"goto main",
|
||||
"func make:",
|
||||
"push_out out_value",
|
||||
"return",
|
||||
"label main:",
|
||||
"call make with anything",
|
||||
"let value = %out",
|
||||
"${value}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "out_value");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void OutParameterWithoutValueFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"let x = %out"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "No out argument in stack");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InParameterOutsideFunctionFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"let x = %in"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Statement not allowed outside of function");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ReturnOutsideFunctionFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"return"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Statement not allowed outside of function");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void PushOutOutsideFunctionFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"push_out value"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Statement not allowed outside of function");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FunctionWithoutColonFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"func missing"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Invalid statement");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void NestedFunctionDefinitionFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"func outer:",
|
||||
"func inner:",
|
||||
"return"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Nested functions are not allowed");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ClearCallStackRunsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"clear_call_stack",
|
||||
"let result = ok",
|
||||
"${result}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "ok");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YesNt.Interpreter.Tests;
|
||||
|
||||
[TestClass]
|
||||
public class PredefinedVariableStatementsTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void TimeTokenProducesUnixTimestampTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"%time"
|
||||
];
|
||||
|
||||
string? value = YesNtAssert.GetLastLine(lines);
|
||||
Assert.IsNotNull(value);
|
||||
Assert.IsTrue(long.TryParse(value, out long parsed));
|
||||
|
||||
long now = DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||
Assert.IsTrue(Math.Abs(now - parsed) < 10);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void OsTokenProducesValueTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"%os"
|
||||
];
|
||||
|
||||
string? value = YesNtAssert.GetLastLine(lines);
|
||||
Assert.IsFalse(string.IsNullOrWhiteSpace(value));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CpuTokenProducesValueTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"%cpu"
|
||||
];
|
||||
|
||||
string? value = YesNtAssert.GetLastLine(lines);
|
||||
Assert.IsFalse(string.IsNullOrWhiteSpace(value));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Is64TokenProducesBooleanTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"%is64"
|
||||
];
|
||||
|
||||
string? value = YesNtAssert.GetLastLine(lines);
|
||||
Assert.AreEqual(Environment.Is64BitOperatingSystem.ToString(), value);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void PiTokenProducesPiTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"%pi"
|
||||
];
|
||||
|
||||
string? value = YesNtAssert.GetLastLine(lines);
|
||||
Assert.IsNotNull(value);
|
||||
Assert.IsTrue(double.TryParse(value, out double parsed));
|
||||
Assert.IsTrue(Math.Abs(parsed - Math.PI) < 0.001d);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RandTokenProducesIntegerTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"%rand"
|
||||
];
|
||||
|
||||
string? value = YesNtAssert.GetLastLine(lines);
|
||||
Assert.IsNotNull(value);
|
||||
Assert.IsTrue(int.TryParse(value, out int parsed));
|
||||
Assert.IsTrue(parsed >= 32767);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MultipleRandTokensAreReplacedTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"%rand %rand"
|
||||
];
|
||||
|
||||
string? value = YesNtAssert.GetLastLine(lines);
|
||||
Assert.IsNotNull(value);
|
||||
|
||||
string[] parts = value.Split(' ', StringSplitOptions.RemoveEmptyEntries);
|
||||
Assert.AreEqual(2, parts.Length);
|
||||
Assert.IsTrue(int.TryParse(parts[0], out _));
|
||||
Assert.IsTrue(int.TryParse(parts[1], out _));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace YesNt.Interpreter.Tests;
|
||||
|
||||
@@ -40,4 +44,98 @@ public class ProcessingStatementsTests
|
||||
{
|
||||
YesNtAssert.IsLineEqual("2 ^ 3 calc", "8");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void EvalDecodesSafeStringTest()
|
||||
{
|
||||
YesNtAssert.IsLineEqual("hello~nliworld eval", "hello\nworld");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SleepInvalidValueFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"sleep nope"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "\"nope\" is not a valid time-out value");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SleepRunsAndContinuesTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"sleep 5",
|
||||
"let result = ok",
|
||||
"${result}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "ok");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LengthPushesOutParameterTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"length hello",
|
||||
"let value = %out",
|
||||
"${value}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "5");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ImportLoadsScriptTest()
|
||||
{
|
||||
string tempFile = Path.Combine(Path.GetTempPath(), $"yesnt-import-{Guid.NewGuid():N}.ynt");
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(tempFile, "let imported = yes");
|
||||
|
||||
List<string> lines =
|
||||
[
|
||||
$"import {tempFile}",
|
||||
"${imported}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "yes");
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (File.Exists(tempFile))
|
||||
{
|
||||
File.Delete(tempFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ImportMissingFileFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
$"import {Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N"))}.ynt"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Could not find file");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TaskCanUpdateGlobalVariableTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"global result = 0",
|
||||
"global result = 1 task",
|
||||
"sleep 50",
|
||||
"${result}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "1", timeout: 3000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YesNt.Interpreter.Tests;
|
||||
|
||||
[TestClass]
|
||||
public class SystemStatementsTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void ExecWithArgsRunsProcessTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"exec cmd with /c,echo yesnt",
|
||||
"let exitCode = %out",
|
||||
"${exitCode}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "0");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ExecWithInStackArgsRunsProcessTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"push_in /c",
|
||||
"push_in echo yesnt",
|
||||
"exec cmd",
|
||||
"let exitCode = %out",
|
||||
"${exitCode}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "0");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ExecInvalidProgramFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"exec does_not_exist_abc_xyz"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Failed to start \"does_not_exist_abc_xyz\"");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YesNt.Interpreter.Tests;
|
||||
|
||||
[TestClass]
|
||||
public class VariableStatementsTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void LetAndReadVariableTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"let value = hi",
|
||||
"${value}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "hi");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GlobalVariableReadTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"global value = hi",
|
||||
"${value}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "hi");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LocalVariableOverridesGlobalTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"global value = global",
|
||||
"let value = local",
|
||||
"${value}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "local");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void DeleteLocalVariableTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"let value = a",
|
||||
"delete value",
|
||||
"global value = b",
|
||||
"${value}"
|
||||
];
|
||||
|
||||
YesNtAssert.IsLastLineEqual(lines, "b");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void DeleteMissingVariableFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"delete missing"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Variable \"missing\" not found");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LetInvalidSyntaxFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"let a"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Invalid statement");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LetInvalidNameFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"let a b = 1"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Invalid Syntax");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MissingVariableReferenceFailsTest()
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
"${missing}"
|
||||
];
|
||||
|
||||
YesNtAssert.ContainsTerminationMessage(lines, "Variable \"missing\" not found");
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
using YesNt.Interpreter.Runtime;
|
||||
@@ -10,76 +12,91 @@ namespace YesNt.Interpreter.Tests;
|
||||
|
||||
internal static class YesNtAssert
|
||||
{
|
||||
private static readonly YesNtInterpreter yesNtInterpreter = new YesNtInterpreter();
|
||||
|
||||
static YesNtAssert()
|
||||
{
|
||||
yesNtInterpreter.Initialize();
|
||||
}
|
||||
|
||||
public static void IsLastLineEqual(List<string> lines, string expected, int timeout = 1000)
|
||||
{
|
||||
(DebugEventArgs? debugEventArgs, _) = ExecuteAndCapture(lines, timeout);
|
||||
Assert.AreEqual(expected, debugEventArgs?.CurrentLine);
|
||||
}
|
||||
|
||||
public static void IsLineEqual(string line, string expected, int timeout = 1000)
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
line
|
||||
];
|
||||
|
||||
(DebugEventArgs? debugEventArgs, _) = ExecuteAndCapture(lines, timeout);
|
||||
Assert.AreEqual(expected, debugEventArgs?.CurrentLine);
|
||||
}
|
||||
|
||||
public static void IsLineNotEqual(string line, string expected, int timeout = 1000)
|
||||
{
|
||||
List<string> lines =
|
||||
[
|
||||
line
|
||||
];
|
||||
|
||||
(DebugEventArgs? debugEventArgs, _) = ExecuteAndCapture(lines, timeout);
|
||||
Assert.AreNotEqual(expected, debugEventArgs?.CurrentLine);
|
||||
}
|
||||
|
||||
public static void ContainsTerminationMessage(List<string> lines, string expectedMessageFragment, int timeout = 1000)
|
||||
{
|
||||
(_, string debugOutput) = ExecuteAndCapture(lines, timeout);
|
||||
|
||||
StringAssert.Contains(debugOutput, expectedMessageFragment);
|
||||
}
|
||||
|
||||
public static void ContainsDebugOutput(List<string> lines, string expectedFragment, int timeout = 1000)
|
||||
{
|
||||
(_, string debugOutput) = ExecuteAndCapture(lines, timeout);
|
||||
|
||||
StringAssert.Contains(debugOutput, expectedFragment);
|
||||
}
|
||||
|
||||
public static string? GetLastLine(List<string> lines, int timeout = 1000)
|
||||
{
|
||||
(DebugEventArgs? debugEventArgs, _) = ExecuteAndCapture(lines, timeout);
|
||||
return debugEventArgs?.CurrentLine;
|
||||
}
|
||||
|
||||
public static void LastLineMatches(List<string> lines, string pattern, int timeout = 1000)
|
||||
{
|
||||
string? value = GetLastLine(lines, timeout);
|
||||
Assert.IsNotNull(value);
|
||||
StringAssert.Matches(value, new Regex(pattern));
|
||||
}
|
||||
|
||||
private static (DebugEventArgs? LastDebugEvent, string DebugOutput) ExecuteAndCapture(List<string> lines, int timeout)
|
||||
{
|
||||
YesNtInterpreter yesNtInterpreter = new YesNtInterpreter();
|
||||
yesNtInterpreter.Initialize();
|
||||
|
||||
AutoResetEvent onDone = new AutoResetEvent(false);
|
||||
DebugEventArgs? debugEventArgs = null;
|
||||
StringBuilder outputBuilder = new StringBuilder();
|
||||
|
||||
DebugEventArgs debugEventArgs = new DebugEventArgs();
|
||||
yesNtInterpreter.OnLineExecuted += (er) =>
|
||||
{
|
||||
debugEventArgs = er ?? debugEventArgs;
|
||||
|
||||
if (er is null)
|
||||
if (er is not null)
|
||||
{
|
||||
debugEventArgs = er;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = onDone.Set();
|
||||
}
|
||||
};
|
||||
|
||||
yesNtInterpreter.Execute(lines, true);
|
||||
|
||||
_ = onDone.WaitOne(TimeSpan.FromSeconds(timeout));
|
||||
|
||||
Assert.AreEqual(expected, debugEventArgs.CurrentLine);
|
||||
}
|
||||
|
||||
public static void IsLineEqual(string line, string expected, int timeout = 1000)
|
||||
{
|
||||
AutoResetEvent onDone = new AutoResetEvent(false);
|
||||
List<string> lines =
|
||||
[
|
||||
line
|
||||
];
|
||||
|
||||
DebugEventArgs debugEventArgs = new DebugEventArgs();
|
||||
yesNtInterpreter.OnLineExecuted += (er) =>
|
||||
yesNtInterpreter.OnDebugOutput += (s) =>
|
||||
{
|
||||
debugEventArgs = er ?? debugEventArgs;
|
||||
_ = onDone.Set();
|
||||
_ = outputBuilder.Append(s);
|
||||
};
|
||||
|
||||
yesNtInterpreter.Execute(lines, true);
|
||||
|
||||
_ = onDone.WaitOne(TimeSpan.FromMilliseconds(timeout));
|
||||
|
||||
Assert.AreEqual(expected, debugEventArgs.CurrentLine);
|
||||
return (debugEventArgs, outputBuilder.ToString());
|
||||
}
|
||||
|
||||
public static void IsLineNotEqual(string line, string expected, int timeout = 1000)
|
||||
{
|
||||
AutoResetEvent onDone = new AutoResetEvent(false);
|
||||
List<string> lines =
|
||||
[
|
||||
line
|
||||
];
|
||||
|
||||
DebugEventArgs debugEventArgs = new DebugEventArgs();
|
||||
yesNtInterpreter.OnLineExecuted += (er) =>
|
||||
{
|
||||
debugEventArgs = er ?? debugEventArgs;
|
||||
_ = onDone.Set();
|
||||
};
|
||||
|
||||
yesNtInterpreter.Execute(lines, true);
|
||||
|
||||
_ = onDone.WaitOne(TimeSpan.FromMilliseconds(timeout));
|
||||
|
||||
Assert.AreNotEqual(expected, debugEventArgs.CurrentLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user