#ifdef TESTS_BUILD #include "../../extern/catch.hpp" #include "../../src/Battling/Pokemon/CreatePokemon.hpp" #include "../../src/ScriptResolving/AngelScript/AngelScripResolver.hpp" #include "../TestLibrary/TestLibrary.hpp" #define AS_CLASS(name, contents) \ { #name, "class " #name " : PkmnScript { " contents "}" } static std::unordered_map _scripts = std::unordered_map{ AS_CLASS(blankScript, ), AS_CLASS(stackScript, "int value = 0; void Stack() override { value++; } int GetValue() { return value; }"), AS_CLASS(onRemoveScript, "int value = 0; void OnRemove() override { value++; } int GetValue() { return value; }"), {"doubleInheritanceScript", R"( class doubleInheritanceScriptBase : PkmnScript { int value = 0; void Stack() override{ value++; } int GetValue(){ return value; } } class doubleInheritanceScript : doubleInheritanceScriptBase {} )"}, AS_CLASS(preventAttackScript, R"(void PreventAttack(ExecutingMove@ attack, bool& result) override{ result = !result; })"), AS_CLASS(stopBeforeAttackScript, R"( void StopBeforeAttack(ExecutingMove@ attack, bool& result) override{ result = !result; })"), AS_CLASS(OnBeforeAttackScript, "int value = 0; void OnBeforeAttack(ExecutingMove@ attack) override { value++; } " "int GetValue() { return value; }"), AS_CLASS( FailIncomingAttackScript, R"(void FailIncomingAttack(ExecutingMove@ attack, Pokemon@ target, bool& result) override{ result = !result; })"), AS_CLASS( IsInvulnerableScript, R"(void IsInvulnerable(ExecutingMove@ attack, Pokemon@ target, bool& result) override{ result = !result; })"), AS_CLASS(OnAttackMissScript, "int value = 0; void OnAttackMiss(ExecutingMove@ attack, Pokemon@ target) override { value++; } " "int GetValue() { return value; }"), AS_CLASS( ChangeAttackTypeScript, R"(void ChangeAttackType(ExecutingMove@ attack, Pokemon@ target, uint8 hit, uint8& outType) override{outType = 1; };)"), AS_CLASS( OnStatusMoveScript, "int value = 0; void OnStatusMove(ExecutingMove@ attack, Pokemon@ target, uint8 hit) override { value++; } " "int GetValue() { return value; }"), AS_CLASS( PreventSecondaryEffectsScript, R"(void PreventSecondaryEffects(ExecutingMove@ attack, Pokemon@ target, uint8 hit, bool& result) override{ result = !result; })"), AS_CLASS(OnSecondaryEffectScript, "int value = 0; void OnSecondaryEffect(ExecutingMove@ attack, Pokemon@ target, " "uint8 hit) override { value++; } " "int GetValue() { return value; }"), AS_CLASS(OnAfterHitsScript, "int value = 0; void OnAfterHits(ExecutingMove@ attack, Pokemon@ target) override { value++; } " "int GetValue() { return value; }"), }; static const char* _testLoadFunc(const char* name) { return _scripts[name]; } static AngelScripResolver* _resolverCache = nullptr; static AngelScripResolver* GetScriptResolver(PkmnLib::Battling::BattleLibrary* mainLib) { if (_resolverCache == nullptr) { _resolverCache = dynamic_cast(PkmnLib::Battling::BattleLibrary::CreateScriptResolver()); _resolverCache->Initialize(mainLib); _resolverCache->SetCreateFunction(&_testLoadFunc); for (auto kv : _scripts) { _resolverCache->CreateScript(kv.first); } _resolverCache->FinalizeModule(); } return _resolverCache; } static AngelScriptScript* GetScript(PkmnLib::Battling::BattleLibrary* mainLib, const char* scriptName) { auto lib = GetScriptResolver(mainLib); auto s = lib->LoadScript(AngelScripResolver::ScriptCategory::Creature, scriptName); auto script = dynamic_cast(s); return script; } TEST_CASE("Invoke non-implemented script function") { auto mainLib = TestLibrary::GetLibrary(); auto script = GetScript(mainLib, "blankScript"); script->Stack(); delete script; } TEST_CASE("Invoke Stack script function") { auto mainLib = TestLibrary::GetLibrary(); auto script = GetScript(mainLib, "stackScript"); for (int i = 1; i <= 10; i++) { script->Stack(); auto ctxPool = script->GetContextPool(); auto ctx = ctxPool->RequestContext(); script->PrepareMethod("GetValue", ctx); REQUIRE(ctx->Execute() == asEXECUTION_FINISHED); REQUIRE(ctx->GetReturnDWord() == i); ctxPool->ReturnContextToPool(ctx); } delete script; } TEST_CASE("Invoke OnRemove script function") { auto mainLib = TestLibrary::GetLibrary(); auto script = GetScript(mainLib, "onRemoveScript"); script->OnRemove(); auto ctxPool = script->GetContextPool(); auto ctx = ctxPool->RequestContext(); script->PrepareMethod("GetValue", ctx); REQUIRE(ctx->Execute() == asEXECUTION_FINISHED); REQUIRE(ctx->GetReturnDWord() == 1); ctxPool->ReturnContextToPool(ctx); delete script; } TEST_CASE("Invoke Stack script function with implementation in base class") { auto mainLib = TestLibrary::GetLibrary(); auto script = GetScript(mainLib, "doubleInheritanceScript"); for (int i = 1; i <= 10; i++) { script->Stack(); auto ctxPool = script->GetContextPool(); auto ctx = ctxPool->RequestContext(); script->PrepareMethod("GetValue", ctx); REQUIRE(ctx->Execute() == asEXECUTION_FINISHED); REQUIRE(ctx->GetReturnDWord() == i); ctxPool->ReturnContextToPool(ctx); } delete script; } TEST_CASE("Invoke preventAttackScript script function") { auto mainLib = TestLibrary::GetLibrary(); auto script = GetScript(mainLib, "preventAttackScript"); bool b = false; script->PreventAttack(nullptr, &b); REQUIRE(b); delete script; } TEST_CASE("Invoke StopBeforeAttack script function") { auto mainLib = TestLibrary::GetLibrary(); auto script = GetScript(mainLib, "stopBeforeAttackScript"); bool b = false; script->StopBeforeAttack(nullptr, &b); REQUIRE(b); delete script; } TEST_CASE("Invoke OnBeforeAttack script function") { auto mainLib = TestLibrary::GetLibrary(); auto script = GetScript(mainLib, "OnBeforeAttackScript"); script->OnBeforeAttack(nullptr); auto ctxPool = script->GetContextPool(); auto ctx = ctxPool->RequestContext(); script->PrepareMethod("GetValue", ctx); REQUIRE(ctx->Execute() == asEXECUTION_FINISHED); REQUIRE(ctx->GetReturnDWord() == 1); ctxPool->ReturnContextToPool(ctx); delete script; } TEST_CASE("Invoke FailIncomingAttack script function") { auto mainLib = TestLibrary::GetLibrary(); auto script = GetScript(mainLib, "FailIncomingAttackScript"); bool b = false; script->FailIncomingAttack(nullptr, nullptr, &b); REQUIRE(b); delete script; } TEST_CASE("Invoke OnAttackMiss script function") { auto mainLib = TestLibrary::GetLibrary(); auto script = GetScript(mainLib, "OnAttackMissScript"); script->OnAttackMiss(nullptr, nullptr); auto ctxPool = script->GetContextPool(); auto ctx = ctxPool->RequestContext(); script->PrepareMethod("GetValue", ctx); REQUIRE(ctx->Execute() == asEXECUTION_FINISHED); REQUIRE(ctx->GetReturnDWord() == 1); ctxPool->ReturnContextToPool(ctx); delete script; } TEST_CASE("Invoke ChangeAttackType script function") { auto mainLib = TestLibrary::GetLibrary(); auto script = GetScript(mainLib, "ChangeAttackTypeScript"); uint8_t b = 0; script->ChangeAttackType(nullptr, nullptr, 0, &b); REQUIRE(b == 1); delete script; } TEST_CASE("Invoke OnStatusMove script function") { auto mainLib = TestLibrary::GetLibrary(); auto script = GetScript(mainLib, "OnStatusMoveScript"); script->OnStatusMove(nullptr, nullptr, 0); auto ctxPool = script->GetContextPool(); auto ctx = ctxPool->RequestContext(); script->PrepareMethod("GetValue", ctx); REQUIRE(ctx->Execute() == asEXECUTION_FINISHED); REQUIRE(ctx->GetReturnDWord() == 1); ctxPool->ReturnContextToPool(ctx); delete script; } TEST_CASE("Invoke PreventSecondaryEffects script function") { auto mainLib = TestLibrary::GetLibrary(); auto script = GetScript(mainLib, "PreventSecondaryEffectsScript"); bool b = false; script->PreventSecondaryEffects(nullptr, nullptr, 0, &b); REQUIRE(b); delete script; } TEST_CASE("Invoke OnSecondaryEffect script function") { auto mainLib = TestLibrary::GetLibrary(); auto script = GetScript(mainLib, "OnSecondaryEffectScript"); script->OnSecondaryEffect(nullptr, nullptr, 0); auto ctxPool = script->GetContextPool(); auto ctx = ctxPool->RequestContext(); script->PrepareMethod("GetValue", ctx); REQUIRE(ctx->Execute() == asEXECUTION_FINISHED); REQUIRE(ctx->GetReturnDWord() == 1); ctxPool->ReturnContextToPool(ctx); delete script; } TEST_CASE("Invoke OnAfterHits script function") { auto mainLib = TestLibrary::GetLibrary(); auto script = GetScript(mainLib, "OnAfterHitsScript"); script->OnAfterHits(nullptr, nullptr); auto ctxPool = script->GetContextPool(); auto ctx = ctxPool->RequestContext(); script->PrepareMethod("GetValue", ctx); REQUIRE(ctx->Execute() == asEXECUTION_FINISHED); REQUIRE(ctx->GetReturnDWord() == 1); ctxPool->ReturnContextToPool(ctx); delete script; } #endif