#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include "../../extern/doctest.hpp" #include "../../src/ASTypeDefParser/Parser.hpp" TEST_CASE("Register Empty Type") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, "type foo{}"); res.RegisterTypes(engine); res.RegisterImplementation(engine); REQUIRE(engine->GetTypeInfoByName("foo") != nullptr); engine->Release(); } void MessageCallback(const asSMessageInfo *msg, void *param) { const char *type = "ERR "; if( msg->type == asMSGTYPE_WARNING ) type = "WARN"; else if( msg->type == asMSGTYPE_INFORMATION ) type = "INFO"; printf("%s (%d, %d) : %s : %s\n", msg->section, msg->row, msg->col, type, msg->message); } TEST_CASE("Register Empty Value Type") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, "valuetype foo{}"); res.RegisterTypes(engine); res.RegisterImplementation(engine); REQUIRE(engine->GetTypeInfoByName("foo") != nullptr); engine->Release(); } TEST_CASE("Register Empty Type With Semicolon") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, "type foo;"); res.RegisterTypes(engine); res.RegisterImplementation(engine); REQUIRE(engine->GetTypeInfoByName("foo") != nullptr); engine->Release(); } TEST_CASE("Register Multiple Empty Types") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, "type foo{} type bar{}"); res.RegisterTypes(engine); res.RegisterImplementation(engine); REQUIRE(engine->GetTypeInfoByName("foo") != nullptr); REQUIRE(engine->GetTypeInfoByName("bar") != nullptr); engine->Release(); } TEST_CASE("Register Type With Method") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( type foo { int Bar(int a, int b); } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("foo"); REQUIRE(type != nullptr); auto method = type->GetMethodByName("Bar"); REQUIRE(method != nullptr); REQUIRE_EQ(method->GetParamCount(), 2); REQUIRE_EQ(std::string(method->GetDeclaration(false, false, true)), "int Bar(int a, int b)"); engine->Release(); } TEST_CASE("Register Type With Multiple Methods") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( type foo { int Bar(int a, int b); int Zet(int a, int b); } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("foo"); REQUIRE(type != nullptr); auto method = type->GetMethodByName("Bar"); REQUIRE(method != nullptr); REQUIRE_EQ(method->GetParamCount(), 2); REQUIRE_EQ(std::string(method->GetDeclaration(false, false, true)), "int Bar(int a, int b)"); method = type->GetMethodByName("Zet"); REQUIRE(method != nullptr); engine->Release(); } TEST_CASE("Register Generic Type With Method") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( type foo { T@ Bar(int a, int b); } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("foo"); REQUIRE(type != nullptr); REQUIRE(type == engine->GetTypeInfoByDecl("foo")); auto method = type->GetMethodByName("Bar"); REQUIRE(method != nullptr); REQUIRE_EQ(method->GetParamCount(), 2); REQUIRE_EQ(std::string(method->GetDeclaration(false, false, true)), "T@ Bar(int a, int b)"); engine->Release(); } TEST_CASE("Register Generic Type With Multiple implementations") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( type foo { T@ Bar(int a, int b); } type a { foo GetFoo(); } type b { foo GetBar(); } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("foo"); REQUIRE(type != nullptr); REQUIRE(type == engine->GetTypeInfoByDecl("foo")); auto method = type->GetMethodByName("Bar"); REQUIRE(method != nullptr); REQUIRE_EQ(method->GetParamCount(), 2); REQUIRE_EQ(std::string(method->GetDeclaration(false, false, true)), "T@ Bar(int a, int b)"); engine->Release(); } TEST_CASE("Register Type With Get Property") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( type foo { int Bar { get; }; } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("foo"); REQUIRE(type != nullptr); auto method = type->GetMethodByName("get_Bar"); REQUIRE(method != nullptr); REQUIRE_EQ(std::string(method->GetDeclaration(false, false, true)), "int get_Bar()"); engine->Release(); } TEST_CASE("Register Type With Get Const Property") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( type foo { int Bar { get const; }; } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("foo"); REQUIRE(type != nullptr); auto method = type->GetMethodByName("get_Bar"); REQUIRE(method != nullptr); REQUIRE_EQ(std::string(method->GetDeclaration(false, false, true)), "int get_Bar() const"); engine->Release(); } TEST_CASE("Register Type With Set Property") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( type foo { int Bar { set; }; } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("foo"); REQUIRE(type != nullptr); auto method = type->GetMethodByName("set_Bar"); REQUIRE(method != nullptr); REQUIRE_EQ(std::string(method->GetDeclaration(false, false, true)), "void set_Bar(int value)"); engine->Release(); } TEST_CASE("Register Type With Set Const Property") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( type foo { int Bar { set const; }; } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("foo"); REQUIRE(type != nullptr); auto method = type->GetMethodByName("set_Bar"); REQUIRE(method != nullptr); REQUIRE_EQ(std::string(method->GetDeclaration(false, false, true)), "void set_Bar(int value) const"); engine->Release(); } TEST_CASE("Register Type With Set Property") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( type foo { int Bar { set; }; } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("foo"); REQUIRE(type != nullptr); auto method = type->GetMethodByName("set_Bar"); REQUIRE(method != nullptr); REQUIRE_EQ(std::string(method->GetDeclaration(false, false, true)), "void set_Bar(int value)"); engine->Release(); } TEST_CASE("Register Type With Getter and Setter Property") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( type foo { int Bar { get; set; }; } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("foo"); REQUIRE(type != nullptr); auto method = type->GetMethodByName("get_Bar"); REQUIRE(method != nullptr); REQUIRE_EQ(std::string(method->GetDeclaration(false, false, true)), "int get_Bar()"); method = type->GetMethodByName("set_Bar"); REQUIRE(method != nullptr); REQUIRE_EQ(std::string(method->GetDeclaration(false, false, true)), "void set_Bar(int value)"); engine->Release(); } TEST_CASE("Register Type With Multiple Getter and Setter Properties") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( type foo { int Bar { get; set; }; int Zet { get; set; }; } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("foo"); REQUIRE(type != nullptr); auto method = type->GetMethodByName("get_Bar"); REQUIRE(method != nullptr); REQUIRE_EQ(std::string(method->GetDeclaration(false, false, true)), "int get_Bar()"); method = type->GetMethodByName("set_Bar"); REQUIRE(method != nullptr); REQUIRE_EQ(std::string(method->GetDeclaration(false, false, true)), "void set_Bar(int value)"); method = type->GetMethodByName("get_Zet"); REQUIRE(method != nullptr); REQUIRE_EQ(std::string(method->GetDeclaration(false, false, true)), "int get_Zet()"); method = type->GetMethodByName("set_Zet"); REQUIRE(method != nullptr); REQUIRE_EQ(std::string(method->GetDeclaration(false, false, true)), "void set_Zet(int value)"); engine->Release(); } TEST_CASE("Register Empty Enum") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( enum foo { } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("foo"); REQUIRE(type != nullptr); REQUIRE(type->GetTypeId() % asOBJ_ENUM != 0); engine->Release(); } TEST_CASE("Register Enum with value") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( enum foo { One } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("foo"); REQUIRE(type != nullptr); REQUIRE(type->GetTypeId() % asOBJ_ENUM != 0); int i = -1; REQUIRE_EQ(std::string(type->GetEnumValueByIndex(0, &i)), "One"); REQUIRE_EQ(i, 0); engine->Release(); } TEST_CASE("Register Enum with multiple values") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( enum foo { One, Two } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("foo"); REQUIRE(type != nullptr); REQUIRE(type->GetTypeId() % asOBJ_ENUM != 0); int i = -1; REQUIRE_EQ(std::string(type->GetEnumValueByIndex(0, &i)), "One"); REQUIRE_EQ(i, 0); REQUIRE_EQ(std::string(type->GetEnumValueByIndex(1, &i)), "Two"); REQUIRE_EQ(i, 1); engine->Release(); } TEST_CASE("Register Enum with explicit value") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( enum foo { One = 5 } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("foo"); REQUIRE(type != nullptr); REQUIRE(type->GetTypeId() % asOBJ_ENUM != 0); int i = -1; REQUIRE_EQ(std::string(type->GetEnumValueByIndex(0, &i)), "One"); REQUIRE_EQ(i, 5); engine->Release(); } TEST_CASE("Register Enum with multiple explicit values") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( enum foo { One = 5, Two = 1, Three = -1000, } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("foo"); REQUIRE(type != nullptr); REQUIRE(type->GetTypeId() % asOBJ_ENUM != 0); int i = -1; REQUIRE_EQ(std::string(type->GetEnumValueByIndex(0, &i)), "One"); REQUIRE_EQ(i, 5); REQUIRE_EQ(std::string(type->GetEnumValueByIndex(1, &i)), "Two"); REQUIRE_EQ(i, 1); REQUIRE_EQ(std::string(type->GetEnumValueByIndex(2, &i)), "Three"); REQUIRE_EQ(i, -1000); engine->Release(); } TEST_CASE("Register Global Function") { asIScriptEngine* engine = asCreateScriptEngine(); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( func void print(int i); )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto func = engine->GetGlobalFunctionByDecl("void print(int i)"); REQUIRE(func != nullptr); engine->Release(); } TEST_CASE("Register Type With Behaviour") { asIScriptEngine* engine = asCreateScriptEngine(); engine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL); ASTypeDefParser::TypeDefResult res; ASTypeDefParser::Parser::ParseAndRegister(res, R"( type fooClass { behave 4 fooClass@ f(int &in) {repeat int}; } )"); res.RegisterTypes(engine); res.RegisterImplementation(engine); auto type = engine->GetTypeInfoByName("fooClass"); REQUIRE(type != nullptr); REQUIRE_EQ(type->GetBehaviourCount(), 1); asEBehaviours b; REQUIRE_EQ(std::string(type->GetBehaviourByIndex(0, &b)->GetDeclaration()), "fooClass@ $list(int&in) { repeat int }"); engine->Release(); }