mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-21 09:39:56 +00:00
Fix the tests
This commit is contained in:
parent
c9783344a0
commit
4529af9b7f
@ -13,12 +13,14 @@ namespace
|
||||
{
|
||||
void SetUp() override
|
||||
{
|
||||
mLua.sol()["callback"] = [&](sol::protected_function fn) -> LuaUtil::Callback {
|
||||
sol::table hiddenData(mLua.sol(), sol::create);
|
||||
hiddenData[LuaUtil::ScriptsContainer::sScriptIdKey] = LuaUtil::ScriptId{};
|
||||
return LuaUtil::Callback{ std::move(fn), hiddenData };
|
||||
};
|
||||
mLua.sol()["pass"] = [this](LuaUtil::Callback callback) { mCb = callback; };
|
||||
mLua.protectedCall([&](LuaUtil::LuaView& view) {
|
||||
view.sol()["callback"] = [&](sol::protected_function fn) -> LuaUtil::Callback {
|
||||
sol::table hiddenData(view.sol(), sol::create);
|
||||
hiddenData[LuaUtil::ScriptsContainer::sScriptIdKey] = LuaUtil::ScriptId{};
|
||||
return LuaUtil::Callback{ std::move(fn), hiddenData };
|
||||
};
|
||||
view.sol()["pass"] = [&](LuaUtil::Callback callback) { mCb = callback; };
|
||||
});
|
||||
}
|
||||
|
||||
LuaUtil::LuaState mLua{ nullptr, nullptr };
|
||||
@ -28,25 +30,29 @@ namespace
|
||||
TEST_F(LuaCoroutineCallbackTest, CoroutineCallbacks)
|
||||
{
|
||||
internal::CaptureStdout();
|
||||
mLua.sol().safe_script(R"X(
|
||||
mLua.protectedCall([&](LuaUtil::LuaView& view) {
|
||||
view.sol().safe_script(R"X(
|
||||
local s = 'test'
|
||||
coroutine.wrap(function()
|
||||
pass(callback(function(v) print(s) end))
|
||||
end)()
|
||||
)X");
|
||||
mLua.sol().collect_garbage();
|
||||
mCb.call();
|
||||
view.sol().collect_garbage();
|
||||
mCb.call();
|
||||
});
|
||||
EXPECT_THAT(internal::GetCapturedStdout(), "test\n");
|
||||
}
|
||||
|
||||
TEST_F(LuaCoroutineCallbackTest, ErrorInCoroutineCallbacks)
|
||||
{
|
||||
mLua.sol().safe_script(R"X(
|
||||
mLua.protectedCall([&](LuaUtil::LuaView& view) {
|
||||
view.sol().safe_script(R"X(
|
||||
coroutine.wrap(function()
|
||||
pass(callback(function() error('COROUTINE CALLBACK') end))
|
||||
end)()
|
||||
)X");
|
||||
mLua.sol().collect_garbage();
|
||||
view.sol().collect_garbage();
|
||||
});
|
||||
EXPECT_ERROR(mCb.call(), "COROUTINE CALLBACK");
|
||||
}
|
||||
}
|
||||
|
@ -81,84 +81,87 @@ you_have_arrows: "Arrows count: {count}"
|
||||
TEST_F(LuaL10nTest, L10n)
|
||||
{
|
||||
LuaUtil::LuaState lua{ mVFS.get(), &mCfg };
|
||||
sol::state_view& l = lua.sol();
|
||||
internal::CaptureStdout();
|
||||
l10n::Manager l10nManager(mVFS.get());
|
||||
l10nManager.setPreferredLocales({ "de", "en" });
|
||||
EXPECT_THAT(internal::GetCapturedStdout(), "Preferred locales: gmst de en\n");
|
||||
lua.protectedCall([&](LuaUtil::LuaView& view) {
|
||||
sol::state_view& l = view.sol();
|
||||
internal::CaptureStdout();
|
||||
l10n::Manager l10nManager(mVFS.get());
|
||||
l10nManager.setPreferredLocales({ "de", "en" });
|
||||
EXPECT_THAT(internal::GetCapturedStdout(), "Preferred locales: gmst de en\n");
|
||||
|
||||
l["l10n"] = LuaUtil::initL10nLoader(l, &l10nManager);
|
||||
l["l10n"] = LuaUtil::initL10nLoader(l, &l10nManager);
|
||||
|
||||
internal::CaptureStdout();
|
||||
l.safe_script("t1 = l10n('Test1')");
|
||||
EXPECT_THAT(internal::GetCapturedStdout(),
|
||||
"Language file \"l10n/Test1/de.yaml\" is enabled\n"
|
||||
"Language file \"l10n/Test1/en.yaml\" is enabled\n");
|
||||
internal::CaptureStdout();
|
||||
l.safe_script("t1 = l10n('Test1')");
|
||||
EXPECT_THAT(internal::GetCapturedStdout(),
|
||||
"Language file \"l10n/Test1/de.yaml\" is enabled\n"
|
||||
"Language file \"l10n/Test1/en.yaml\" is enabled\n");
|
||||
|
||||
internal::CaptureStdout();
|
||||
l.safe_script("t2 = l10n('Test2')");
|
||||
{
|
||||
std::string output = internal::GetCapturedStdout();
|
||||
EXPECT_THAT(output, HasSubstr("Language file \"l10n/Test2/en.yaml\" is enabled"));
|
||||
}
|
||||
internal::CaptureStdout();
|
||||
l.safe_script("t2 = l10n('Test2')");
|
||||
{
|
||||
std::string output = internal::GetCapturedStdout();
|
||||
EXPECT_THAT(output, HasSubstr("Language file \"l10n/Test2/en.yaml\" is enabled"));
|
||||
}
|
||||
|
||||
EXPECT_EQ(get<std::string>(l, "t1('good_morning')"), "Guten Morgen.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('you_have_arrows', {count=1})"), "Du hast ein Pfeil.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('you_have_arrows', {count=5})"), "Du hast 5 Pfeile.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('Hello {name}!', {name='World'})"), "Hallo World!");
|
||||
EXPECT_EQ(get<std::string>(l, "t2('good_morning')"), "Morning!");
|
||||
EXPECT_EQ(get<std::string>(l, "t2('you_have_arrows', {count=3})"), "Arrows count: 3");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('good_morning')"), "Guten Morgen.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('you_have_arrows', {count=1})"), "Du hast ein Pfeil.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('you_have_arrows', {count=5})"), "Du hast 5 Pfeile.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('Hello {name}!', {name='World'})"), "Hallo World!");
|
||||
EXPECT_EQ(get<std::string>(l, "t2('good_morning')"), "Morning!");
|
||||
EXPECT_EQ(get<std::string>(l, "t2('you_have_arrows', {count=3})"), "Arrows count: 3");
|
||||
|
||||
internal::CaptureStdout();
|
||||
l10nManager.setPreferredLocales({ "en", "de" });
|
||||
EXPECT_THAT(internal::GetCapturedStdout(),
|
||||
"Preferred locales: gmst en de\n"
|
||||
"Language file \"l10n/Test1/en.yaml\" is enabled\n"
|
||||
"Language file \"l10n/Test1/de.yaml\" is enabled\n"
|
||||
"Language file \"l10n/Test2/en.yaml\" is enabled\n");
|
||||
internal::CaptureStdout();
|
||||
l10nManager.setPreferredLocales({ "en", "de" });
|
||||
EXPECT_THAT(internal::GetCapturedStdout(),
|
||||
"Preferred locales: gmst en de\n"
|
||||
"Language file \"l10n/Test1/en.yaml\" is enabled\n"
|
||||
"Language file \"l10n/Test1/de.yaml\" is enabled\n"
|
||||
"Language file \"l10n/Test2/en.yaml\" is enabled\n");
|
||||
|
||||
EXPECT_EQ(get<std::string>(l, "t1('good_morning')"), "Good morning.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('you_have_arrows', {count=1})"), "You have one arrow.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('you_have_arrows', {count=5})"), "You have 5 arrows.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('pc_must_come', {PCGender=\"male\"})"), "He is coming with us.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('pc_must_come', {PCGender=\"female\"})"), "She is coming with us.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('pc_must_come', {PCGender=\"blah\"})"), "They are coming with us.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('pc_must_come', {PCGender=\"other\"})"), "They are coming with us.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('quest_completion', {done=0.1})"), "The quest is 10% complete.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('quest_completion', {done=1})"), "The quest is 100% complete.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('ordinal', {num=1})"), "You came in 1st place.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('ordinal', {num=100})"), "You came in 100th place.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('spellout', {num=1})"), "There is one thing.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('spellout', {num=100})"), "There are one hundred things.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('duration', {num=100})"), "It took 1:40");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('numbers', {int=123, double=123.456})"),
|
||||
"123 and 123 are integers, but 123.456 is a double");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('rounding', {value=123.456789})"), "123.46");
|
||||
// Check that failed messages display the key instead of an empty string
|
||||
EXPECT_EQ(get<std::string>(l, "t1('{mismatched_braces')"), "{mismatched_braces");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('{unknown_arg}')"), "{unknown_arg}");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('{num, integer}', {num=1})"), "{num, integer}");
|
||||
// Doesn't give a valid currency symbol with `en`. Not that openmw is designed for real world currency.
|
||||
l10nManager.setPreferredLocales({ "en-US", "de" });
|
||||
EXPECT_EQ(get<std::string>(l, "t1('currency', {money=10000.10})"), "You have $10,000.10");
|
||||
// Note: Not defined in English localisation file, so we fall back to the German before falling back to the key
|
||||
EXPECT_EQ(get<std::string>(l, "t1('Hello {name}!', {name='World'})"), "Hallo World!");
|
||||
EXPECT_EQ(get<std::string>(l, "t2('good_morning')"), "Morning!");
|
||||
EXPECT_EQ(get<std::string>(l, "t2('you_have_arrows', {count=3})"), "Arrows count: 3");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('good_morning')"), "Good morning.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('you_have_arrows', {count=1})"), "You have one arrow.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('you_have_arrows', {count=5})"), "You have 5 arrows.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('pc_must_come', {PCGender=\"male\"})"), "He is coming with us.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('pc_must_come', {PCGender=\"female\"})"), "She is coming with us.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('pc_must_come', {PCGender=\"blah\"})"), "They are coming with us.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('pc_must_come', {PCGender=\"other\"})"), "They are coming with us.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('quest_completion', {done=0.1})"), "The quest is 10% complete.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('quest_completion', {done=1})"), "The quest is 100% complete.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('ordinal', {num=1})"), "You came in 1st place.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('ordinal', {num=100})"), "You came in 100th place.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('spellout', {num=1})"), "There is one thing.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('spellout', {num=100})"), "There are one hundred things.");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('duration', {num=100})"), "It took 1:40");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('numbers', {int=123, double=123.456})"),
|
||||
"123 and 123 are integers, but 123.456 is a double");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('rounding', {value=123.456789})"), "123.46");
|
||||
// Check that failed messages display the key instead of an empty string
|
||||
EXPECT_EQ(get<std::string>(l, "t1('{mismatched_braces')"), "{mismatched_braces");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('{unknown_arg}')"), "{unknown_arg}");
|
||||
EXPECT_EQ(get<std::string>(l, "t1('{num, integer}', {num=1})"), "{num, integer}");
|
||||
// Doesn't give a valid currency symbol with `en`. Not that openmw is designed for real world currency.
|
||||
l10nManager.setPreferredLocales({ "en-US", "de" });
|
||||
EXPECT_EQ(get<std::string>(l, "t1('currency', {money=10000.10})"), "You have $10,000.10");
|
||||
// Note: Not defined in English localisation file, so we fall back to the German before falling back to the
|
||||
// key
|
||||
EXPECT_EQ(get<std::string>(l, "t1('Hello {name}!', {name='World'})"), "Hallo World!");
|
||||
EXPECT_EQ(get<std::string>(l, "t2('good_morning')"), "Morning!");
|
||||
EXPECT_EQ(get<std::string>(l, "t2('you_have_arrows', {count=3})"), "Arrows count: 3");
|
||||
|
||||
// Test that locales with variants and country codes fall back to more generic locales
|
||||
internal::CaptureStdout();
|
||||
l10nManager.setPreferredLocales({ "en-GB-oed", "de" });
|
||||
EXPECT_THAT(internal::GetCapturedStdout(),
|
||||
"Preferred locales: gmst en_GB_OED de\n"
|
||||
"Language file \"l10n/Test1/en.yaml\" is enabled\n"
|
||||
"Language file \"l10n/Test1/de.yaml\" is enabled\n"
|
||||
"Language file \"l10n/Test2/en.yaml\" is enabled\n");
|
||||
EXPECT_EQ(get<std::string>(l, "t2('you_have_arrows', {count=3})"), "Arrows count: 3");
|
||||
// Test that locales with variants and country codes fall back to more generic locales
|
||||
internal::CaptureStdout();
|
||||
l10nManager.setPreferredLocales({ "en-GB-oed", "de" });
|
||||
EXPECT_THAT(internal::GetCapturedStdout(),
|
||||
"Preferred locales: gmst en_GB_OED de\n"
|
||||
"Language file \"l10n/Test1/en.yaml\" is enabled\n"
|
||||
"Language file \"l10n/Test1/de.yaml\" is enabled\n"
|
||||
"Language file \"l10n/Test2/en.yaml\" is enabled\n");
|
||||
EXPECT_EQ(get<std::string>(l, "t2('you_have_arrows', {count=3})"), "Arrows count: 3");
|
||||
|
||||
// Test setting fallback language
|
||||
l.safe_script("t3 = l10n('Test3', 'de')");
|
||||
l10nManager.setPreferredLocales({ "en" });
|
||||
EXPECT_EQ(get<std::string>(l, "t3('Hello {name}!', {name='World'})"), "Hallo World!");
|
||||
// Test setting fallback language
|
||||
l.safe_script("t3 = l10n('Test3', 'de')");
|
||||
l10nManager.setPreferredLocales({ "en" });
|
||||
EXPECT_EQ(get<std::string>(l, "t3('Hello {name}!', {name='World'})"), "Hallo World!");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -97,26 +97,26 @@ return {
|
||||
|
||||
TEST_F(LuaStateTest, ToString)
|
||||
{
|
||||
EXPECT_EQ(LuaUtil::toString(sol::make_object(mLua.sol(), 3.14)), "3.14");
|
||||
EXPECT_EQ(LuaUtil::toString(sol::make_object(mLua.sol(), true)), "true");
|
||||
EXPECT_EQ(LuaUtil::toString(sol::make_object(mLua.unsafeState(), 3.14)), "3.14");
|
||||
EXPECT_EQ(LuaUtil::toString(sol::make_object(mLua.unsafeState(), true)), "true");
|
||||
EXPECT_EQ(LuaUtil::toString(sol::nil), "nil");
|
||||
EXPECT_EQ(LuaUtil::toString(sol::make_object(mLua.sol(), "something")), "\"something\"");
|
||||
EXPECT_EQ(LuaUtil::toString(sol::make_object(mLua.unsafeState(), "something")), "\"something\"");
|
||||
}
|
||||
|
||||
TEST_F(LuaStateTest, Cast)
|
||||
{
|
||||
EXPECT_EQ(LuaUtil::cast<int>(sol::make_object(mLua.sol(), 3.14)), 3);
|
||||
EXPECT_ERROR(
|
||||
LuaUtil::cast<int>(sol::make_object(mLua.sol(), "3.14")), "Value \"\"3.14\"\" can not be casted to int");
|
||||
EXPECT_ERROR(LuaUtil::cast<std::string_view>(sol::make_object(mLua.sol(), sol::nil)),
|
||||
EXPECT_EQ(LuaUtil::cast<int>(sol::make_object(mLua.unsafeState(), 3.14)), 3);
|
||||
EXPECT_ERROR(LuaUtil::cast<int>(sol::make_object(mLua.unsafeState(), "3.14")),
|
||||
"Value \"\"3.14\"\" can not be casted to int");
|
||||
EXPECT_ERROR(LuaUtil::cast<std::string_view>(sol::make_object(mLua.unsafeState(), sol::nil)),
|
||||
"Value \"nil\" can not be casted to string");
|
||||
EXPECT_ERROR(LuaUtil::cast<std::string>(sol::make_object(mLua.sol(), sol::nil)),
|
||||
EXPECT_ERROR(LuaUtil::cast<std::string>(sol::make_object(mLua.unsafeState(), sol::nil)),
|
||||
"Value \"nil\" can not be casted to string");
|
||||
EXPECT_ERROR(LuaUtil::cast<sol::table>(sol::make_object(mLua.sol(), sol::nil)),
|
||||
EXPECT_ERROR(LuaUtil::cast<sol::table>(sol::make_object(mLua.unsafeState(), sol::nil)),
|
||||
"Value \"nil\" can not be casted to sol::table");
|
||||
EXPECT_ERROR(LuaUtil::cast<sol::function>(sol::make_object(mLua.sol(), "3.14")),
|
||||
EXPECT_ERROR(LuaUtil::cast<sol::function>(sol::make_object(mLua.unsafeState(), "3.14")),
|
||||
"Value \"\"3.14\"\" can not be casted to sol::function");
|
||||
EXPECT_ERROR(LuaUtil::cast<sol::protected_function>(sol::make_object(mLua.sol(), "3.14")),
|
||||
EXPECT_ERROR(LuaUtil::cast<sol::protected_function>(sol::make_object(mLua.unsafeState(), "3.14")),
|
||||
"Value \"\"3.14\"\" can not be casted to sol::function");
|
||||
}
|
||||
|
||||
@ -186,21 +186,22 @@ return {
|
||||
TEST_F(LuaStateTest, ProvideAPI)
|
||||
{
|
||||
LuaUtil::LuaState lua(mVFS.get(), &mCfg);
|
||||
lua.protectedCall([&](LuaUtil::LuaView& view) {
|
||||
sol::table api1 = LuaUtil::makeReadOnly(view.sol().create_table_with("name", "api1"));
|
||||
sol::table api2 = LuaUtil::makeReadOnly(view.sol().create_table_with("name", "api2"));
|
||||
|
||||
sol::table api1 = LuaUtil::makeReadOnly(lua.sol().create_table_with("name", "api1"));
|
||||
sol::table api2 = LuaUtil::makeReadOnly(lua.sol().create_table_with("name", "api2"));
|
||||
sol::table script1 = lua.runInNewSandbox("bbb/tests.lua", "", { { "test.api", api1 } });
|
||||
|
||||
sol::table script1 = lua.runInNewSandbox("bbb/tests.lua", "", { { "test.api", api1 } });
|
||||
lua.addCommonPackage("sqrlib", view.sol().create_table_with("sqr", [](int x) { return x * x; }));
|
||||
|
||||
lua.addCommonPackage("sqrlib", lua.sol().create_table_with("sqr", [](int x) { return x * x; }));
|
||||
sol::table script2 = lua.runInNewSandbox("bbb/tests.lua", "", { { "test.api", api2 } });
|
||||
|
||||
sol::table script2 = lua.runInNewSandbox("bbb/tests.lua", "", { { "test.api", api2 } });
|
||||
EXPECT_ERROR(LuaUtil::call(script1["sqr"], 3), "module not found: sqrlib");
|
||||
EXPECT_EQ(LuaUtil::call(script2["sqr"], 3).get<int>(), 9);
|
||||
|
||||
EXPECT_ERROR(LuaUtil::call(script1["sqr"], 3), "module not found: sqrlib");
|
||||
EXPECT_EQ(LuaUtil::call(script2["sqr"], 3).get<int>(), 9);
|
||||
|
||||
EXPECT_EQ(LuaUtil::call(script1["apiName"]).get<std::string>(), "api1");
|
||||
EXPECT_EQ(LuaUtil::call(script2["apiName"]).get<std::string>(), "api2");
|
||||
EXPECT_EQ(LuaUtil::call(script1["apiName"]).get<std::string>(), "api1");
|
||||
EXPECT_EQ(LuaUtil::call(script2["apiName"]).get<std::string>(), "api2");
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(LuaStateTest, GetLuaVersion)
|
||||
@ -212,7 +213,7 @@ return {
|
||||
{
|
||||
auto getMem = [&] {
|
||||
for (int i = 0; i < 5; ++i)
|
||||
lua_gc(mLua.sol(), LUA_GCCOLLECT, 0);
|
||||
lua_gc(mLua.unsafeState(), LUA_GCCOLLECT, 0);
|
||||
return mLua.getTotalMemoryUsage();
|
||||
};
|
||||
int64_t memWithScript;
|
||||
|
@ -198,8 +198,9 @@ CUSTOM, PLAYER: useInterface.lua
|
||||
EXPECT_TRUE(scripts.addCustomScript(*mCfg.findId("stopEvent.lua")));
|
||||
EXPECT_TRUE(scripts.addCustomScript(*mCfg.findId("test2.lua")));
|
||||
|
||||
std::string X0 = LuaUtil::serialize(mLua.sol().create_table_with("x", 0.5));
|
||||
std::string X1 = LuaUtil::serialize(mLua.sol().create_table_with("x", 1.5));
|
||||
sol::state_view sol = mLua.unsafeState();
|
||||
std::string X0 = LuaUtil::serialize(sol.create_table_with("x", 0.5));
|
||||
std::string X1 = LuaUtil::serialize(sol.create_table_with("x", 1.5));
|
||||
|
||||
{
|
||||
testing::internal::CaptureStdout();
|
||||
@ -243,7 +244,8 @@ CUSTOM, PLAYER: useInterface.lua
|
||||
EXPECT_TRUE(scripts.addCustomScript(*mCfg.findId("test1.lua")));
|
||||
EXPECT_TRUE(scripts.addCustomScript(*mCfg.findId("stopEvent.lua")));
|
||||
EXPECT_TRUE(scripts.addCustomScript(*mCfg.findId("test2.lua")));
|
||||
std::string X = LuaUtil::serialize(mLua.sol().create_table_with("x", 0.5));
|
||||
sol::state_view sol = mLua.unsafeState();
|
||||
std::string X = LuaUtil::serialize(sol.create_table_with("x", 0.5));
|
||||
|
||||
{
|
||||
testing::internal::CaptureStdout();
|
||||
@ -334,8 +336,9 @@ CUSTOM, PLAYER: useInterface.lua
|
||||
scripts1.addAutoStartedScripts();
|
||||
EXPECT_TRUE(scripts1.addCustomScript(*mCfg.findId("test1.lua")));
|
||||
|
||||
scripts1.receiveEvent("Set", LuaUtil::serialize(mLua.sol().create_table_with("n", 1, "x", 0.5, "y", 3.5)));
|
||||
scripts1.receiveEvent("Set", LuaUtil::serialize(mLua.sol().create_table_with("n", 2, "x", 2.5, "y", 1.5)));
|
||||
sol::state_view sol = mLua.unsafeState();
|
||||
scripts1.receiveEvent("Set", LuaUtil::serialize(sol.create_table_with("n", 1, "x", 0.5, "y", 3.5)));
|
||||
scripts1.receiveEvent("Set", LuaUtil::serialize(sol.create_table_with("n", 2, "x", 2.5, "y", 1.5)));
|
||||
|
||||
ESM::LuaScripts data;
|
||||
scripts1.save(data);
|
||||
@ -379,10 +382,10 @@ CUSTOM, PLAYER: useInterface.lua
|
||||
EXPECT_EQ(internal::GetCapturedStdout(), "");
|
||||
|
||||
int counter1 = 0, counter2 = 0, counter3 = 0, counter4 = 0;
|
||||
sol::function fn1 = sol::make_object(mLua.sol(), [&]() { counter1++; });
|
||||
sol::function fn2 = sol::make_object(mLua.sol(), [&]() { counter2++; });
|
||||
sol::function fn3 = sol::make_object(mLua.sol(), [&](int d) { counter3 += d; });
|
||||
sol::function fn4 = sol::make_object(mLua.sol(), [&](int d) { counter4 += d; });
|
||||
sol::function fn1 = sol::make_object(mLua.unsafeState(), [&]() { counter1++; });
|
||||
sol::function fn2 = sol::make_object(mLua.unsafeState(), [&]() { counter2++; });
|
||||
sol::function fn3 = sol::make_object(mLua.unsafeState(), [&](int d) { counter3 += d; });
|
||||
sol::function fn4 = sol::make_object(mLua.unsafeState(), [&](int d) { counter4 += d; });
|
||||
|
||||
scripts.registerTimerCallback(test1Id, "A", fn3);
|
||||
scripts.registerTimerCallback(test1Id, "B", fn4);
|
||||
@ -391,12 +394,16 @@ CUSTOM, PLAYER: useInterface.lua
|
||||
|
||||
scripts.processTimers(1, 2);
|
||||
|
||||
scripts.setupSerializableTimer(TimerType::SIMULATION_TIME, 10, test1Id, "B", sol::make_object(mLua.sol(), 3));
|
||||
scripts.setupSerializableTimer(TimerType::GAME_TIME, 10, test2Id, "B", sol::make_object(mLua.sol(), 4));
|
||||
scripts.setupSerializableTimer(TimerType::SIMULATION_TIME, 5, test1Id, "A", sol::make_object(mLua.sol(), 1));
|
||||
scripts.setupSerializableTimer(TimerType::GAME_TIME, 5, test2Id, "A", sol::make_object(mLua.sol(), 2));
|
||||
scripts.setupSerializableTimer(TimerType::SIMULATION_TIME, 15, test1Id, "A", sol::make_object(mLua.sol(), 10));
|
||||
scripts.setupSerializableTimer(TimerType::SIMULATION_TIME, 15, test1Id, "B", sol::make_object(mLua.sol(), 20));
|
||||
scripts.setupSerializableTimer(
|
||||
TimerType::SIMULATION_TIME, 10, test1Id, "B", sol::make_object(mLua.unsafeState(), 3));
|
||||
scripts.setupSerializableTimer(TimerType::GAME_TIME, 10, test2Id, "B", sol::make_object(mLua.unsafeState(), 4));
|
||||
scripts.setupSerializableTimer(
|
||||
TimerType::SIMULATION_TIME, 5, test1Id, "A", sol::make_object(mLua.unsafeState(), 1));
|
||||
scripts.setupSerializableTimer(TimerType::GAME_TIME, 5, test2Id, "A", sol::make_object(mLua.unsafeState(), 2));
|
||||
scripts.setupSerializableTimer(
|
||||
TimerType::SIMULATION_TIME, 15, test1Id, "A", sol::make_object(mLua.unsafeState(), 10));
|
||||
scripts.setupSerializableTimer(
|
||||
TimerType::SIMULATION_TIME, 15, test1Id, "B", sol::make_object(mLua.unsafeState(), 20));
|
||||
|
||||
scripts.setupUnsavableTimer(TimerType::SIMULATION_TIME, 10, test2Id, fn2);
|
||||
scripts.setupUnsavableTimer(TimerType::GAME_TIME, 10, test1Id, fn2);
|
||||
@ -446,7 +453,8 @@ CUSTOM, PLAYER: useInterface.lua
|
||||
|
||||
TEST_F(LuaScriptsContainerTest, CallbackWrapper)
|
||||
{
|
||||
LuaUtil::Callback callback{ mLua.sol()["print"], mLua.newTable() };
|
||||
sol::state_view view = mLua.unsafeState();
|
||||
LuaUtil::Callback callback{ view["print"], sol::table(view, sol::create) };
|
||||
callback.mHiddenData[LuaUtil::ScriptsContainer::sScriptDebugNameKey] = "some_script.lua";
|
||||
callback.mHiddenData[LuaUtil::ScriptsContainer::sScriptIdKey] = LuaUtil::ScriptId{ nullptr, 0 };
|
||||
|
||||
|
@ -19,102 +19,110 @@ namespace
|
||||
{
|
||||
// Note: LuaUtil::Callback can be used only if Lua is initialized via LuaUtil::LuaState
|
||||
LuaUtil::LuaState luaState{ nullptr, nullptr };
|
||||
sol::state_view& mLua = luaState.sol();
|
||||
LuaUtil::LuaStorage::initLuaBindings(mLua);
|
||||
LuaUtil::LuaStorage storage(mLua);
|
||||
storage.setActive(true);
|
||||
luaState.protectedCall([](LuaUtil::LuaView& view) {
|
||||
sol::state_view& lua = view.sol();
|
||||
LuaUtil::LuaStorage::initLuaBindings(view);
|
||||
LuaUtil::LuaStorage storage;
|
||||
storage.setActive(true);
|
||||
|
||||
sol::table callbackHiddenData(mLua, sol::create);
|
||||
callbackHiddenData[LuaUtil::ScriptsContainer::sScriptIdKey] = LuaUtil::ScriptId{};
|
||||
LuaUtil::getAsyncPackageInitializer(
|
||||
mLua.lua_state(), []() { return 0.0; }, []() { return 0.0; })(callbackHiddenData);
|
||||
mLua["async"] = LuaUtil::AsyncPackageId{ nullptr, 0, callbackHiddenData };
|
||||
sol::table callbackHiddenData(lua, sol::create);
|
||||
callbackHiddenData[LuaUtil::ScriptsContainer::sScriptIdKey] = LuaUtil::ScriptId{};
|
||||
LuaUtil::getAsyncPackageInitializer(
|
||||
lua.lua_state(), []() { return 0.0; }, []() { return 0.0; })(callbackHiddenData);
|
||||
lua["async"] = LuaUtil::AsyncPackageId{ nullptr, 0, callbackHiddenData };
|
||||
|
||||
mLua["mutable"] = storage.getMutableSection("test");
|
||||
mLua["ro"] = storage.getReadOnlySection("test");
|
||||
lua["mutable"] = storage.getMutableSection(lua, "test");
|
||||
lua["ro"] = storage.getReadOnlySection(lua, "test");
|
||||
|
||||
mLua.safe_script(R"(
|
||||
callbackCalls = {}
|
||||
ro:subscribe(async:callback(function(section, key)
|
||||
table.insert(callbackCalls, section .. '_' .. (key or '*'))
|
||||
end))
|
||||
)");
|
||||
lua.safe_script(R"(
|
||||
callbackCalls = {}
|
||||
ro:subscribe(async:callback(function(section, key)
|
||||
table.insert(callbackCalls, section .. '_' .. (key or '*'))
|
||||
end))
|
||||
)");
|
||||
|
||||
mLua.safe_script("mutable:set('x', 5)");
|
||||
EXPECT_EQ(get<int>(mLua, "mutable:get('x')"), 5);
|
||||
EXPECT_EQ(get<int>(mLua, "ro:get('x')"), 5);
|
||||
lua.safe_script("mutable:set('x', 5)");
|
||||
EXPECT_EQ(get<int>(lua, "mutable:get('x')"), 5);
|
||||
EXPECT_EQ(get<int>(lua, "ro:get('x')"), 5);
|
||||
|
||||
EXPECT_THROW(mLua.safe_script("ro:set('y', 3)"), std::exception);
|
||||
EXPECT_THROW(lua.safe_script("ro:set('y', 3)"), std::exception);
|
||||
|
||||
mLua.safe_script("t1 = mutable:asTable()");
|
||||
mLua.safe_script("t2 = ro:asTable()");
|
||||
EXPECT_EQ(get<int>(mLua, "t1.x"), 5);
|
||||
EXPECT_EQ(get<int>(mLua, "t2.x"), 5);
|
||||
lua.safe_script("t1 = mutable:asTable()");
|
||||
lua.safe_script("t2 = ro:asTable()");
|
||||
EXPECT_EQ(get<int>(lua, "t1.x"), 5);
|
||||
EXPECT_EQ(get<int>(lua, "t2.x"), 5);
|
||||
|
||||
mLua.safe_script("mutable:reset()");
|
||||
EXPECT_TRUE(get<bool>(mLua, "ro:get('x') == nil"));
|
||||
lua.safe_script("mutable:reset()");
|
||||
EXPECT_TRUE(get<bool>(lua, "ro:get('x') == nil"));
|
||||
|
||||
mLua.safe_script("mutable:reset({x=4, y=7})");
|
||||
EXPECT_EQ(get<int>(mLua, "ro:get('x')"), 4);
|
||||
EXPECT_EQ(get<int>(mLua, "ro:get('y')"), 7);
|
||||
lua.safe_script("mutable:reset({x=4, y=7})");
|
||||
EXPECT_EQ(get<int>(lua, "ro:get('x')"), 4);
|
||||
EXPECT_EQ(get<int>(lua, "ro:get('y')"), 7);
|
||||
|
||||
EXPECT_THAT(get<std::string>(mLua, "table.concat(callbackCalls, ', ')"), "test_x, test_*, test_*");
|
||||
EXPECT_THAT(get<std::string>(lua, "table.concat(callbackCalls, ', ')"), "test_x, test_*, test_*");
|
||||
});
|
||||
}
|
||||
|
||||
TEST(LuaUtilStorageTest, Table)
|
||||
{
|
||||
sol::state mLua;
|
||||
LuaUtil::LuaStorage::initLuaBindings(mLua);
|
||||
LuaUtil::LuaStorage storage(mLua);
|
||||
storage.setActive(true);
|
||||
mLua["mutable"] = storage.getMutableSection("test");
|
||||
mLua["ro"] = storage.getReadOnlySection("test");
|
||||
LuaUtil::LuaState luaState{ nullptr, nullptr };
|
||||
luaState.protectedCall([](LuaUtil::LuaView& view) {
|
||||
LuaUtil::LuaStorage::initLuaBindings(view);
|
||||
LuaUtil::LuaStorage storage;
|
||||
auto& lua = view.sol();
|
||||
storage.setActive(true);
|
||||
lua["mutable"] = storage.getMutableSection(lua, "test");
|
||||
lua["ro"] = storage.getReadOnlySection(lua, "test");
|
||||
|
||||
mLua.safe_script("mutable:set('x', { y = 'abc', z = 7 })");
|
||||
EXPECT_EQ(get<int>(mLua, "mutable:get('x').z"), 7);
|
||||
EXPECT_THROW(mLua.safe_script("mutable:get('x').z = 3"), std::exception);
|
||||
EXPECT_NO_THROW(mLua.safe_script("mutable:getCopy('x').z = 3"));
|
||||
EXPECT_EQ(get<int>(mLua, "mutable:get('x').z"), 7);
|
||||
EXPECT_EQ(get<int>(mLua, "ro:get('x').z"), 7);
|
||||
EXPECT_EQ(get<std::string>(mLua, "ro:get('x').y"), "abc");
|
||||
lua.safe_script("mutable:set('x', { y = 'abc', z = 7 })");
|
||||
EXPECT_EQ(get<int>(lua, "mutable:get('x').z"), 7);
|
||||
EXPECT_THROW(lua.safe_script("mutable:get('x').z = 3"), std::exception);
|
||||
EXPECT_NO_THROW(lua.safe_script("mutable:getCopy('x').z = 3"));
|
||||
EXPECT_EQ(get<int>(lua, "mutable:get('x').z"), 7);
|
||||
EXPECT_EQ(get<int>(lua, "ro:get('x').z"), 7);
|
||||
EXPECT_EQ(get<std::string>(lua, "ro:get('x').y"), "abc");
|
||||
});
|
||||
}
|
||||
|
||||
TEST(LuaUtilStorageTest, Saving)
|
||||
{
|
||||
sol::state mLua;
|
||||
LuaUtil::LuaStorage::initLuaBindings(mLua);
|
||||
LuaUtil::LuaStorage storage(mLua);
|
||||
storage.setActive(true);
|
||||
LuaUtil::LuaState luaState{ nullptr, nullptr };
|
||||
luaState.protectedCall([](LuaUtil::LuaView& view) {
|
||||
LuaUtil::LuaStorage::initLuaBindings(view);
|
||||
LuaUtil::LuaStorage storage;
|
||||
auto& lua = view.sol();
|
||||
storage.setActive(true);
|
||||
|
||||
mLua["permanent"] = storage.getMutableSection("permanent");
|
||||
mLua["temporary"] = storage.getMutableSection("temporary");
|
||||
mLua.safe_script("temporary:removeOnExit()");
|
||||
mLua.safe_script("permanent:set('x', 1)");
|
||||
mLua.safe_script("temporary:set('y', 2)");
|
||||
lua["permanent"] = storage.getMutableSection(lua, "permanent");
|
||||
lua["temporary"] = storage.getMutableSection(lua, "temporary");
|
||||
lua.safe_script("temporary:removeOnExit()");
|
||||
lua.safe_script("permanent:set('x', 1)");
|
||||
lua.safe_script("temporary:set('y', 2)");
|
||||
|
||||
const auto tmpFile = std::filesystem::temp_directory_path() / "test_storage.bin";
|
||||
storage.save(tmpFile);
|
||||
EXPECT_EQ(get<int>(mLua, "permanent:get('x')"), 1);
|
||||
EXPECT_EQ(get<int>(mLua, "temporary:get('y')"), 2);
|
||||
const auto tmpFile = std::filesystem::temp_directory_path() / "test_storage.bin";
|
||||
storage.save(lua, tmpFile);
|
||||
EXPECT_EQ(get<int>(lua, "permanent:get('x')"), 1);
|
||||
EXPECT_EQ(get<int>(lua, "temporary:get('y')"), 2);
|
||||
|
||||
storage.clearTemporaryAndRemoveCallbacks();
|
||||
mLua["permanent"] = storage.getMutableSection("permanent");
|
||||
mLua["temporary"] = storage.getMutableSection("temporary");
|
||||
EXPECT_EQ(get<int>(mLua, "permanent:get('x')"), 1);
|
||||
EXPECT_TRUE(get<bool>(mLua, "temporary:get('y') == nil"));
|
||||
storage.clearTemporaryAndRemoveCallbacks();
|
||||
lua["permanent"] = storage.getMutableSection(lua, "permanent");
|
||||
lua["temporary"] = storage.getMutableSection(lua, "temporary");
|
||||
EXPECT_EQ(get<int>(lua, "permanent:get('x')"), 1);
|
||||
EXPECT_TRUE(get<bool>(lua, "temporary:get('y') == nil"));
|
||||
|
||||
mLua.safe_script("permanent:set('x', 3)");
|
||||
mLua.safe_script("permanent:set('z', 4)");
|
||||
lua.safe_script("permanent:set('x', 3)");
|
||||
lua.safe_script("permanent:set('z', 4)");
|
||||
|
||||
LuaUtil::LuaStorage storage2(mLua);
|
||||
storage2.setActive(true);
|
||||
storage2.load(tmpFile);
|
||||
mLua["permanent"] = storage2.getMutableSection("permanent");
|
||||
mLua["temporary"] = storage2.getMutableSection("temporary");
|
||||
LuaUtil::LuaStorage storage2;
|
||||
storage2.setActive(true);
|
||||
storage2.load(lua, tmpFile);
|
||||
lua["permanent"] = storage2.getMutableSection(lua, "permanent");
|
||||
lua["temporary"] = storage2.getMutableSection(lua, "temporary");
|
||||
|
||||
EXPECT_EQ(get<int>(mLua, "permanent:get('x')"), 1);
|
||||
EXPECT_TRUE(get<bool>(mLua, "permanent:get('z') == nil"));
|
||||
EXPECT_TRUE(get<bool>(mLua, "temporary:get('y') == nil"));
|
||||
EXPECT_EQ(get<int>(lua, "permanent:get('x')"), 1);
|
||||
EXPECT_TRUE(get<bool>(lua, "permanent:get('z') == nil"));
|
||||
EXPECT_TRUE(get<bool>(lua, "temporary:get('y') == nil"));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ namespace
|
||||
return LuaUi::ContentView(result.get<sol::table>());
|
||||
}
|
||||
|
||||
sol::table makeTable() { return sol::table(mLuaState.sol(), sol::create); }
|
||||
sol::table makeTable() { return sol::table(mLuaState.unsafeState(), sol::create); }
|
||||
|
||||
sol::table makeTable(std::string name)
|
||||
{
|
||||
@ -39,13 +39,14 @@ namespace
|
||||
|
||||
TEST_F(LuaUiContentTest, ProtectedMetatable)
|
||||
{
|
||||
mLuaState.sol()["makeContent"] = mNew;
|
||||
mLuaState.sol()["M"] = makeContent(makeTable()).getMetatable();
|
||||
sol::state_view sol = mLuaState.unsafeState();
|
||||
sol["makeContent"] = mNew;
|
||||
sol["M"] = makeContent(makeTable()).getMetatable();
|
||||
std::string testScript = R"(
|
||||
assert(not pcall(function() setmetatable(makeContent{}, {}) end), 'Metatable is not protected')
|
||||
assert(getmetatable(makeContent{}) == false, 'Metatable is not protected')
|
||||
)";
|
||||
EXPECT_NO_THROW(mLuaState.sol().safe_script(testScript));
|
||||
EXPECT_NO_THROW(sol.safe_script(testScript));
|
||||
}
|
||||
|
||||
TEST_F(LuaUiContentTest, Create)
|
||||
|
@ -95,7 +95,7 @@ namespace MWLua
|
||||
|
||||
sol::table initMWScriptBindings(const Context& context)
|
||||
{
|
||||
sol::state_view lua = lua;
|
||||
sol::state_view lua = context.sol();
|
||||
sol::table api(lua, sol::create);
|
||||
|
||||
api["getGlobalScript"]
|
||||
|
Loading…
x
Reference in New Issue
Block a user