// https://github.com/vinniefalco/LuaBridge // // Copyright 2019, Dmitry Tarakanov // Copyright 2012, Vinnie Falco // Copyright 2007, Nathan Reed // SPDX-License-Identifier: MIT #pragma once #include "Lua/LuaLibrary.h" #include "LuaBridge/LuaBridge.h" #include #include // traceback function, adapted from lua.c // when a runtime error occurs, this will append the call stack to the error message // inline int traceback (lua_State* L) { // look up Lua's 'debug.traceback' function lua_getglobal (L, "debug"); if (!lua_istable (L, -1)) { lua_pop (L, 1); return 1; } lua_getfield (L, -1, "traceback"); if (!lua_isfunction (L, -1)) { lua_pop (L, 2); return 1; } lua_pushvalue (L, 1); /* pass error message */ lua_pushinteger (L, 2); /* skip this function and traceback */ lua_call (L, 2, 1); /* call debug.traceback */ return 1; } /// Base test class. Introduces the global 'result' variable, /// used for checking of C++ - Lua interoperation. /// struct TestBase : public ::testing::Test { lua_State* L = nullptr; void SetUp () override { L = nullptr; L = luaL_newstate (); luaL_openlibs (L); lua_pushcfunction (L, &traceback); } void TearDown () override { if (L != nullptr) { lua_close (L); } } void runLua (const std::string& script) const { if (luaL_loadstring (L, script.c_str ()) != 0) { throw std::runtime_error (lua_tostring (L, -1)); } if (lua_pcall (L, 0, 0, -2) != 0) { throw std::runtime_error (lua_tostring (L, -1)); } } template T result () const { return luabridge::getGlobal (L, "result").cast (); } void resetResult () const { luabridge::setGlobal (L, luabridge::LuaRef (L), "result"); } void printStack () const { std::cerr << "===== Stack =====\n"; for (int i = 1; i <= lua_gettop (L); ++i) { std::cerr << "@" << i << " = " << luabridge::LuaRef::fromStack (L, i) << "\n"; } } };