mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
tests for the lua call error handling functions...
This commit is contained in:
parent
8f59cf2eee
commit
34af96214b
|
@ -120,22 +120,22 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
~handler() {
|
~handler() {
|
||||||
if (target.valid()) {
|
if (stack > 0) {
|
||||||
lua_remove(target.state(), stack);
|
lua_remove(target.state(), stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int luacodecall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount, const handler& h) const {
|
int luacodecall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount, handler& h) const {
|
||||||
return lua_pcallk(state(), static_cast<int>(argcount), static_cast<int>(resultcount), h.stack, 0, nullptr);
|
return lua_pcallk(state(), static_cast<int>(argcount), static_cast<int>(resultcount), h.stack, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount, const handler& h) const {
|
void luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount, handler& h) const {
|
||||||
lua_callk(state(), static_cast<int>(argcount), static_cast<int>(resultcount), 0, nullptr);
|
lua_callk(state(), static_cast<int>(argcount), static_cast<int>(resultcount), 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t... I, typename... Ret>
|
template<std::size_t... I, typename... Ret>
|
||||||
std::tuple<Ret...> invoke(indices<I...>, types<Ret...>, std::ptrdiff_t n, const handler& h) const {
|
std::tuple<Ret...> invoke(indices<I...>, types<Ret...>, std::ptrdiff_t n, handler& h) const {
|
||||||
luacall(n, sizeof...(Ret), h);
|
luacall(n, sizeof...(Ret), h);
|
||||||
const int nreturns = static_cast<int>(sizeof...(Ret));
|
const int nreturns = static_cast<int>(sizeof...(Ret));
|
||||||
const int stacksize = lua_gettop(state());
|
const int stacksize = lua_gettop(state());
|
||||||
|
@ -146,17 +146,18 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t I, typename Ret>
|
template<std::size_t I, typename Ret>
|
||||||
Ret invoke(indices<I>, types<Ret>, std::ptrdiff_t n, const handler& h) const {
|
Ret invoke(indices<I>, types<Ret>, std::ptrdiff_t n, handler& h) const {
|
||||||
luacall(n, 1, h);
|
luacall(n, 1, h);
|
||||||
return stack::pop<Ret>(state());
|
return stack::pop<Ret>(state());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t I>
|
template <std::size_t I>
|
||||||
void invoke(indices<I>, types<void>, std::ptrdiff_t n, const handler& h) const {
|
void invoke(indices<I>, types<void>, std::ptrdiff_t n, handler& h) const {
|
||||||
luacall(n, 0, h);
|
luacall(n, 0, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
function_result invoke(indices<>, types<>, std::ptrdiff_t n, const handler& h) const {
|
function_result invoke(indices<>, types<>, std::ptrdiff_t n, handler& h) const {
|
||||||
|
const bool handlerpushed = error_handler.valid();
|
||||||
const int stacksize = lua_gettop(state());
|
const int stacksize = lua_gettop(state());
|
||||||
const int firstreturn = std::max(0, stacksize - static_cast<int>(n) - 1);
|
const int firstreturn = std::max(0, stacksize - static_cast<int>(n) - 1);
|
||||||
int code = LUA_OK;
|
int code = LUA_OK;
|
||||||
|
@ -166,6 +167,7 @@ private:
|
||||||
// Handle C++ errors thrown from C++ functions bound inside of lua
|
// Handle C++ errors thrown from C++ functions bound inside of lua
|
||||||
catch (const std::exception& error) {
|
catch (const std::exception& error) {
|
||||||
code = LUA_ERRRUN;
|
code = LUA_ERRRUN;
|
||||||
|
h.stack = 0;
|
||||||
stack::push(state(), error.what());
|
stack::push(state(), error.what());
|
||||||
}
|
}
|
||||||
// TODO: handle idiots?
|
// TODO: handle idiots?
|
||||||
|
@ -186,7 +188,7 @@ private:
|
||||||
}
|
}
|
||||||
const int poststacksize = lua_gettop(state());
|
const int poststacksize = lua_gettop(state());
|
||||||
const int returncount = poststacksize - firstreturn;
|
const int returncount = poststacksize - firstreturn;
|
||||||
return function_result(state(), firstreturn + ( error_handler.valid() ? 0 : 1 ), returncount, static_cast<call_error>(code));
|
return function_result(state(), firstreturn + ( handlerpushed ? 0 : 1 ), returncount, static_cast<call_error>(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
49
tests.cpp
49
tests.cpp
|
@ -998,3 +998,52 @@ TEST_CASE("interop/null-to-nil-and-back", "nil should be the given type when a p
|
||||||
"rofl(x)\n"
|
"rofl(x)\n"
|
||||||
"assert(x == nil)"));
|
"assert(x == nil)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE( "functions/sol::function_result", "Function result should be the beefy return type for sol::function that allows for error checking and error handlers" ) {
|
||||||
|
sol::state lua;
|
||||||
|
lua.open_libraries( sol::lib::base, sol::lib::debug );
|
||||||
|
|
||||||
|
static const char errormessage1[] = "true error message";
|
||||||
|
static const char errormessage2[] = "doodle";
|
||||||
|
|
||||||
|
// Some function; just using a lambda to be cheap
|
||||||
|
auto doom = []() {
|
||||||
|
// Bypasses handler function: puts information directly into lua error
|
||||||
|
throw std::exception( errormessage1 );
|
||||||
|
};
|
||||||
|
auto luadoom = [&lua]() {
|
||||||
|
// Does not bypass error function, will call it
|
||||||
|
luaL_error( lua.lua_state(), "BIG ERROR MESSAGES!" );
|
||||||
|
};
|
||||||
|
auto specialhandler = []( std::string message ) {
|
||||||
|
return errormessage2;
|
||||||
|
};
|
||||||
|
|
||||||
|
lua.set_function( "doom", doom );
|
||||||
|
lua.set_function( "luadoom", luadoom );
|
||||||
|
lua.set_function( "cpphandler", specialhandler );
|
||||||
|
lua.script(
|
||||||
|
std::string( "function handler ( message )" )
|
||||||
|
+ " return '" + errormessage2 + "'"
|
||||||
|
+ "end"
|
||||||
|
);
|
||||||
|
|
||||||
|
sol::function func = lua[ "doom" ];
|
||||||
|
sol::function luafunc = lua[ "luadoom" ];
|
||||||
|
sol::function luahandler = lua[ "handler" ];
|
||||||
|
sol::function cpphandler = lua[ "cpphandler" ];
|
||||||
|
func.error_handler = luahandler;
|
||||||
|
luafunc.error_handler = cpphandler;
|
||||||
|
|
||||||
|
sol::function_result result1 = func();
|
||||||
|
int test = lua_gettop(lua.lua_state());
|
||||||
|
REQUIRE(!result1.valid());
|
||||||
|
std::string errorstring = result1;
|
||||||
|
REQUIRE(errorstring == errormessage1);
|
||||||
|
|
||||||
|
sol::function_result result2 = luafunc();
|
||||||
|
REQUIRE(!result2.valid());
|
||||||
|
errorstring = result2;
|
||||||
|
REQUIRE(errorstring == errormessage2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user