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 IStack Stack { get; } protected abstract T[] GetValues(int count); protected virtual T[] Get2Different() { return this.GetValues(2); } protected virtual void Test(Expression expression) { this.interpreter.Run(expression); } protected abstract void CheckOtherStacksAreEmpty(); [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestEqualsTrue() { var values = this.GetValues(1); var merged = new[] { values[0], values[0] }; this.Stack.Push(merged); var isBooleanStack = this.interpreter.BooleanStack.Count == 2; this.Test(ExpressionTable.GetStatelessExpression(this.TypeName + ".=")); if (isBooleanStack) Assert.AreEqual(1, this.Stack.Count); else Assert.AreEqual(0, this.Stack.Count); Assert.IsTrue(this.interpreter.BooleanStack.Top); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestEqualsFalse() { var values = this.Get2Different(); this.Stack.Push(values); var isBooleanStack = this.interpreter.BooleanStack.Count == 2; this.Test(ExpressionTable.GetStatelessExpression(this.TypeName + ".=")); if (isBooleanStack) Assert.AreEqual(1, this.Stack.Count); else Assert.AreEqual(0, this.Stack.Count); Assert.IsFalse(this.interpreter.BooleanStack.Top); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestEqualsWithInsufficientArguments() { this.TestWithInsufficientArguments("=", 1); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestDuplicate() { var values = this.GetValues(1); this.Stack.Push(values); this.Test(ExpressionTable.GetStatelessExpression(this.TypeName + ".DUP")); Assert.AreEqual(this.Stack.Count, 2); Assert.AreEqual(this.Stack[0], values[0]); Assert.AreEqual(this.Stack[1], values[0]); this.CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestPop() { var values = this.GetValues(2); this.Stack.Push(values); this.Test(ExpressionTable.GetStatelessExpression(this.TypeName + ".POP")); this.CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestSwap() { var values = this.GetValues(3); this.Stack.Push(values); this.Test(ExpressionTable.GetStatelessExpression(this.TypeName + ".SWAP")); Assert.AreEqual(values[0], this.Stack[0]); Assert.AreEqual(values[2], this.Stack[1]); Assert.AreEqual(values[1], this.Stack[2]); this.CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestSwapWithInsufficientArguments() { this.TestWithInsufficientArguments("SWAP", 1); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestRotate() { var values = this.GetValues(4); this.Stack.Push(values); this.Test(ExpressionTable.GetStatelessExpression(this.TypeName + ".ROT")); Assert.AreEqual(values[0], this.Stack[0]); Assert.AreEqual(values[3], this.Stack[1]); Assert.AreEqual(values[1], this.Stack[2]); Assert.AreEqual(values[2], this.Stack[3]); this.CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestRotateWithInsufficientArguments() { this.TestWithInsufficientArguments("ROT", 2); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestShove() { var values = this.GetValues(3); this.Stack.Push(values); this.interpreter.IntegerStack.Push(1); this.Test(ExpressionTable.GetStatelessExpression(this.TypeName + ".SHOVE")); Assert.AreEqual(values[0], this.Stack[0]); Assert.AreEqual(values[2], this.Stack[1]); Assert.AreEqual(values[1], this.Stack[2]); this.CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestShoveWithInsufficientArguments() { this.TestWithInsufficientArguments("SHOVE", 1); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestShoveWithNegativeIndex() { this.TestWithNegativeIndex("SHOVE"); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestYank() { var values = this.GetValues(3); this.Stack.Push(values); this.interpreter.IntegerStack.Push(1); this.Test(ExpressionTable.GetStatelessExpression(this.TypeName + ".YANK")); Assert.AreEqual(values[0], this.Stack[0]); Assert.AreEqual(values[2], this.Stack[1]); Assert.AreEqual(values[1], this.Stack[2]); this.CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestYankWithInsufficientArguments() { this.TestWithInsufficientArguments("YANK", 1); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestYankWithNegativeIndex() { this.TestWithNegativeIndex("YANK"); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestYankDuplicate() { var values = this.GetValues(3); this.Stack.Push(values); this.interpreter.IntegerStack.Push(1); this.Test(ExpressionTable.GetStatelessExpression(this.TypeName + ".YANKDUP")); Assert.AreEqual(values[0], this.Stack[0]); Assert.AreEqual(values[1], this.Stack[1]); Assert.AreEqual(values[2], this.Stack[2]); Assert.AreEqual(values[1], this.Stack[3]); this.CheckOtherStacksAreEmpty(); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestYankDuplicateWithInsufficientArguments() { this.TestWithInsufficientArguments("YANKDUP", 1); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestYankDuplicateWithNegativeIndex() { this.TestWithNegativeIndex("YANKDUP"); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ExpressionTest")] [TestCategory("CommonExpressionTest")] public virtual void TestStackdpeth() { var values = this.GetValues(3); this.Stack.Push(values); this.Test(ExpressionTable.GetStatelessExpression(this.TypeName + ".STACKDEPTH")); // if stack is integer stack if (this.Stack.Count != values.Length) { Assert.AreEqual(4, this.Stack.Count); this.CheckOtherStacksAreEmpty(); } else { Assert.AreEqual(3, this.Stack.Count); Assert.AreEqual(values.Length, this.interpreter.IntegerStack.Top); } } protected void TestWithInsufficientArguments(string instructionName, int argCount = 0) { for (var i = 0; i < argCount + 1; i++) { var values = this.GetValues(i); this.Stack.Push(values); var fullInstructionname = string.Format(FullInstructionNameFormat, this.TypeName, instructionName); this.Test(ExpressionTable.GetStatelessExpression(fullInstructionname)); for (var j = 0; j < i; j++) Assert.AreEqual(values[j], this.Stack[j]); this.CheckOtherStacksAreEmpty(); this.interpreter.Clear(); } } protected void TestWithNegativeIndex(string instructionName) { var values = this.GetValues(1); this.Stack.Push(values); this.interpreter.IntegerStack.Push(-1); var fullInstructionname = string.Format(FullInstructionNameFormat, this.TypeName, instructionName); this.Test(ExpressionTable.GetStatelessExpression(fullInstructionname)); Assert.AreEqual(values[0], this.Stack[0]); } } }