committed by
Jérôme Leclercq
parent
7c1ffea19c
commit
dfd28160a0
187
tests/Engine/Lua/LuaState.cpp
Normal file
187
tests/Engine/Lua/LuaState.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
#include <Nazara/Lua/LuaInstance.hpp>
|
||||
#include <Catch/catch.hpp>
|
||||
|
||||
static int counter(lua_State* L)
|
||||
{
|
||||
Nz::LuaInstance& luaInstance = Nz::LuaInstance::GetInstance(L);
|
||||
double val = luaInstance.ToNumber(luaInstance.GetIndexOfUpValue(1));
|
||||
luaInstance.PushNumber(++val);
|
||||
luaInstance.PushValue(-1);
|
||||
luaInstance.Replace(luaInstance.GetIndexOfUpValue(1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct TestLuaState
|
||||
{
|
||||
int a = 3;
|
||||
float b = 5.f;
|
||||
};
|
||||
|
||||
struct TestMetaTable
|
||||
{
|
||||
float x = 1.f;
|
||||
float y = 2.f;
|
||||
};
|
||||
|
||||
inline int LuaImplReplyVal(const Nz::LuaState& state, TestLuaState&& val, Nz::TypeTag<TestLuaState>)
|
||||
{
|
||||
state.PushTable();
|
||||
state.PushField("a", val.a);
|
||||
state.PushField("b", val.b);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline unsigned int LuaImplQueryArg(const Nz::LuaState& state, int index, TestLuaState* arg, Nz::TypeTag<TestLuaState>)
|
||||
{
|
||||
state.CheckType(index, Nz::LuaType_Table);
|
||||
|
||||
arg->a = state.CheckField<int>("a", index);
|
||||
arg->b = state.CheckField<float>("b", index);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
SCENARIO("LuaState", "[LUA][LUASTATE]")
|
||||
{
|
||||
GIVEN("One lua instance")
|
||||
{
|
||||
Nz::LuaInstance luaInstance;
|
||||
luaInstance.LoadLibraries(Nz::LuaLib_Math);
|
||||
|
||||
WHEN("We push different primitive types")
|
||||
{
|
||||
bool booleanValue = true;
|
||||
long long integerValue = 5LL;
|
||||
double doubleValue = -55.0;
|
||||
const char* stringValue = "test";
|
||||
Nz::String nazaraValue = "Nazara";
|
||||
luaInstance.PushBoolean(booleanValue);
|
||||
luaInstance.PushInteger(integerValue);
|
||||
luaInstance.PushNil();
|
||||
luaInstance.PushNumber(doubleValue);
|
||||
luaInstance.PushString(stringValue);
|
||||
luaInstance.PushString(nazaraValue);
|
||||
|
||||
THEN("We should be able to retrieve them")
|
||||
{
|
||||
CHECK(luaInstance.CheckBoolean(1) == booleanValue);
|
||||
CHECK(luaInstance.CheckInteger(2) == integerValue);
|
||||
bool succeeded = false;
|
||||
CHECK(luaInstance.ToInteger(2, &succeeded) == integerValue);
|
||||
CHECK(succeeded);
|
||||
CHECK(luaInstance.ToPointer(3) == nullptr);
|
||||
CHECK(luaInstance.CheckNumber(4) == Approx(doubleValue));
|
||||
succeeded = false;
|
||||
CHECK(luaInstance.ToNumber(4, &succeeded) == Approx(doubleValue));
|
||||
CHECK(succeeded);
|
||||
CHECK(luaInstance.CheckString(5) == std::string(stringValue));
|
||||
CHECK(luaInstance.CheckString(6) == nazaraValue);
|
||||
std::size_t length = 0;
|
||||
CHECK(luaInstance.ToString(6, &length) == nazaraValue);
|
||||
CHECK(length == nazaraValue.GetSize());
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We use basic operations")
|
||||
{
|
||||
luaInstance.PushInteger(1);
|
||||
luaInstance.PushInteger(2);
|
||||
|
||||
THEN("We should behave normally")
|
||||
{
|
||||
CHECK(luaInstance.Compare(1, 2, Nz::LuaComparison_Less));
|
||||
luaInstance.Compute(Nz::LuaOperation_Substraction);
|
||||
CHECK(luaInstance.ToInteger(1) == -1);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We manipulate the stack")
|
||||
{
|
||||
Nz::String stringValue = "hello";
|
||||
luaInstance.PushBoolean(true);
|
||||
luaInstance.PushNumber(10.0);
|
||||
luaInstance.PushNil();
|
||||
luaInstance.PushString(stringValue);
|
||||
/* true 10.0 nil hello */
|
||||
|
||||
THEN("These effects are expected")
|
||||
{
|
||||
luaInstance.PushValue(-4);
|
||||
/* true 10.0 nil hello true */
|
||||
CHECK(luaInstance.CheckBoolean(5));
|
||||
|
||||
luaInstance.Replace(3);
|
||||
/* true 10.0 true hello */
|
||||
CHECK(luaInstance.CheckBoolean(3));
|
||||
|
||||
luaInstance.Remove(-2);
|
||||
/* true 10.0 hello */
|
||||
CHECK(luaInstance.CheckString(3) == stringValue);
|
||||
|
||||
luaInstance.Pop(2);
|
||||
/* true */
|
||||
CHECK_FALSE(luaInstance.IsValid(2));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We try the CFunction")
|
||||
{
|
||||
double counterValue = 55.0;
|
||||
luaInstance.PushFunction([=](Nz::LuaState& s) -> int {
|
||||
s.PushNumber(counterValue);
|
||||
s.PushCFunction(&counter, 1);
|
||||
return 1;
|
||||
});
|
||||
|
||||
THEN("We can call them")
|
||||
{
|
||||
luaInstance.Call(0); // We call our counter creator
|
||||
luaInstance.Call(0); // We call our counter, which increments the value
|
||||
CHECK(luaInstance.ToNumber(0) == Approx(counterValue + 1.0));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We push our user type locally")
|
||||
{
|
||||
luaInstance.Push(TestLuaState());
|
||||
|
||||
THEN("We can retrieve it")
|
||||
{
|
||||
int index = 1;
|
||||
TestLuaState popped = luaInstance.Check<TestLuaState>(&index);
|
||||
CHECK(popped.a == 3);
|
||||
CHECK(popped.b == Approx(5.0));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We push our user type globally")
|
||||
{
|
||||
luaInstance.PushGlobal("TestLuaState", TestLuaState());
|
||||
|
||||
THEN("We can retrieve it")
|
||||
{
|
||||
TestLuaState popped = luaInstance.CheckGlobal<TestLuaState>("TestLuaState");
|
||||
CHECK(popped.a == 3);
|
||||
CHECK(popped.b == Approx(5.0));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We define a lua function")
|
||||
{
|
||||
luaInstance.Execute(R"(
|
||||
function f (x, y)
|
||||
return (x^2 * math.sin(y))/(1 - x)
|
||||
end
|
||||
)");
|
||||
|
||||
THEN("We can call it from the code")
|
||||
{
|
||||
REQUIRE(luaInstance.GetGlobal("f") == Nz::LuaType_Function);
|
||||
luaInstance.Push(3.0, 2.0);
|
||||
luaInstance.Call(2, 1);
|
||||
CHECK(luaInstance.ToNumber(1) == Approx(-4.09).margin(0.1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user