diff --git a/tests/ParserTests/VirtPropTests.cpp b/tests/ParserTests/VirtPropTests.cpp new file mode 100644 index 0000000..0660c0a --- /dev/null +++ b/tests/ParserTests/VirtPropTests.cpp @@ -0,0 +1,131 @@ +#include "../../extern/doctest.hpp" +#include "../../src/Parser/Parser.hpp" + +using namespace MalachScript; + +#define PARSER_TEST(name, tokens, asserts) \ + TEST_CASE(name) { \ + std::vector vec = { \ + tokens, \ + new Parser::LexTokenImpl(TextSpan(0, 0)), \ + }; \ + for (size_t i = 0; i < vec.size() - 1; i++) { \ + vec[i]->SetNext(vec[i + 1]); \ + } \ + Diagnostics::Diagnostics diags; \ + auto parser = Parser::Parser(u8"scriptname", vec.front(), &diags); \ + auto* script = parser.Parse(); \ + REQUIRE(diags.GetMessages().empty()); \ + asserts; \ + delete vec[0]; \ + delete script; \ + } + +#define PARSER_TEST_TOKENS(...) __VA_ARGS__ + +PARSER_TEST( + "Parse class foobar { bool foo { get; set; } }", + PARSER_TEST_TOKENS(new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::IdentifierToken(TextSpan(0, 0), u8"foobar"), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::IdentifierToken(TextSpan(0, 0), u8"bool"), + new Parser::IdentifierToken(TextSpan(0, 0), u8"foo"), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0))), + { + REQUIRE(script->GetStatements().size() == 1); + auto firstStatement = script->GetStatements()[0].get(); + REQUIRE(firstStatement->GetKind() == Parser::ParsedStatementKind::Class); + auto firstClassStatement = + dynamic_cast(firstStatement)->GetBody()[0].get(); + REQUIRE(firstClassStatement->GetKind() == Parser::ParsedStatementKind::VirtProp); + auto virtPropStatement = + dynamic_cast(firstClassStatement); + REQUIRE(virtPropStatement->GetAccess() == MalachScript::AccessModifier::Public); + REQUIRE(virtPropStatement->GetIdentifier().GetString() == u8"foo"); + REQUIRE(virtPropStatement->HasGet()); + REQUIRE(virtPropStatement->HasSet()); + REQUIRE_FALSE(virtPropStatement->IsGetConst()); + REQUIRE_FALSE(virtPropStatement->IsSetConst()); + REQUIRE(virtPropStatement->GetGetStatement() == nullptr); + REQUIRE(virtPropStatement->GetSetStatement() == nullptr); + }) + +PARSER_TEST( + "Parse class foobar { bool foo { get const; set const; } }", + PARSER_TEST_TOKENS(new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::IdentifierToken(TextSpan(0, 0), u8"foobar"), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::IdentifierToken(TextSpan(0, 0), u8"bool"), + new Parser::IdentifierToken(TextSpan(0, 0), u8"foo"), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0))), + { + REQUIRE(script->GetStatements().size() == 1); + auto firstStatement = script->GetStatements()[0].get(); + REQUIRE(firstStatement->GetKind() == Parser::ParsedStatementKind::Class); + auto firstClassStatement = + dynamic_cast(firstStatement)->GetBody()[0].get(); + REQUIRE(firstClassStatement->GetKind() == Parser::ParsedStatementKind::VirtProp); + auto virtPropStatement = + dynamic_cast(firstClassStatement); + REQUIRE(virtPropStatement->GetAccess() == MalachScript::AccessModifier::Public); + REQUIRE(virtPropStatement->GetIdentifier().GetString() == u8"foo"); + REQUIRE(virtPropStatement->HasGet()); + REQUIRE(virtPropStatement->HasSet()); + REQUIRE(virtPropStatement->IsGetConst()); + REQUIRE(virtPropStatement->IsSetConst()); + REQUIRE(virtPropStatement->GetGetStatement() == nullptr); + REQUIRE(virtPropStatement->GetSetStatement() == nullptr); + }) + +PARSER_TEST( + "Parse class foobar { bool foo { get const override; set const override; } }", + PARSER_TEST_TOKENS(new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::IdentifierToken(TextSpan(0, 0), u8"foobar"), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::IdentifierToken(TextSpan(0, 0), u8"bool"), + new Parser::IdentifierToken(TextSpan(0, 0), u8"foo"), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0))), + { + REQUIRE(script->GetStatements().size() == 1); + auto firstStatement = script->GetStatements()[0].get(); + REQUIRE(firstStatement->GetKind() == Parser::ParsedStatementKind::Class); + auto firstClassStatement = + dynamic_cast(firstStatement)->GetBody()[0].get(); + REQUIRE(firstClassStatement->GetKind() == Parser::ParsedStatementKind::VirtProp); + auto virtPropStatement = + dynamic_cast(firstClassStatement); + REQUIRE(virtPropStatement->GetAccess() == MalachScript::AccessModifier::Public); + REQUIRE(virtPropStatement->GetIdentifier().GetString() == u8"foo"); + REQUIRE(virtPropStatement->HasGet()); + REQUIRE(virtPropStatement->HasSet()); + REQUIRE(virtPropStatement->IsGetConst()); + REQUIRE(virtPropStatement->IsSetConst()); + REQUIRE(FuncAttrHelpers::Contains(virtPropStatement->GetGetFuncAttr(), FuncAttr::Override)); + REQUIRE(FuncAttrHelpers::Contains(virtPropStatement->GetSetFuncAttr(), FuncAttr::Override)); + REQUIRE(virtPropStatement->GetGetStatement() == nullptr); + REQUIRE(virtPropStatement->GetSetStatement() == nullptr); + }) \ No newline at end of file