From 648bd3bad0cf27e2135d32749cd692e2420acc75 Mon Sep 17 00:00:00 2001 From: wagesj45 Date: Tue, 19 Aug 2025 04:52:37 -0500 Subject: [PATCH] tests: Add NUnit suite for InputInterpreter.Interpret covering arithmetic, comparisons, variables, := binding, arrays, soft errors, and timing Adds InputInterpreterTests with: - Arithmetic cases including precedence, hex/binary, exponent. - Comparisons yielding numeric booleans. - Variable assignment (::) and persistence across calls; unknown variable soft error. - Expression binding (:=) re-evaluated at use-time; invalid expression soft error. - Array assignment (->) and indexing; out-of-range and index-expression scenarios. - String literal used as expression soft error. - Divide-by-zero soft error (no thrown exception). - LastExecutionTime measured across calls. Each test asserts both the return value and NumericValue/StringValue for consistency. --- src/tests/InputInterpreterTests.cs | 149 ++++++++++++++++++++++++++--- 1 file changed, 136 insertions(+), 13 deletions(-) diff --git a/src/tests/InputInterpreterTests.cs b/src/tests/InputInterpreterTests.cs index 95ec79e..4368e52 100644 --- a/src/tests/InputInterpreterTests.cs +++ b/src/tests/InputInterpreterTests.cs @@ -1,16 +1,139 @@ -namespace tests -{ - public class InputInterpreterTests - { - [SetUp] - public void Setup() - { - } +using System.Globalization; +using csmic; - [Test] - public void Test1() - { - Assert.Pass(); - } +namespace tests; + +public class InputInterpreterTests +{ + private InputInterpreter _interp = null!; + + [SetUp] + public void Setup() + { + CultureInfo.CurrentCulture = CultureInfo.InvariantCulture; + _interp = new InputInterpreter(); + } + + private static void AssertSuccess(decimal result, decimal expected, InputInterpreter interp) + { + Assert.That(result, Is.EqualTo(expected)); + Assert.That(interp.NumericValue, Is.EqualTo(expected)); + Assert.That(interp.StringValue, Is.EqualTo(string.Empty)); + } + + private static void AssertSoftError(decimal result, InputInterpreter interp) + { + Assert.That(result, Is.EqualTo(0m)); + Assert.That(interp.NumericValue, Is.EqualTo(0m)); + Assert.That(string.IsNullOrEmpty(interp.StringValue), Is.False); + } + + [TestCase("2", 2)] + [TestCase("-5", -5)] + [TestCase("2+3*4", 14)] + [TestCase("(2+3)*4", 20)] + [TestCase("8/2", 4)] + [TestCase("7%4", 3)] + [TestCase("2^3", 8)] + [TestCase("1e2", 100)] + [TestCase("0xFF", 255)] + [TestCase("1010b", 10)] + public void Arithmetic_Works(string expr, decimal expected) + { + var result = _interp.Interpret(expr); + AssertSuccess(result, expected, _interp); + } + + [TestCase("2==2", 1)] + [TestCase("2<3", 1)] + [TestCase("3<2", 0)] + [TestCase("2>=2", 1)] + [TestCase("2<=1", 0)] + public void Comparisons_YieldBooleanAsNumeric(string expr, decimal expected) + { + var result = _interp.Interpret(expr); + AssertSuccess(result, expected, _interp); + } + + [Test] + public void Variables_AssignAndUse_PersistAcrossCalls() + { + AssertSuccess(_interp.Interpret("x :: 2"), 2, _interp); + AssertSuccess(_interp.Interpret("x+1"), 3, _interp); + AssertSuccess(_interp.Interpret("x :: 3"), 3, _interp); + AssertSuccess(_interp.Interpret("x+1"), 4, _interp); + } + + [Test] + public void UnknownVariable_ProducesSoftError() + { + var result = _interp.Interpret("nope + 1"); + AssertSoftError(result, _interp); + } + + [Test] + public void ExpressionBinding_EvaluatesAtUseTime() + { + AssertSuccess(_interp.Interpret("num :: 2"), 2, _interp); + AssertSuccess(_interp.Interpret("exp := 1 + num"), 0, _interp); // assignment returns 0 + AssertSuccess(_interp.Interpret("exp"), 3, _interp); + + AssertSuccess(_interp.Interpret("num :: 3"), 3, _interp); + AssertSuccess(_interp.Interpret("exp"), 4, _interp); + } + + [Test] + public void ExpressionBinding_InvalidExpression_ProducesSoftError() + { + _interp.Interpret("exp := bad + 1"); + var result = _interp.Interpret("exp"); + AssertSoftError(result, _interp); + } + + [Test] + public void Arrays_AssignAndIndex() + { + AssertSuccess(_interp.Interpret("arr -> [1,2,3]"), 0, _interp); // array assignment returns 0 + AssertSuccess(_interp.Interpret("arr[0]"), 1, _interp); + AssertSuccess(_interp.Interpret("arr[2]"), 3, _interp); + } + + [Test] + public void Arrays_OutOfRange_ProducesSoftError() + { + _interp.Interpret("arr -> [1,2,3]"); + var result = _interp.Interpret("arr[3]"); + AssertSoftError(result, _interp); + } + + [Test] + public void Arrays_IndexExpression_Works() + { + _interp.Interpret("arr -> [1,2,3]"); + _interp.Interpret("i :: 1"); + AssertSuccess(_interp.Interpret("arr[i+1]"), 3, _interp); + } + + [Test] + public void StringLiteral_Alone_IsError() + { + var result = _interp.Interpret("\"hi\""); + AssertSoftError(result, _interp); + } + + [Test] + public void DivideByZero_ProducesSoftError() + { + var result = _interp.Interpret("1/0"); + AssertSoftError(result, _interp); + } + + [Test] + public void LastExecutionTime_IsMeasured() + { + _interp.Interpret("2+2"); + Assert.That(_interp.LastExecutionTime, Is.GreaterThanOrEqualTo(TimeSpan.Zero)); + _interp.Interpret("3+3"); + Assert.That(_interp.LastExecutionTime, Is.GreaterThanOrEqualTo(TimeSpan.Zero)); } }