From 7680f92ae1690aab3ec8ee4d9fed8e2792ba02f6 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 25 Nov 2021 01:20:51 +0100 Subject: [PATCH] Add base for simple expression unit tests --- premake5.lua | 2 + .../Expression/SimpleExpressionMatchers.h | 3 +- test/ParserTests.lua | 53 ++++++++++ .../Parsing/Simple/SimpleExpressionTests.cpp | 100 ++++++++++++++++++ test/ParserTests/main.cpp | 2 + 5 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 test/ParserTests.lua create mode 100644 test/ParserTests/Parsing/Simple/SimpleExpressionTests.cpp create mode 100644 test/ParserTests/main.cpp diff --git a/premake5.lua b/premake5.lua index 3ba48f78..638c8583 100644 --- a/premake5.lua +++ b/premake5.lua @@ -129,6 +129,7 @@ group "" include "test/ObjCommonTests.lua" include "test/ObjLoadingTests.lua" include "test/ParserTestUtils.lua" +include "test/ParserTests.lua" include "test/ZoneCodeGeneratorLibTests.lua" include "test/ZoneCommonTests.lua" @@ -137,6 +138,7 @@ group "Tests" ObjCommonTests:project() ObjLoadingTests:project() ParserTestUtils:project() + ParserTests:project() ZoneCodeGeneratorLibTests:project() ZoneCommonTests:project() group "" \ No newline at end of file diff --git a/src/Parser/Parsing/Simple/Expression/SimpleExpressionMatchers.h b/src/Parser/Parsing/Simple/Expression/SimpleExpressionMatchers.h index 5d9cb3f2..29332cc8 100644 --- a/src/Parser/Parsing/Simple/Expression/SimpleExpressionMatchers.h +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionMatchers.h @@ -34,6 +34,7 @@ private: public: SimpleExpressionMatchers(); + SimpleExpressionMatchers(bool enableStringOperands, bool enableIdentifierOperands, bool enableFloatingPointOperands, bool enableIntOperands); virtual ~SimpleExpressionMatchers(); SimpleExpressionMatchers(const SimpleExpressionMatchers& other) = default; SimpleExpressionMatchers(SimpleExpressionMatchers&& other) noexcept = default; @@ -41,8 +42,6 @@ public: SimpleExpressionMatchers& operator=(SimpleExpressionMatchers&& other) noexcept = default; protected: - SimpleExpressionMatchers(bool enableStringOperands, bool enableIdentifierOperands, bool enableFloatingPointOperands, bool enableIntOperands); - virtual std::unique_ptr ParseOperandExtension(const supplier_t* labelSupplier) const; virtual std::unique_ptr ProcessOperandExtension(SequenceResult& result) const; diff --git a/test/ParserTests.lua b/test/ParserTests.lua new file mode 100644 index 00000000..7e8cb35f --- /dev/null +++ b/test/ParserTests.lua @@ -0,0 +1,53 @@ +ParserTests = {} + +function ParserTests:include(includes) + if includes:handle(self:name()) then + includedirs { + path.join(TestFolder(), "ParserTests") + } + end +end + +function ParserTests:link(links) + +end + +function ParserTests:use() + +end + +function ParserTests:name() + return "ParserTests" +end + +function ParserTests:project() + local folder = TestFolder() + local includes = Includes:create() + local links = Links:create() + + project(self:name()) + targetdir(TargetDirectoryTest) + location "%{wks.location}/test/%{prj.name}" + kind "ConsoleApp" + language "C++" + + files { + path.join(folder, "ParserTests/**.h"), + path.join(folder, "ParserTests/**.cpp") + } + + vpaths { + ["*"] = { + path.join(folder, "ParserTests") + } + } + + self:include(includes) + ParserTestUtils:include(includes) + Parser:include(includes) + catch2:include(includes) + + links:linkto(ParserTestUtils) + links:linkto(Parser) + links:linkall() +end diff --git a/test/ParserTests/Parsing/Simple/SimpleExpressionTests.cpp b/test/ParserTests/Parsing/Simple/SimpleExpressionTests.cpp new file mode 100644 index 00000000..8ee8ee74 --- /dev/null +++ b/test/ParserTests/Parsing/Simple/SimpleExpressionTests.cpp @@ -0,0 +1,100 @@ +#include + +#include "Parsing/Impl/AbstractParser.h" +#include "Utils/ClassUtils.h" +#include "Parsing/Mock/MockLexer.h" +#include "Parsing/Simple/SimpleParserValue.h" +#include "Parsing/Simple/Expression/ISimpleExpression.h" +#include "Parsing/Simple/Expression/SimpleExpressionMatchers.h" +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +namespace test::parsing::simple::expression +{ + class SimpleExpressionTestState + { + public: + std::unique_ptr m_expression; + }; + + class SimpleExpressionSequence final : public AbstractSequence + { + const SimpleExpressionMatchers m_expression_matchers; + + public: + SimpleExpressionSequence() + : m_expression_matchers(true, true, true, true) + { + const SimpleMatcherFactory create(this); + + AddLabeledMatchers(m_expression_matchers.Expression(this), SimpleExpressionMatchers::LABEL_EXPRESSION); + AddMatchers(create.Label(SimpleExpressionMatchers::LABEL_EXPRESSION)); + } + + protected: + void ProcessMatch(SimpleExpressionTestState* state, SequenceResult& result) const override + { + state->m_expression = m_expression_matchers.ProcessExpression(result); + } + }; + + class SimpleExpressionTestsHelper + { + public: + std::unique_ptr m_state; + std::unique_ptr> m_lexer; + + std::unique_ptr m_sequence; + + unsigned m_consumed_token_count; + + explicit SimpleExpressionTestsHelper() + : m_state(std::make_unique()), + m_sequence(std::make_unique()), + m_consumed_token_count(0u) + { + } + + void Tokens(std::initializer_list> tokens) + { + m_lexer = std::make_unique>(tokens, SimpleParserValue::EndOfFile(TokenPos())); + } + + void Tokens(std::vector tokens) + { + m_lexer = std::make_unique>(std::move(tokens), SimpleParserValue::EndOfFile(TokenPos())); + } + + bool PerformTest() + { + REQUIRE(m_lexer); + + m_consumed_token_count = 0; + return m_sequence->MatchSequence(m_lexer.get(), m_state.get(), m_consumed_token_count); + } + }; + + TEST_CASE("SimpleExpressions: Can parse expression with add operation", "[parsing][simple][expression]") + { + SimpleExpressionTestsHelper helper; + const TokenPos pos; + helper.Tokens({ + SimpleParserValue::Integer(pos, 1336), + SimpleParserValue::Character(pos, '+'), + SimpleParserValue::Integer(pos, 1), + SimpleParserValue::EndOfFile(pos) + }); + + const auto result = helper.PerformTest(); + + REQUIRE(result); + REQUIRE(helper.m_consumed_token_count == 3); + + const auto& expression = helper.m_state->m_expression; + REQUIRE(expression->IsStatic()); + + const auto value = expression->Evaluate(); + REQUIRE(value.m_type == SimpleExpressionValue::Type::INT); + REQUIRE(value.m_int_value == 1337); + } + +} diff --git a/test/ParserTests/main.cpp b/test/ParserTests/main.cpp new file mode 100644 index 00000000..2380d6bf --- /dev/null +++ b/test/ParserTests/main.cpp @@ -0,0 +1,2 @@ +#define CATCH_CONFIG_MAIN +#include \ No newline at end of file