123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <AzCore/UnitTest/TestTypes.h>
- #include <gtest/gtest-param-test.h>
- #include <ExpressionEvaluation/ExpressionEngine.h>
- #include <Tests/ExpressionEngineTestFixture.h>
- #include <ExpressionEngine/MathOperators/MathExpressionOperators.h>
- namespace ExpressionEvaluation
- {
- using namespace UnitTest;
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_MathOperatorTest_AddOperator)
- {
- MathExpressionOperators operatorInterface;
- ElementInformation operatorInformation = MathExpressionOperators::AddOperator();
- ExpressionResultStack resultStack;
- {
- resultStack.emplace(3.0);
- resultStack.emplace(1.0);
- EXPECT_EQ(resultStack.size(), 2);
- operatorInterface.EvaluateToken(operatorInformation, resultStack);
- EXPECT_EQ(resultStack.size(), 1);
- auto treeResult = resultStack.PopAndReturn();
- ConfirmResult<double>(treeResult, 3.0+1.0);
- }
- {
- resultStack.emplace(1.0);
- resultStack.emplace(3.0);
- EXPECT_EQ(resultStack.size(), 2);
- operatorInterface.EvaluateToken(operatorInformation, resultStack);
- EXPECT_EQ(resultStack.size(), 1);
- auto treeResult = resultStack.PopAndReturn();
- ConfirmResult<double>(treeResult, 1.0+3.0);
- }
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_MathOperatorTest_SubtractOperator)
- {
- MathExpressionOperators operatorInterface;
- ElementInformation operatorInformation = MathExpressionOperators::SubtractOperator();
- ExpressionResultStack resultStack;
- {
- resultStack.emplace(3.0);
- resultStack.emplace(1.0);
- EXPECT_EQ(resultStack.size(), 2);
- operatorInterface.EvaluateToken(operatorInformation, resultStack);
- EXPECT_EQ(resultStack.size(), 1);
- auto treeResult = resultStack.PopAndReturn();
- ConfirmResult<double>(treeResult, 3.0-1.0);
- }
- {
- resultStack.emplace(1.0);
- resultStack.emplace(3.0);
- EXPECT_EQ(resultStack.size(), 2);
- operatorInterface.EvaluateToken(operatorInformation, resultStack);
- EXPECT_EQ(resultStack.size(), 1);
- auto treeResult = resultStack.PopAndReturn();
- ConfirmResult<double>(treeResult, 1.0-3.0);
- }
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_MathOperatorTest_MultiplyOperator)
- {
- MathExpressionOperators operatorInterface;
- ElementInformation operatorInformation = MathExpressionOperators::MultiplyOperator();
- ExpressionResultStack resultStack;
- {
- resultStack.emplace(2.0);
- resultStack.emplace(3.0);
- EXPECT_EQ(resultStack.size(), 2);
- operatorInterface.EvaluateToken(operatorInformation, resultStack);
- EXPECT_EQ(resultStack.size(), 1);
- auto treeResult = resultStack.PopAndReturn();
- ConfirmResult<double>(treeResult, 2.0*3.0);
- }
- {
- resultStack.emplace(3.0);
- resultStack.emplace(2.0);
- EXPECT_EQ(resultStack.size(), 2);
- operatorInterface.EvaluateToken(operatorInformation, resultStack);
- EXPECT_EQ(resultStack.size(), 1);
- auto treeResult = resultStack.PopAndReturn();
- ConfirmResult<double>(treeResult, 3.0*2.0);
- }
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_MathOperatorTest_DivideOperator)
- {
- MathExpressionOperators operatorInterface;
- ElementInformation operatorInformation = MathExpressionOperators::DivideOperator();
- ExpressionResultStack resultStack;
- {
- resultStack.emplace(4.0);
- resultStack.emplace(2.0);
- EXPECT_EQ(resultStack.size(), 2);
- operatorInterface.EvaluateToken(operatorInformation, resultStack);
- EXPECT_EQ(resultStack.size(), 1);
- auto treeResult = resultStack.PopAndReturn();
- ConfirmResult<double>(treeResult, 4.0/2.0);
- }
- {
- resultStack.emplace(2.0);
- resultStack.emplace(4.0);
- EXPECT_EQ(resultStack.size(), 2);
- operatorInterface.EvaluateToken(operatorInformation, resultStack);
- EXPECT_EQ(resultStack.size(), 1);
- auto treeResult = resultStack.PopAndReturn();
- ConfirmResult<double>(treeResult, 2.0/4.0);
- }
- {
- resultStack.emplace(2.0);
- resultStack.emplace(0.0);
- EXPECT_EQ(resultStack.size(), 2);
- operatorInterface.EvaluateToken(operatorInformation, resultStack);
- EXPECT_EQ(resultStack.size(), 0);
- }
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_MathOperatorTest_ModuloOperator)
- {
- MathExpressionOperators advandedMathInterface;
-
- ElementInformation operatorInformation = MathExpressionOperators::ModuloOperator();
- ExpressionResultStack resultStack;
- {
- resultStack.emplace(4.0);
- resultStack.emplace(2.0);
- EXPECT_EQ(resultStack.size(), 2);
- advandedMathInterface.EvaluateToken(operatorInformation, resultStack);
- EXPECT_EQ(resultStack.size(), 1);
- auto treeResult = resultStack.PopAndReturn();
- ConfirmResult<double>(treeResult, 4%2);
- }
- {
- resultStack.emplace(2.0);
- resultStack.emplace(4.0);
- EXPECT_EQ(resultStack.size(), 2);
- advandedMathInterface.EvaluateToken(operatorInformation, resultStack);
- EXPECT_EQ(resultStack.size(), 1);
- auto treeResult = resultStack.PopAndReturn();
- ConfirmResult<double>(treeResult, 2 % 4);
- }
- {
- resultStack.emplace(2.0);
- resultStack.emplace(0.0);
- EXPECT_EQ(resultStack.size(), 2);
- advandedMathInterface.EvaluateToken(operatorInformation, resultStack);
- EXPECT_EQ(resultStack.size(), 0);
- }
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_MathOperatorTest_BasicMathParser)
- {
- MathExpressionOperators mathParser;
-
- {
- ExpressionElementParser::ParseResult result = mathParser.ParseElement("+", 0);
- EXPECT_EQ(result.m_charactersConsumed, 1);
- EXPECT_EQ(result.m_element.m_id, MathExpressionOperators::MathOperatorId::Add);
- EXPECT_TRUE(result.m_element.m_extraStore.empty());
- }
-
- {
- ExpressionElementParser::ParseResult result = mathParser.ParseElement("-", 0);
- EXPECT_EQ(result.m_charactersConsumed, 1);
- EXPECT_EQ(result.m_element.m_id, MathExpressionOperators::MathOperatorId::Subtract);
- EXPECT_TRUE(result.m_element.m_extraStore.empty());
- }
- {
- ExpressionElementParser::ParseResult result = mathParser.ParseElement("*", 0);
- EXPECT_EQ(result.m_charactersConsumed, 1);
- EXPECT_EQ(result.m_element.m_id, MathExpressionOperators::MathOperatorId::Multiply);
- EXPECT_TRUE(result.m_element.m_extraStore.empty());
- }
- {
- ExpressionElementParser::ParseResult result = mathParser.ParseElement("/", 0);
- EXPECT_EQ(result.m_charactersConsumed, 1);
- EXPECT_EQ(result.m_element.m_id, MathExpressionOperators::MathOperatorId::Divide);
- EXPECT_TRUE(result.m_element.m_extraStore.empty());
- }
- {
- ExpressionElementParser::ParseResult result = mathParser.ParseElement("%", 0);
- EXPECT_EQ(result.m_charactersConsumed, 1);
- EXPECT_EQ(result.m_element.m_id, MathExpressionOperators::MathOperatorId::Modulo);
- EXPECT_TRUE(result.m_element.m_extraStore.empty());
- }
- {
- ExpressionElementParser::ParseResult result = mathParser.ParseElement("(", 0);
- EXPECT_EQ(result.m_charactersConsumed, 0);
- }
- {
- ExpressionElementParser::ParseResult result = mathParser.ParseElement("ABCDEFG", 0);
- EXPECT_EQ(result.m_charactersConsumed, 0);
- }
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_MathTest_SimpleTreeEvaluation)
- {
- {
- ExpressionTree tree;
- PushPrimitive(tree, 3.0);
- PushPrimitive(tree, 1.0);
- PushOperator(tree, Interfaces::MathOperators, MathExpressionOperators::AddOperator());
- auto result = GetExpressionEvaluationRequests()->Evaluate(tree);
- ConfirmResult<double>(result, 3.0+1.0);
- }
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_MathTest_ComplexTreeEvaluation)
- {
- {
- ExpressionTree tree;
- PushPrimitive(tree, 2.0);
- PushPrimitive(tree, 2.0);
- PushOperator(tree, Interfaces::MathOperators, MathExpressionOperators::AddOperator());
- PushPrimitive(tree, 4.0);
- PushPrimitive(tree, 3.0);
- PushOperator(tree, Interfaces::MathOperators, MathExpressionOperators::SubtractOperator());
- PushOperator(tree, Interfaces::MathOperators, MathExpressionOperators::MultiplyOperator());
- PushPrimitive(tree, 2.0);
- PushOperator(tree, Interfaces::MathOperators, MathExpressionOperators::DivideOperator());
- auto result = GetExpressionEvaluationRequests()->Evaluate(tree);
- ConfirmResult<double>(result, ((2.0 + 2.0)*(4.0 - 3.0)) / 2.0);
- }
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_MathTest_BasicParserPass)
- {
- AZ::Outcome<ExpressionTree, ParsingError> treeOutcome = GetExpressionEvaluationRequests()->ParseExpression("3+1");
- EXPECT_TRUE(treeOutcome.IsSuccess());
- const ExpressionTree& tree = treeOutcome.GetValue();
- EXPECT_EQ(tree.GetTreeSize(), 3);
- auto result = GetExpressionEvaluationRequests()->Evaluate(tree);
- ConfirmResult<double>(result, 3+1);
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_MathTest_BasicParserPassMultiOperator)
- {
- AZ::Outcome<ExpressionTree, ParsingError> treeOutcome = GetExpressionEvaluationRequests()->ParseExpression("3+1*5");
- EXPECT_TRUE(treeOutcome.IsSuccess());
- const ExpressionTree& tree = treeOutcome.GetValue();
- // 3 Values + 2 Operators
- EXPECT_EQ(tree.GetTreeSize(), 3 + 2);
- auto result = GetExpressionEvaluationRequests()->Evaluate(tree);
- ConfirmResult<double>(result, 3 + 1 * 5);
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_NumericParser_ComplexParserPass)
- {
- AZ::Outcome<ExpressionTree, ParsingError> treeOutcome = GetExpressionEvaluationRequests()->ParseExpression("(3 + 1)");
- EXPECT_TRUE(treeOutcome.IsSuccess());
- const ExpressionTree& tree = treeOutcome.GetValue();
- EXPECT_EQ(tree.GetTreeSize(), 3);
- auto result = GetExpressionEvaluationRequests()->Evaluate(tree);
- ConfirmResult<double>(result, (3.0 + 1.0));
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_NumericParser_ComplexParserPassMultiOperator)
- {
- AZ::Outcome<ExpressionTree, ParsingError> treeOutcome = GetExpressionEvaluationRequests()->ParseExpression("((2.0 + 2.0)*(4.0 - 3.0)) / 2.0");
- EXPECT_TRUE(treeOutcome.IsSuccess());
- const ExpressionTree& tree = treeOutcome.GetValue();
- // 5 values + 4 operators
- EXPECT_EQ(tree.GetTreeSize(), 5 + 4);
- auto result = GetExpressionEvaluationRequests()->Evaluate(tree);
- ConfirmResult<double>(result, ((2.0 + 2.0)*(4.0 - 3.0)) / 2.0);
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_NumericParser_ObtuseParserPassMultiOperator)
- {
- AZ::Outcome<ExpressionTree, ParsingError> treeOutcome = GetExpressionEvaluationRequests()->ParseExpression("(( (( ) )( 2.0) + 2.0)*(4.0 - 3.0)) / (((2.0 )))");
- EXPECT_TRUE(treeOutcome.IsSuccess());
- const ExpressionTree& tree = treeOutcome.GetValue();
- // 5 values + 4 operators
- EXPECT_EQ(tree.GetTreeSize(), 5 + 4);
- auto result = GetExpressionEvaluationRequests()->Evaluate(tree);
- ConfirmResult<double>(result, ((2.0 + 2.0)*(4.0 - 3.0)) / 2.0);
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_NumericParser_AdvancedParserPass)
- {
- AZ::Outcome<ExpressionTree, ParsingError> treeOutcome = GetExpressionEvaluationRequests()->ParseExpression("(3 + 1) % 2");
- EXPECT_TRUE(treeOutcome.IsSuccess());
- const ExpressionTree& tree = treeOutcome.GetValue();
- EXPECT_EQ(tree.GetTreeSize(), 3 + 2);
- auto result = GetExpressionEvaluationRequests()->Evaluate(tree);
- ConfirmResult<double>(result, (3+1)%2);
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_NumericParser_BasicVariablePass)
- {
- AZ::Outcome<ExpressionTree, ParsingError> treeOutcome = GetExpressionEvaluationRequests()->ParseExpression("{A}+{B}");
- EXPECT_TRUE(treeOutcome.IsSuccess());
- ExpressionTree& tree = treeOutcome.GetValue();
- EXPECT_EQ(tree.GetTreeSize(), 2 + 1);
- auto variables = tree.GetVariables();
- EXPECT_EQ(static_cast<int>(variables.size()), 2);
- {
- AZStd::string variable = variables[0];
- EXPECT_EQ(variable, AZStd::string("A"));
- tree.SetVariable(variable, 3.0);
- }
- {
- AZStd::string variable = variables[1];
- EXPECT_EQ(variable, AZStd::string("B"));
- tree.SetVariable(variable, 1.0);
- }
- auto result = GetExpressionEvaluationRequests()->Evaluate(tree);
- ConfirmResult<double>(result, 3.0+1.0);
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_NumericParser_BasicRepeatedVariablePass)
- {
- AZ::Outcome<ExpressionTree, ParsingError> treeOutcome = GetExpressionEvaluationRequests()->ParseExpression("{A}+{B}+{A}");
- EXPECT_TRUE(treeOutcome.IsSuccess());
- ExpressionTree& tree = treeOutcome.GetValue();
- EXPECT_EQ(tree.GetTreeSize(), 3 + 2);
- auto variables = tree.GetVariables();
- EXPECT_EQ(static_cast<int>(variables.size()), 2);
- {
- AZStd::string variable = variables[0];
- EXPECT_EQ(variable, AZStd::string("A"));
- tree.SetVariable(variable, 3.0);
- }
- {
- AZStd::string variable = variables[1];
- EXPECT_EQ(variable, AZStd::string("B"));
- tree.SetVariable(variable, 1.0);
- }
- auto result = GetExpressionEvaluationRequests()->Evaluate(tree);
- ConfirmResult<double>(result, 3.0 + 1.0 + 3.0);
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_NumericParser_BasicFail)
- {
- AZ::Outcome<ExpressionTree, ParsingError> treeOutcome = GetExpressionEvaluationRequests()->ParseRestrictedExpression(MathOnlyOperatorRestrictions(), "true || false");
- EXPECT_FALSE(treeOutcome.IsSuccess());
- EXPECT_EQ(treeOutcome.GetError().m_offsetIndex, 0);
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_NumericParser_ComplexFail)
- {
- AZ::Outcome<ExpressionTree, ParsingError> treeOutcome = GetExpressionEvaluationRequests()->ParseRestrictedExpression(MathOnlyOperatorRestrictions(), "2+2 || 1+3");
- EXPECT_FALSE(treeOutcome.IsSuccess());
- EXPECT_EQ(treeOutcome.GetError().m_offsetIndex, 4);
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_ParenParser_UnbalancedCloseFail)
- {
- AZ::Outcome<ExpressionTree, ParsingError> treeOutcome = GetExpressionEvaluationRequests()->ParseRestrictedExpression(MathOnlyOperatorRestrictions(), "1+1)");
- EXPECT_FALSE(treeOutcome.IsSuccess());
- EXPECT_EQ(treeOutcome.GetError().m_offsetIndex, 3);
- }
- TEST_F(ExpressionEngineTestFixture, ExpressionEngine_ParenParser_UnbalancedOpenFail)
- {
- AZ::Outcome<ExpressionTree, ParsingError> treeOutcome = GetExpressionEvaluationRequests()->ParseRestrictedExpression(MathOnlyOperatorRestrictions(), "(1+1");
- EXPECT_FALSE(treeOutcome.IsSuccess());
- EXPECT_EQ(treeOutcome.GetError().m_offsetIndex, 0);
- }
- }
|