Files
EVEngine/test/binding_selfcheck.cpp
T

59 lines
2.3 KiB
C++

#include "zeroerr/assert.h"
#include "zeroerr/unittest.h"
#include "ScriptTest.h"
// Runtime binding self-check (companion to scripts/check_bindings.py): builds
// a bare script VM with every registered module exposed, then verifies curated
// "hot" bindings on light modules actually exist. Constructing a module class
// is a real smoke: it exercises ModuleManager::create + expose. (eve.reflect is
// covered by test/ReflectScript.cpp, which uses the full Runtime.)
TEST_CASE("binding.selfcheck.scriptSurface") {
ScriptTest t(R"(
local missing = [];
// Light modules: constructor must succeed and hot bindings must exist.
local hot = {
Math = ["newVec2", "newMat4", "setRandomSeed"],
DataModule = ["newByteData", "decodeJson", "encodeJson"],
PlatformEvent = ["pump", "poll", "pushData"],
Timer = ["getTime", "step"],
Rx = ["newSubject"],
Spatial = ["newQuadTree", "newOctree"],
IK = ["newSkeleton2D", "newSolver2D"],
RPG = ["newActor"],
Inventory = ["newBag"],
Climbing = ["newRuntime", "newAnchorGraphJson"],
};
foreach (cls, methods in hot) {
// Module classes are installed lazily through eve's _get delegate.
// Squirrel's `in` operator only checks existing slots and therefore
// bypasses the resolver that this smoke test is meant to exercise.
local ctor = null;
try {
ctor = eve[cls];
} catch (e) {
missing.push(cls + ":ctor-missing");
continue;
}
if (ctor == null) { missing.push(cls + ":ctor-null"); continue; }
local inst = null;
try {
inst = ctor();
} catch (e) {
missing.push(cls + ":ctor:" + e);
continue;
}
if (inst == null) { missing.push(cls + ":ctor-null"); continue; }
foreach (fn in methods) if (!(fn in inst)) missing.push(cls + "." + fn);
}
local msg = "";
for (local i = 0; i < missing.len(); i++) {
if (i > 0) msg += ",";
msg += missing[i];
}
if (missing.len() > 0) throw "binding self-check failed: " + msg;
)");
}