mirror of
https://github.com/0xJ1M/MathsEngine.git
synced 2026-06-05 02:20:07 +00:00
Major refactor
This commit is contained in:
@@ -1,93 +1,112 @@
|
||||
using MathEngine.Parser.Tokeniser;
|
||||
using MathEngine.Parser.Parser;
|
||||
using Xunit;
|
||||
|
||||
using MathEngine.Parser;
|
||||
using MathEngine.Tokenizer;
|
||||
|
||||
using static MathEngine.Tokenizer.Token;
|
||||
|
||||
namespace EngineTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for testing the Parser
|
||||
/// </summary>
|
||||
[TestClass]
|
||||
public class ParserTests
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Test the Parser on a basic List of tokens
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void TestParserBasicExpression()
|
||||
public static IEnumerable<object[]> TestParserValidExpressionsCases
|
||||
{
|
||||
//Arrange
|
||||
string testString = "3+4";
|
||||
List<Token> testList = Tokeniser.Tokenise(testString);
|
||||
Token three = new("3", Token.Type.Numeric, Token.NumericType.Decimal, 0);
|
||||
Token four = new("4", Token.Type.Numeric, Token.NumericType.Decimal, 0);
|
||||
Assert.IsNotNull(testList);
|
||||
Stack<Token> expectedStack = new();
|
||||
expectedStack.Push(Token.Plus);
|
||||
expectedStack.Push(four);
|
||||
expectedStack.Push(three);
|
||||
//Act
|
||||
Stack<Token> returnedStack = Parser.Parse(testList);
|
||||
//Assert
|
||||
if (returnedStack.Count != expectedStack.Count)
|
||||
get
|
||||
{
|
||||
Assert.Fail();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (returnedStack.Count > 0)
|
||||
{
|
||||
if (!returnedStack.Pop().Equals(expectedStack.Pop()))
|
||||
{
|
||||
Assert.Fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Token one = new("1", TokenType.Numeric);
|
||||
Token two = new("2", TokenType.Numeric);
|
||||
Token three = new("3", TokenType.Numeric);
|
||||
Token four = new("4", TokenType.Numeric);
|
||||
Token five = new("5", TokenType.Numeric);
|
||||
|
||||
/// <summary>
|
||||
/// Test the Parser on a more compilicated basic expression to see if operator precedence is respected
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void TestParserBasicExpressionAllOperators()
|
||||
{
|
||||
//Arrange
|
||||
string testString = "3+4*8-47.2/9";
|
||||
List<Token> testList = Tokeniser.Tokenise(testString);
|
||||
Token three = new("3", Token.Type.Numeric, Token.NumericType.Decimal, 0);
|
||||
Token four = new("4", Token.Type.Numeric, Token.NumericType.Decimal, 0);
|
||||
Token eight = new("8", Token.Type.Numeric, Token.NumericType.Decimal, 0);
|
||||
Token nine = new("9", Token.Type.Numeric, Token.NumericType.Decimal, 0);
|
||||
Token fourSevenPoint2 = new("47.2", Token.Type.Numeric, Token.NumericType.Decimal, 0);
|
||||
Assert.IsNotNull(testList);
|
||||
Stack<Token> expectedStack = new();
|
||||
expectedStack.Push(Token.Minus);
|
||||
expectedStack.Push(Token.Divide);
|
||||
expectedStack.Push(nine);
|
||||
expectedStack.Push(fourSevenPoint2);
|
||||
expectedStack.Push(Token.Plus);
|
||||
expectedStack.Push(Token.Multiply);
|
||||
expectedStack.Push(eight);
|
||||
expectedStack.Push(four);
|
||||
expectedStack.Push(three);
|
||||
//Act
|
||||
Stack<Token> returnedStack = Parser.Parse(testList);
|
||||
//Assert
|
||||
if (returnedStack.Count != expectedStack.Count)
|
||||
{
|
||||
Assert.Fail();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (returnedStack.Count > 0)
|
||||
{
|
||||
if (!returnedStack.Pop().Equals(expectedStack.Pop()))
|
||||
{
|
||||
Assert.Fail();
|
||||
}
|
||||
}
|
||||
return new List<object[]> {
|
||||
new object[] { "1+1", new Queue<Token>(new List<Token> { one, one, Token.Plus }) },
|
||||
new object[] { "1-1", new Queue<Token>(new List<Token> { one, one, Token.Minus }) },
|
||||
new object[] { "1*1", new Queue<Token>(new List<Token> { one, one, Token.Multiply }) },
|
||||
new object[] { "1/1", new Queue<Token>(new List<Token> { one, one, Token.Divide }) },
|
||||
new object[] { "1^1", new Queue<Token>(new List<Token> { one, one, Token.Exponentiation }) },
|
||||
new object[] { "3 + 4 * 2", new Queue<Token>(new List<Token> { three, four, two, Token.Multiply, Token.Plus }) },
|
||||
new object[] { "(1+2)*3", new Queue<Token>(new List<Token> {one, two, Token.Plus, three, Token.Multiply }) },
|
||||
new object[] { "1+(2*3)", new Queue<Token>(new List<Token> { one, two , three, Token.Multiply, Token.Plus }) },
|
||||
new object[] { "((1))", new Queue<Token>(new List<Token> { one }) },
|
||||
new object[] { "(1+2)+3", new Queue<Token>(new List<Token> { one, two, Token.Plus, three, Token.Plus }) },
|
||||
new object[] { "1+2*3-4/2", new Queue<Token>(new List<Token> { one, two, three, Token.Multiply, Token.Plus, four, two, Token.Divide, Token.Minus }) },
|
||||
new object[] { "1-2-3", new Queue<Token>(new List<Token> {one, two, Token.Minus, three, Token.Minus }) },
|
||||
new object[] { "2^3^4", new Queue<Token>(new List<Token> { two, three, four, Token.Exponentiation, Token.Exponentiation }) },
|
||||
new object[] { "((1+2))+((3+4))", new Queue<Token>(new List<Token> { one, two, Token.Plus, three, four, Token.Plus, Token.Plus }) },
|
||||
new object[] { "1 + ((2 + 3) * 4) - 5", new Queue<Token>(new List<Token> { one, two, three, Token.Plus, four, Token.Multiply, Token.Plus,five, Token.Minus }) },
|
||||
new object[] { "1 ^ (2 + 3)", new Queue<Token>(new List<Token> { one, two, three, Token.Plus, Token.Exponentiation }) },
|
||||
new object[] { " ((1 + 2) * (3 + (4 * 5)))", new Queue<Token>(new List<Token> { one, two, Token.Plus, three, four, five, Token.Multiply, Token.Plus, Token.Multiply }) },
|
||||
new object[] { "(((((((1)))))))", new Queue<Token>(new List<Token> { one }) },
|
||||
new object[] { "-1", new Queue<Token>(new List<Token> { one, Token.UnaryMinus }) },
|
||||
new object[] { "+1", new Queue<Token>(new List<Token> { one, Token.UnaryPlus }) },
|
||||
new object[] { "1+-1", new Queue<Token>(new List<Token> { one, one, Token.UnaryMinus, Token.Plus }) },
|
||||
new object[] { "-(1+2)", new Queue<Token>(new List<Token> { one, two, Token.Plus, Token.UnaryMinus }) },
|
||||
new object[] { "--1", new Queue<Token>(new List<Token> { one, Token.UnaryMinus, Token.UnaryMinus }) },
|
||||
new object[] { "+-1", new Queue<Token>(new List<Token> { one, Token.UnaryMinus, Token.UnaryPlus }) },
|
||||
new object[] { "-3^2", new Queue<Token>(new List<Token> { three, two, Token.Exponentiation, Token.UnaryMinus}) },
|
||||
new object[] { "1++2", new Queue<Token>(new List<Token> { one, two, Token.UnaryPlus, Token.Plus}) },
|
||||
new object[] { "1--2", new Queue<Token>(new List<Token> { one, two, Token.UnaryMinus, Token.Minus }) },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test the Parser on valid expressions
|
||||
/// </summary>
|
||||
[Theory]
|
||||
[MemberData(nameof(TestParserValidExpressionsCases))]
|
||||
public void TestParserValidExpressions(string expression, object expected_result)
|
||||
{
|
||||
List<Token> testList = ExpressionTokenizer.Tokenize(expression);
|
||||
|
||||
Queue<Token> returned_rpn_qeue = Parser.Parse(testList);
|
||||
|
||||
Assert.Equal(expected_result, returned_rpn_qeue);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> TestParserInValidExpressionsCases
|
||||
{
|
||||
get
|
||||
{
|
||||
Token one = new("1", TokenType.Numeric);
|
||||
Token two = new("2", TokenType.Numeric);
|
||||
Token three = new("3", TokenType.Numeric);
|
||||
Token four = new("4", TokenType.Numeric);
|
||||
Token five = new("5", TokenType.Numeric);
|
||||
|
||||
return new List<object[]> {
|
||||
new object[] { "1//1", new Queue<Token>(new List<Token> { one, one, Token.Plus }) },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Test the Parser on invalid expressions
|
||||
/// These are expressions that are considered Parsing errors, such
|
||||
/// </summary>
|
||||
[Theory]
|
||||
[MemberData(nameof(TestParserInValidExpressionsCases))]
|
||||
public void TestParserInValidExpressions(string expression, object expected_result)
|
||||
{
|
||||
Assert.True(true);
|
||||
return;
|
||||
//List<Token> testList = ExpressionTokenizer.Tokenize(expression);
|
||||
|
||||
//Queue<Token> returned_rpn_qeue = Parser.Parse(testList);
|
||||
|
||||
//Assert.Equal(expected_result, returned_rpn_qeue);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user