feat(plugins): add debug.traceback (#6652)
Reviewed-by: Mm2PL <mm2pl+gh@kotmisia.pl>
This commit is contained in:
+82
-22
@@ -157,6 +157,24 @@ std::string luaTestPath(const QString &category, const QString &entry)
|
||||
return luaTestBaseDir(category).filePath(entry + ".lua").toStdString();
|
||||
}
|
||||
|
||||
bool runLuaTest(const QString &category, const QString &entry,
|
||||
sol::state_view lua)
|
||||
{
|
||||
auto loadResult = lua.load_file(luaTestPath(category, entry));
|
||||
auto pfn = loadResult.get<sol::protected_function>();
|
||||
pfn.set_error_handler(lua["debug"]["traceback"]);
|
||||
auto pfr = pfn.call();
|
||||
EXPECT_TRUE(pfr.valid());
|
||||
if (!pfr.valid())
|
||||
{
|
||||
qDebug().noquote() << "Test" << entry << "failed:";
|
||||
sol::error err = pfr;
|
||||
qDebug().noquote() << err.what();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace chatterino {
|
||||
@@ -1528,23 +1546,15 @@ TEST_P(PluginJsonTest, Run)
|
||||
auto reg = lua->registry().size();
|
||||
auto globals = lua->globals().size();
|
||||
|
||||
auto pfr = lua->safe_script_file(luaTestPath("json", GetParam()));
|
||||
EXPECT_TRUE(pfr.valid());
|
||||
if (!pfr.valid())
|
||||
{
|
||||
qDebug() << "Test" << GetParam() << "failed:";
|
||||
sol::error err = pfr;
|
||||
qDebug() << err.what();
|
||||
return;
|
||||
}
|
||||
runLuaTest("json", GetParam(), *this->lua);
|
||||
|
||||
for (size_t i = 0; i < 5; i++)
|
||||
{
|
||||
lua->collect_garbage();
|
||||
}
|
||||
// make sure we don't leak anything to globals or the registry
|
||||
// but give the registry some room of 1 slot
|
||||
EXPECT_LE(lua->registry().size(), reg + 1);
|
||||
// but give the registry some room of 3 slots (two from getting the debug library)
|
||||
EXPECT_LE(lua->registry().size(), reg + 3);
|
||||
EXPECT_EQ(lua->globals().size(), globals);
|
||||
}
|
||||
|
||||
@@ -1557,17 +1567,8 @@ class PluginMessageTest : public PluginTest,
|
||||
};
|
||||
TEST_P(PluginMessageTest, Run)
|
||||
{
|
||||
configure();
|
||||
|
||||
auto pfr = lua->safe_script_file(luaTestPath("message", GetParam()));
|
||||
EXPECT_TRUE(pfr.valid());
|
||||
if (!pfr.valid())
|
||||
{
|
||||
qDebug() << "Test" << GetParam() << "failed:";
|
||||
sol::error err = pfr;
|
||||
qDebug() << err.what();
|
||||
return;
|
||||
}
|
||||
this->configure();
|
||||
runLuaTest("message", GetParam(), *this->lua);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(PluginMessage, PluginMessageTest,
|
||||
@@ -1593,4 +1594,63 @@ TEST_F(PluginTest, testAccounts)
|
||||
ASSERT_TRUE(res.valid()) << res.get<sol::error>().what();
|
||||
}
|
||||
|
||||
TEST_F(PluginTest, debugTraceback)
|
||||
{
|
||||
configure();
|
||||
|
||||
QString traceback = lua->script(R"lua(
|
||||
local function other()
|
||||
error("oh no")
|
||||
end
|
||||
local function main()
|
||||
local function inner()
|
||||
other()
|
||||
end
|
||||
inner()
|
||||
end
|
||||
|
||||
local ok, res = xpcall(main, debug.traceback)
|
||||
return res
|
||||
)lua")
|
||||
.get<QString>();
|
||||
ASSERT_TRUE(traceback.contains("[C]: in function 'error'"));
|
||||
ASSERT_TRUE(traceback.contains("[string \"...\"]:3: in upvalue 'other'"));
|
||||
ASSERT_TRUE(traceback.contains("[string \"...\"]:7: in local 'inner'"));
|
||||
ASSERT_TRUE(traceback.contains(
|
||||
"[string \"...\"]:9: in function <[string \"...\"]:5>"));
|
||||
ASSERT_TRUE(traceback.contains("[C]: in function 'xpcall'"));
|
||||
ASSERT_TRUE(traceback.contains("[string \"...\"]:12: in main chunk"));
|
||||
|
||||
traceback = lua->script(R"lua(
|
||||
return debug.traceback()
|
||||
)lua")
|
||||
.get<QString>();
|
||||
ASSERT_TRUE(traceback.contains("[string \"...\"]:2: in main chunk"));
|
||||
|
||||
traceback = lua->script(R"lua(
|
||||
return debug.traceback("my message")
|
||||
)lua")
|
||||
.get<QString>();
|
||||
ASSERT_TRUE(traceback.contains("my message"));
|
||||
ASSERT_TRUE(traceback.contains("[string \"...\"]:2: in main chunk"));
|
||||
|
||||
traceback = lua->script(R"lua(
|
||||
local coro = coroutine.create(function ()
|
||||
coroutine.yield()
|
||||
end)
|
||||
coroutine.resume(coro)
|
||||
return debug.traceback(coro)
|
||||
)lua")
|
||||
.get<QString>();
|
||||
ASSERT_TRUE(traceback.contains("[C]: in function 'coroutine.yield'"));
|
||||
ASSERT_TRUE(traceback.contains(
|
||||
"[string \"...\"]:3: in function <[string \"...\"]:2>"));
|
||||
|
||||
auto msg = lua->script(R"lua(
|
||||
return debug.traceback(c2.Message.new({id = "who would do this"}))
|
||||
)lua")
|
||||
.get<std::shared_ptr<Message>>();
|
||||
ASSERT_EQ(msg->id, "who would do this");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user