#ifdef TESTS_BUILD #include #include "../src/Script.hpp" #include "../../src/UserData/UserData.hpp" #include "../../src/UserData/UserDataStorage.hpp" #include "../../src/UserData/UserDataValue.hpp" #include "../../src/UserData/UserDataFunction.hpp" #include "../../src/UserData/UserDataFunctionType.hpp" #include "../../src/UserData/UserDataTemplates.hpp" #include "../../src/UserData/UserDataCollections/UserDataCollectionType.hpp" #include "../../src/UserData/UserDataCollections/UserDataCollectionValue.hpp" #include "../../src/UserData/UserDataCollections/UserDataCollectionRangeIterator.hpp" #include "../../src/Evaluator/EvalValues/EvalValueHelper.hpp" using namespace Porygon; using namespace Porygon::UserData; using namespace Porygon::Utilities; class UserDataTestObject{ public: int foo = 10; int readonly = 5; vector fooVector = {5,10,15,25}; int getFoo(){ return foo; } int Addition(int a, int b){ return a + b; } // Declare script properties private: PORYGON_PREPARE_FUNCTION(UserDataTestObject, getFoo, IntegerEvalValue) PORYGON_PREPARE_FUNCTION(UserDataTestObject, Addition, IntegerEvalValue, (par[0] -> EvaluateInteger()), (par[1] -> EvaluateInteger())) void __setFooVector(const EvalValue* key, const EvalValue* value){ auto index = key->EvaluateInteger(); fooVector[index] = value->EvaluateInteger(); } public: PORYGON_USERDATA(testObject, UserDataTestObject, PORYGON_INTEGER_FIELD(foo) PORYGON_READONLY_INTEGER_FIELD(readonly) PORYGON_INTEGER_FUNCTION(getFoo) PORYGON_INTEGER_FUNCTION(Addition, PORYGON_INTEGER_TYPE, PORYGON_INTEGER_TYPE) PORYGON_READONLY_VECTOR_FIELD(fooVector, PORYGON_INTEGER_TYPE) ) }; TEST_CASE( "Gets UserData value", "[integration]" ) { UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData()); Script* script = Script::Create(R"( function testFunc(testObject obj) return obj["foo"] end )"); REQUIRE(!script->Diagnostics -> HasErrors()); script->Evaluate(); auto par = new UserDataTestObject(); auto parameter = new UserDataValue(HashedString::ConstHash("testObject"), par); auto variable = script->CallFunction(u"testFunc", {parameter}); REQUIRE(variable != nullptr); REQUIRE(variable->EvaluateInteger() == 10); delete par; delete parameter; delete script; delete variable; UserDataStorage::RemoveType(HashedString::ConstHash("testObject")); } TEST_CASE( "Sets UserData value", "[integration]" ) { UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData()); Script* script = Script::Create(R"( function testFunc(testObject obj) obj["foo"] = 5000 end )"); REQUIRE(!script->Diagnostics -> HasErrors()); script->Evaluate(); auto obj = new UserDataTestObject(); auto parameter = new UserDataValue(HashedString::ConstHash("testObject"), obj); script->CallFunction(u"testFunc", {parameter}); delete script; REQUIRE(obj->foo == 5000); delete obj; delete parameter; UserDataStorage::RemoveType(HashedString::ConstHash("testObject")); } TEST_CASE( "Calls UserData function", "[integration]" ) { UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData()); Script* script = Script::Create(R"( function testFunc(testObject obj) return obj.getFoo() end )"); REQUIRE(!script->Diagnostics -> HasErrors()); script->Evaluate(); auto obj = new UserDataTestObject(); auto parameter = new UserDataValue(HashedString::ConstHash("testObject"), obj); auto result = script->CallFunction(u"testFunc", {parameter}); REQUIRE(result -> EvaluateInteger() == 10); delete script; delete obj; delete parameter; delete result; UserDataStorage::RemoveType(HashedString::ConstHash("testObject")); } TEST_CASE( "Calls UserData function with parameters", "[integration]" ) { UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData()); Script* script = Script::Create(R"( function testFunc(testObject obj) return obj.Addition(5046, 8432) end )"); REQUIRE(!script->Diagnostics -> HasErrors()); script->Evaluate(); auto obj = new UserDataTestObject(); auto parameter = new UserDataValue(HashedString::ConstHash("testObject"), obj); auto result = script->CallFunction(u"testFunc", {parameter}); REQUIRE(result -> EvaluateInteger() == 13478); delete script; delete obj; delete parameter; delete result; UserDataStorage::RemoveType(HashedString::ConstHash("testObject")); } TEST_CASE( "Gets userdata vector value", "[integration]" ) { UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData()); Script* script = Script::Create(R"( function testFunc(testObject obj) return obj.fooVector[1] end )"); REQUIRE(!script->Diagnostics -> HasErrors()); script->Evaluate(); auto func = (GenericFunctionEvalValue*)script -> GetVariable(u"testFunc"); auto funcType = func -> GetType(); REQUIRE(funcType->GetFirstOption()->GetReturnType()->GetClass() == TypeClass::Number); auto obj = new UserDataTestObject(); auto parameter = new UserDataValue(HashedString::ConstHash("testObject"), obj); auto result = script->CallFunction(u"testFunc", {parameter}); REQUIRE(result -> EvaluateInteger() == 5); delete obj; delete parameter; delete result; delete script; delete func; UserDataStorage::RemoveType(HashedString::ConstHash("testObject")); } TEST_CASE( "Sets userdata vector value", "[integration]" ) { UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData()); Script* script = Script::Create(R"( function testFunc(testObject obj) obj.fooVector[3] = 684 end )"); REQUIRE(!script->Diagnostics -> HasErrors()); script->Evaluate(); auto func = (GenericFunctionEvalValue*)script -> GetVariable(u"testFunc"); auto funcType = func -> GetType(); auto obj = new UserDataTestObject(); auto parameter = new UserDataValue(HashedString::ConstHash("testObject"), obj); script->CallFunction(u"testFunc", {parameter}); REQUIRE(obj->fooVector[2] == 684); delete obj; delete parameter; delete script; delete func; UserDataStorage::RemoveType(HashedString::ConstHash("testObject")); } TEST_CASE( "returns readonly value + 2", "[integration]" ) { UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData()); Script* script = Script::Create(R"( function testFunc(testObject obj) return obj.readonly + 2 end )"); REQUIRE(!script->Diagnostics -> HasErrors()); script->Evaluate(); auto func = (GenericFunctionEvalValue*)script -> GetVariable(u"testFunc"); auto funcType = func -> GetType(); auto obj = new UserDataTestObject(); auto parameter = new UserDataValue(HashedString::ConstHash("testObject"), obj); auto result = script->CallFunction(u"testFunc", {parameter}); REQUIRE(result -> EvaluateInteger() == 7); delete obj; delete parameter; delete script; delete func; delete result; UserDataStorage::RemoveType(HashedString::ConstHash("testObject")); } TEST_CASE( "returns negative readonly value", "[integration]" ) { UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData()); Script* script = Script::Create(R"( function testFunc(testObject obj) return -obj.readonly end )"); REQUIRE(!script->Diagnostics -> HasErrors()); script->Evaluate(); auto func = (GenericFunctionEvalValue*)script -> GetVariable(u"testFunc"); auto funcType = func -> GetType(); auto obj = new UserDataTestObject(); auto parameter = new UserDataValue(HashedString::ConstHash("testObject"), obj); auto result = script->CallFunction(u"testFunc", {parameter}); REQUIRE(result -> EvaluateInteger() == -5); delete obj; delete parameter; delete script; delete func; delete result; UserDataStorage::RemoveType(HashedString::ConstHash("testObject")); } TEST_CASE( "Iterate over userdata vector keys", "[integration]" ) { UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData()); Script* script = Script::Create(R"( function testFunc(testObject obj) local val = 0 for i in obj.fooVector do val = val + i end return val end )"); REQUIRE(!script->Diagnostics -> HasErrors()); script->Evaluate(); auto func = (GenericFunctionEvalValue*)script -> GetVariable(u"testFunc"); auto funcType = func -> GetType(); auto obj = new UserDataTestObject(); auto parameter = new UserDataValue(HashedString::ConstHash("testObject"), obj); auto result = script->CallFunction(u"testFunc", {parameter}); REQUIRE(result->EvaluateInteger() == 10); delete obj; delete parameter; delete script; delete func; delete result; UserDataStorage::RemoveType(HashedString::ConstHash("testObject")); } TEST_CASE( "Iterate over userdata vector values", "[integration]" ) { UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData()); Script* script = Script::Create(R"( function testFunc(testObject obj) local val = 0 for i, v in obj.fooVector do val = val + v end return val end )"); REQUIRE(!script->Diagnostics -> HasErrors()); script->Evaluate(); auto func = (GenericFunctionEvalValue*)script -> GetVariable(u"testFunc"); auto funcType = func -> GetType(); auto obj = new UserDataTestObject(); auto parameter = new UserDataValue(HashedString::ConstHash("testObject"), obj); auto result = script->CallFunction(u"testFunc", {parameter}); REQUIRE(result->EvaluateInteger() == 55); delete obj; delete parameter; delete script; delete func; delete result; UserDataStorage::RemoveType(HashedString::ConstHash("testObject")); } #endif