Initial work on also doing battle stuff in tests.
This commit is contained in:
parent
3488339d51
commit
c821e6f53b
|
@ -1 +1 @@
|
|||
Subproject commit 069eadf7c9f94ca4b8616dca8eb7562c9ecf26e0
|
||||
Subproject commit 9b27ad72f18d4924d0851a523b64fbff0c779620
|
|
@ -0,0 +1,3 @@
|
|||
#include "Globals.hpp"
|
||||
|
||||
ArbUt::OptionalUniquePtr<const PkmnLib::Battling::BattleLibrary> Globals::Library = nullptr;
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef POKEMONSCRIPTTESTER_GLOBALS_HPP
|
||||
#define POKEMONSCRIPTTESTER_GLOBALS_HPP
|
||||
#include <PkmnLib/Battling/Library/BattleLibrary.hpp>
|
||||
|
||||
class Globals {
|
||||
public:
|
||||
static ArbUt::OptionalUniquePtr<const PkmnLib::Battling::BattleLibrary> Library;
|
||||
};
|
||||
|
||||
#endif // POKEMONSCRIPTTESTER_GLOBALS_HPP
|
|
@ -0,0 +1,52 @@
|
|||
#ifndef POKEMONSCRIPTTESTER_BATTLEBUILDER_HPP
|
||||
#define POKEMONSCRIPTTESTER_BATTLEBUILDER_HPP
|
||||
|
||||
#include <PkmnLib/Battling/Battle/Battle.hpp>
|
||||
#include <PkmnLib/Battling/Pokemon/CreatePokemon.hpp>
|
||||
#include <angelscript.h>
|
||||
#include "../TestEnvironment.hpp"
|
||||
|
||||
class BattleBuilder {
|
||||
static PkmnLib::Battling::Battle* CreateSimpleBattle(u32 seed, const ArbUt::StringView& species1,
|
||||
const ArbUt::StringView& species2, u8 level) {
|
||||
auto* ctx = asGetActiveContext();
|
||||
TestEnvironment* env = static_cast<TestEnvironment*>(ctx->GetUserData());
|
||||
auto lib = Globals::Library.GetValue();
|
||||
|
||||
auto mon1 = PkmnLib::Battling::CreatePokemon(lib, species1, level).Build();
|
||||
auto p1 = new CreatureLib::Battling::CreatureParty(1);
|
||||
p1->SwapInto(0, mon1);
|
||||
|
||||
auto mon2 = PkmnLib::Battling::CreatePokemon(lib, species2, level).Build();
|
||||
auto p2 = new CreatureLib::Battling::CreatureParty(1);
|
||||
p1->SwapInto(0, mon2);
|
||||
|
||||
auto battle = new PkmnLib::Battling::Battle(
|
||||
lib,
|
||||
{new CreatureLib::Battling::BattleParty(p1, {CreatureLib::Battling::CreatureIndex(0, 0)}),
|
||||
new CreatureLib::Battling::BattleParty(p2, {CreatureLib::Battling::CreatureIndex(1, 0)})},
|
||||
true, // can flee
|
||||
2, // 2 sides
|
||||
1, // 1 mon per side
|
||||
seed // with seed
|
||||
);
|
||||
battle->SwitchCreature(0, 0, mon1);
|
||||
battle->SwitchCreature(1, 0, mon2);
|
||||
|
||||
env->AddGarbage(battle);
|
||||
env->AddGarbage(p1);
|
||||
env->AddGarbage(p2);
|
||||
|
||||
return battle;
|
||||
}
|
||||
|
||||
public:
|
||||
static void Register(AngelScriptResolver* scriptResolver) {
|
||||
auto engine = scriptResolver->GetBuilder().GetEngine();
|
||||
Ensure(engine->RegisterGlobalFunction("Battle@ CreateSimpleBattle(uint seed, const constString&in species1, "
|
||||
"const constString&in species2, uint8 level)",
|
||||
asFUNCTION(CreateSimpleBattle), asCALL_CDECL) >= 0);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // POKEMONSCRIPTTESTER_BATTLEBUILDER_HPP
|
|
@ -2,32 +2,32 @@
|
|||
#define POKEMONSCRIPTTESTER_TESTFUNCTIONS_HPP
|
||||
|
||||
#include <angelscript.h>
|
||||
#include "AssertionFailed.hpp"
|
||||
#include "TestEnvironment.hpp"
|
||||
#include "../RequirementFailed.hpp"
|
||||
#include "../TestEnvironment.hpp"
|
||||
|
||||
class TestFunctions {
|
||||
private:
|
||||
struct AssertionData {
|
||||
struct RequirementData {
|
||||
std::string FileName;
|
||||
size_t Line;
|
||||
};
|
||||
|
||||
static AssertionData GetAssertionData() {
|
||||
static RequirementData GetRequirementData() {
|
||||
auto* ctx = asGetActiveContext();
|
||||
TestEnvironment* env = static_cast<TestEnvironment*>(ctx->GetUserData());
|
||||
env->AssertionCount += 1;
|
||||
auto filename = ctx->GetFunction()->GetScriptSectionName();
|
||||
auto line = ctx->GetLineNumber();
|
||||
return AssertionData{
|
||||
return RequirementData{
|
||||
.FileName = filename,
|
||||
.Line = (size_t)line,
|
||||
};
|
||||
}
|
||||
|
||||
static bool Assert(bool value) {
|
||||
static bool Require(bool value) {
|
||||
if (!value) {
|
||||
auto data = GetAssertionData();
|
||||
throw AssertionFailed(data.FileName, data.Line);
|
||||
auto data = GetRequirementData();
|
||||
throw RequirementFailed(data.FileName, data.Line);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -40,25 +40,25 @@ private:
|
|||
eqMsg = ss.str(); \
|
||||
}
|
||||
|
||||
static bool AssertEqualsI32(i32 expected, i32 actual) {
|
||||
static bool RequireEqualsI32(i32 expected, i32 actual) {
|
||||
if (expected != actual) {
|
||||
auto data = GetAssertionData();
|
||||
auto data = GetRequirementData();
|
||||
GetEqualityMessage(expected, actual);
|
||||
throw AssertionFailed(data.FileName, data.Line, eqMsg);
|
||||
throw RequirementFailed(data.FileName, data.Line, eqMsg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool AssertEqualsString(const std::string& expected, const std::string& actual) {
|
||||
static bool RequireEqualsString(const std::string& expected, const std::string& actual) {
|
||||
if (expected != actual) {
|
||||
auto data = GetAssertionData();
|
||||
auto data = GetRequirementData();
|
||||
std::string eqMsg;
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Expected: '" << expected << "', but was: '" << actual << "'";
|
||||
eqMsg = ss.str();
|
||||
}
|
||||
throw AssertionFailed(data.FileName, data.Line, eqMsg);
|
||||
throw RequirementFailed(data.FileName, data.Line, eqMsg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -66,11 +66,11 @@ private:
|
|||
public:
|
||||
static void Register(AngelScriptResolver* scriptResolver) {
|
||||
auto engine = scriptResolver->GetBuilder().GetEngine();
|
||||
Ensure(engine->RegisterGlobalFunction("bool Assert(bool expression)", asFUNCTION(Assert), asCALL_CDECL) >= 0);
|
||||
Ensure(engine->RegisterGlobalFunction("bool AssertEquals(int expected, int actual)",
|
||||
asFUNCTION(AssertEqualsI32), asCALL_CDECL) >= 0);
|
||||
Ensure(engine->RegisterGlobalFunction("bool AssertEquals(const string &in expected, const string &in actual)",
|
||||
asFUNCTION(AssertEqualsString), asCALL_CDECL) >= 0);
|
||||
Ensure(engine->RegisterGlobalFunction("bool Require(bool expression)", asFUNCTION(Require), asCALL_CDECL) >= 0);
|
||||
Ensure(engine->RegisterGlobalFunction("bool RequireEquals(int expected, int actual)",
|
||||
asFUNCTION(RequireEqualsI32), asCALL_CDECL) >= 0);
|
||||
Ensure(engine->RegisterGlobalFunction("bool RequireEquals(const string &in expected, const string &in actual)",
|
||||
asFUNCTION(RequireEqualsString), asCALL_CDECL) >= 0);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
#ifndef POKEMONSCRIPTTESTER_ASSERTIONFAILED_HPP
|
||||
#define POKEMONSCRIPTTESTER_ASSERTIONFAILED_HPP
|
||||
#ifndef POKEMONSCRIPTTESTER_REQUIREMENTFAILED_HPP
|
||||
#define POKEMONSCRIPTTESTER_REQUIREMENTFAILED_HPP
|
||||
#include <exception>
|
||||
#include <sstream>
|
||||
|
||||
class AssertionFailed : public std::exception {
|
||||
class RequirementFailed : public std::exception {
|
||||
static inline std::string& ltrim(std::string& s, const char* t = " \t\n\r\f\v") {
|
||||
s.erase(0, s.find_first_not_of(t));
|
||||
return s;
|
||||
|
@ -26,10 +26,10 @@ class AssertionFailed : public std::exception {
|
|||
char* _msg;
|
||||
|
||||
public:
|
||||
AssertionFailed(const std::string& path, size_t line, const std::string& message = "") {
|
||||
RequirementFailed(const std::string& path, size_t line, const std::string& message = "") {
|
||||
auto l = GetLine(path, line);
|
||||
std::stringstream ss;
|
||||
ss << "Assertion failed at: " << path << ":" << line << std::endl;
|
||||
ss << "Requirement failed at: " << path << ":" << line << std::endl;
|
||||
ss << l;
|
||||
if (message.length() > 0) {
|
||||
ss << std::endl << message;
|
||||
|
@ -40,9 +40,9 @@ public:
|
|||
_msg[str.length()] = 0;
|
||||
}
|
||||
|
||||
~AssertionFailed() { delete[] _msg; }
|
||||
~RequirementFailed() { delete[] _msg; }
|
||||
|
||||
const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW override { return _msg; }
|
||||
};
|
||||
|
||||
#endif // POKEMONSCRIPTTESTER_ASSERTIONFAILED_HPP
|
||||
#endif // POKEMONSCRIPTTESTER_REQUIREMENTFAILED_HPP
|
|
@ -15,6 +15,7 @@ public:
|
|||
ctx->Prepare(_function);
|
||||
ctx->SetUserData(_env.get());
|
||||
auto e = ctx->Execute();
|
||||
_env->CollectGarbage();
|
||||
if (e == asEXECUTION_EXCEPTION) {
|
||||
_errorMessage = ctx->GetExceptionString();
|
||||
_result = TestResult::Failed;
|
||||
|
|
|
@ -3,6 +3,28 @@
|
|||
|
||||
struct TestEnvironment {
|
||||
size_t AssertionCount = 0;
|
||||
|
||||
template <typename T> void AddGarbage(T* data) { _garbage.Append(GarbageObject(data)); }
|
||||
|
||||
void CollectGarbage() {
|
||||
for (auto& o : _garbage) {
|
||||
o.Destructor(o.Ptr);
|
||||
}
|
||||
_garbage.Clear();
|
||||
}
|
||||
|
||||
private:
|
||||
struct GarbageObject {
|
||||
void* Ptr;
|
||||
std::function<void(void* ptr)> Destructor;
|
||||
|
||||
template <typename T> GarbageObject(T* ptr) {
|
||||
Ptr = ptr;
|
||||
Destructor = [](void* v) { delete static_cast<T*>(v); };
|
||||
}
|
||||
};
|
||||
|
||||
ArbUt::List<GarbageObject> _garbage;
|
||||
};
|
||||
|
||||
#endif // POKEMONSCRIPTTESTER_TESTENVIRONMENT_HPP
|
||||
|
|
11
src/main.cpp
11
src/main.cpp
|
@ -3,7 +3,9 @@
|
|||
#include <iostream>
|
||||
#include "../extern/args.hpp"
|
||||
#include "BuildData/BuildLibrary.hpp"
|
||||
#include "Tester/TestFunctions.hpp"
|
||||
#include "Globals.hpp"
|
||||
#include "Tester/AngelScript/BattleBuilder.hpp"
|
||||
#include "Tester/AngelScript/TestFunctions.hpp"
|
||||
#include "Tester/TestRunner.hpp"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
@ -41,13 +43,14 @@ int main(int argc, char** argv) {
|
|||
auto* scriptResolver = dynamic_cast<AngelScriptResolver*>(resolver);
|
||||
scriptResolver->DefineWord("TEST");
|
||||
TestFunctions::Register(scriptResolver);
|
||||
BattleBuilder::Register(scriptResolver);
|
||||
};
|
||||
|
||||
auto battleLib = ArbUt::OptionalScopedPtr(BuildLibrary::Build("", initialize));
|
||||
if (!battleLib.HasValue()) {
|
||||
Globals::Library = BuildLibrary::Build("", initialize);
|
||||
if (!Globals::Library.HasValue()) {
|
||||
return 1;
|
||||
}
|
||||
auto* scriptResolver = dynamic_cast<AngelScriptResolver*>(battleLib.GetValue()->GetScriptResolver().get());
|
||||
auto* scriptResolver = dynamic_cast<AngelScriptResolver*>(Globals::Library.GetValue()->GetScriptResolver().get());
|
||||
auto testRunner = TestRunner(scriptResolver);
|
||||
auto* engine = scriptResolver->GetBuilder().GetEngine();
|
||||
return testRunner.RunAll(engine);
|
||||
|
|
Loading…
Reference in New Issue