namespace HeuristicLab.Tests.Interpreter.Expressions { using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions; using HeuristicLab.Problems.ProgramSynthesis.Push.Stack; using Microsoft.VisualStudio.TestTools.UnitTesting; public abstract class CommonTests : ExpressionTest { protected const string FullInstructionNameFormat = "{0}.{1}"; protected abstract string TypeName { get; } protected abstract IPushStack Stack { get; } protected abstract T[] GetValues(int count); protected virtual T[] Get2Different() { return GetValues(2); } protected virtual void Test(Expression expression) { interpreter.Run(expression); } protected abstract void CheckOtherStacksAreEmpty(); [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestEqualsTrue() { var values = GetValues(1); var merged = new[] { values[0], values[0] }; Stack.Push(merged); var isBooleanStack = interpreter.BooleanStack.Count == 2; Test(ExpressionTable.GetStatelessExpression(TypeName + ".=")); if (isBooleanStack) Assert.AreEqual(1, Stack.Count); else Assert.AreEqual(0, Stack.Count); Assert.IsTrue(interpreter.BooleanStack.Top); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestEqualsFalse() { var values = Get2Different(); Stack.Push(values); var isBooleanStack = interpreter.BooleanStack.Count == 2; Test(ExpressionTable.GetStatelessExpression(TypeName + ".=")); if (isBooleanStack) Assert.AreEqual(1, Stack.Count); else Assert.AreEqual(0, Stack.Count); Assert.IsFalse(interpreter.BooleanStack.Top); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestEqualsWithInsufficientArguments() { TestWithInsufficientArguments("=", 1); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestDuplicate() { var values = GetValues(1); Stack.Push(values); Test(ExpressionTable.GetStatelessExpression(TypeName + ".DUP")); Assert.AreEqual(Stack.Count, 2); Assert.AreEqual(Stack[0], values[0]); Assert.AreEqual(Stack[1], values[0]); CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestPop() { var values = GetValues(2); Stack.Push(values); Test(ExpressionTable.GetStatelessExpression(TypeName + ".POP")); CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestSwap() { var values = GetValues(3); Stack.Push(values); Test(ExpressionTable.GetStatelessExpression(TypeName + ".SWAP")); Assert.AreEqual(values[0], Stack[2]); Assert.AreEqual(values[1], Stack[0]); Assert.AreEqual(values[2], Stack[1]); CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestSwapWithInsufficientArguments() { TestWithInsufficientArguments("SWAP", 1); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestRotate() { var values = GetValues(4); Stack.Push(values); Test(ExpressionTable.GetStatelessExpression(TypeName + ".ROT")); Assert.AreEqual(values[0], Stack[3]); Assert.AreEqual(values[3], Stack[2]); Assert.AreEqual(values[1], Stack[1]); Assert.AreEqual(values[2], Stack[0]); CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestRotateWithInsufficientArguments() { TestWithInsufficientArguments("ROT", 2); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestShove() { var values = GetValues(3); Stack.Push(values); interpreter.IntegerStack.Push(1); Test(ExpressionTable.GetStatelessExpression(TypeName + ".SHOVE")); Assert.AreEqual(values[0], Stack[2]); Assert.AreEqual(values[1], Stack[0]); Assert.AreEqual(values[2], Stack[1]); CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestShoveWithInsufficientArguments() { TestWithInsufficientArguments("SHOVE", 1); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestShoveWithNegativeIndex() { var values = GetValues(3); Stack.Push(values); interpreter.IntegerStack.Push(-1); Test(ExpressionTable.GetStatelessExpression(TypeName + ".SHOVE")); Assert.AreEqual(values[0], Stack[2]); Assert.AreEqual(values[1], Stack[0]); Assert.AreEqual(values[2], Stack[1]); CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestYank() { var values = GetValues(3); Stack.Push(values); interpreter.IntegerStack.Push(1); Test(ExpressionTable.GetStatelessExpression(TypeName + ".YANK")); Assert.AreEqual(values[0], Stack[2]); Assert.AreEqual(values[1], Stack[0]); Assert.AreEqual(values[2], Stack[1]); CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestYankWithInsufficientArguments() { TestWithInsufficientArguments("YANK", 1); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestYankWithNegativeIndex() { var values = GetValues(3); Stack.Push(values); interpreter.IntegerStack.Push(-1); Test(ExpressionTable.GetStatelessExpression(TypeName + ".YANK")); Assert.AreEqual(values[0], Stack[2]); Assert.AreEqual(values[1], Stack[0]); Assert.AreEqual(values[2], Stack[1]); CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestYankDuplicate() { var values = GetValues(3); Stack.Push(values); interpreter.IntegerStack.Push(1); Test(ExpressionTable.GetStatelessExpression(TypeName + ".YANKDUP")); Assert.AreEqual(values[0], Stack[3]); Assert.AreEqual(values[1], Stack[2]); Assert.AreEqual(values[2], Stack[1]); Assert.AreEqual(values[1], Stack[0]); CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestYankDuplicateWithInsufficientArguments() { TestWithInsufficientArguments("YANKDUP", 1); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestYankDuplicateWithNegativeIndex() { var values = GetValues(3); Stack.Push(values); interpreter.IntegerStack.Push(-1); Test(ExpressionTable.GetStatelessExpression(TypeName + ".YANKDUP")); Assert.AreEqual(values[0], Stack[3]); Assert.AreEqual(values[1], Stack[2]); Assert.AreEqual(values[2], Stack[1]); Assert.AreEqual(values[1], Stack[0]); CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestStackdpeth() { var values = GetValues(3); Stack.Push(values); Test(ExpressionTable.GetStatelessExpression(TypeName + ".STACKDEPTH")); // if stack is integer stack if (Stack.Count != values.Length) { Assert.AreEqual(4, Stack.Count); CheckOtherStacksAreEmpty(); } else { Assert.AreEqual(3, Stack.Count); Assert.AreEqual(values.Length, interpreter.IntegerStack.Top); } } protected void TestWithInsufficientArguments(string instructionName, int argCount = 0) { for (var i = 0; i < argCount + 1; i++) { var values = GetValues(i); Stack.Push(values); var fullInstructionName = string.Format(FullInstructionNameFormat, TypeName, instructionName); Test(ExpressionTable.GetStatelessExpression(fullInstructionName)); for (var j = 0; j < i; j++) Assert.AreEqual(values[j], Stack[i - j - 1]); CheckOtherStacksAreEmpty(); interpreter.ClearStacks(); } } protected void TestWithNegativeIndex(string instructionName) { var values = GetValues(3); Stack.Push(values); interpreter.IntegerStack.Push(-1); var fullInstructionname = string.Format(FullInstructionNameFormat, TypeName, instructionName); Test(ExpressionTable.GetStatelessExpression(fullInstructionname)); Assert.AreEqual(values[0], Stack[2]); Assert.AreEqual(values[1], Stack[0]); Assert.AreEqual(values[2], Stack[1]); } } }