// https://github.com/vinniefalco/LuaBridge // // Copyright 2019, Dmitry Tarakanov // Copyright 2012, Vinnie Falco // Copyright 2007, Nathan Reed // SPDX-License-Identifier: MIT #include "TestBase.h" #include struct LuaRefTests : TestBase { }; TEST_F (LuaRefTests, ValueAccess) { runLua ("result = true"); ASSERT_TRUE (result ().isBool ()); ASSERT_TRUE (result ()); runLua ("result = 7"); ASSERT_TRUE (result ().isNumber ()); ASSERT_EQ (7u, result ()); ASSERT_EQ (7, result ()); ASSERT_EQ (7u, result ()); ASSERT_EQ (7, result ()); ASSERT_EQ (7u, result ()); ASSERT_EQ (7, result ()); ASSERT_EQ (7u, result ()); ASSERT_EQ (7, result ()); ASSERT_EQ (7u, result ()); runLua ("result = 3.14"); ASSERT_TRUE (result ().isNumber ()); ASSERT_FLOAT_EQ (3.14f, result ()); ASSERT_DOUBLE_EQ (3.14, result ()); runLua ("result = 'D'"); ASSERT_TRUE (result ().isString ()); ASSERT_EQ ('D', result ()); ASSERT_EQ ("D", result ()); ASSERT_STREQ ("D", result ()); runLua ("result = 'abc'"); ASSERT_TRUE (result ().isString ()); ASSERT_EQ ("abc", result ()); ASSERT_STREQ ("abc", result ()); runLua ("result = function (i) " " result = i + 1 " " return i " "end"); ASSERT_TRUE (result ().isFunction ()); auto fnResult = result () (41); // Replaces result variable ASSERT_TRUE (fnResult.isNumber ()); ASSERT_EQ (41, fnResult.cast ()); ASSERT_TRUE (result ().isNumber ()); ASSERT_EQ (42, result ()); } TEST_F (LuaRefTests, DictionaryRead) { runLua ( "result = {" " bool = true," " int = 5," " c = 3.14," " [true] = 'D'," " [8] = 'abc'," " fn = function (i) " " result = i + 1 " " return i " " end" "}"); ASSERT_TRUE (result () ["bool"].isBool ()); ASSERT_TRUE (result () ["bool"].cast ()); ASSERT_TRUE (result () ["int"].isNumber ()); ASSERT_EQ (5u, result () ["int"].cast ()); ASSERT_EQ (5, result () ["int"].cast ()); ASSERT_EQ (5u, result () ["int"].cast ()); ASSERT_EQ (5, result () ["int"].cast ()); ASSERT_EQ (5u, result () ["int"].cast ()); ASSERT_EQ (5, result () ["int"].cast ()); ASSERT_EQ (5u, result () ["int"].cast ()); ASSERT_EQ (5, result () ["int"].cast ()); ASSERT_EQ (5u, result () ["int"].cast ()); ASSERT_TRUE (result () ['c'].isNumber ()); ASSERT_FLOAT_EQ (3.14f, result () ['c'].cast ()); ASSERT_DOUBLE_EQ (3.14, result () ['c'].cast ()); ASSERT_TRUE (result () [true].isString ()); ASSERT_EQ ('D', result () [true].cast ()); ASSERT_EQ ("D", result () [true].cast ()); ASSERT_STREQ ("D", result () [true].cast ()); ASSERT_TRUE (result () [8].isString ()); ASSERT_EQ ("abc", result () [8].cast ()); ASSERT_STREQ ("abc", result () [8].cast ()); ASSERT_TRUE (result () ["fn"].isFunction ()); auto fnResult = result () ["fn"] (41); // Replaces result variable ASSERT_TRUE (fnResult.isNumber ()); ASSERT_EQ (41, fnResult.cast ()); ASSERT_TRUE (result ().isNumber ()); ASSERT_EQ (42, result ()); } TEST_F (LuaRefTests, DictionaryWrite) { runLua ("result = {a = 5}"); ASSERT_TRUE (result () ["a"].isNumber ()); ASSERT_EQ (5, result () ["a"].cast ()); result () ["a"] = 7; ASSERT_EQ (7, result () ["a"].cast ()); runLua ("result = result.a"); ASSERT_EQ (7, result ()); runLua ("result = {a = {b = 1}}"); ASSERT_EQ (1, result () ["a"] ["b"].cast ()); result () ["a"] ["b"] = 2; ASSERT_EQ (2, result () ["a"] ["b"].cast ()); } struct Class { }; TEST_F (LuaRefTests, Comparison) { runLua ( "function foo () end " "local m = {} " "m.__eq = function (l, r) return l.a == r.a end " "m.__lt = function (l, r) return l.a < r.a end " "m.__le = function (l, r) return l.a <= r.a end " "t1 = {a = 1} setmetatable (t1, m) " "t2 = {a = 2} setmetatable (t2, m) " "t3 = {a = 1} setmetatable (t3, m) " "t4 = {a = 2} " ); luabridge::getGlobalNamespace (L) .beginClass ("Class") .endClass (); luabridge::LuaRef nil (L, luabridge::Nil ()); luabridge::LuaRef boolFalse (L, false); luabridge::LuaRef boolTrue (L, true); luabridge::LuaRef minus5 (L, -5); luabridge::LuaRef numPi (L, 3.14); luabridge::LuaRef stringA (L, 'a'); luabridge::LuaRef stringAB (L, "ab"); luabridge::LuaRef t1 = luabridge::getGlobal (L, "t1"); luabridge::LuaRef t2 = luabridge::getGlobal (L, "t2"); luabridge::LuaRef t3 = luabridge::getGlobal (L, "t3"); luabridge::LuaRef t4 = luabridge::getGlobal (L, "t4"); ASSERT_TRUE (nil == nil); ASSERT_TRUE (nil < boolFalse); ASSERT_TRUE (boolFalse == boolFalse); ASSERT_TRUE (boolTrue == boolTrue); ASSERT_TRUE (boolTrue < minus5); ASSERT_TRUE (minus5 == minus5); ASSERT_FALSE (minus5 == numPi); ASSERT_TRUE (minus5 < numPi); ASSERT_TRUE (minus5 <= numPi); ASSERT_FALSE (minus5 > numPi); ASSERT_FALSE (minus5 >= numPi); ASSERT_TRUE (numPi < stringA); ASSERT_TRUE (stringA == stringA); ASSERT_FALSE (stringA == stringAB); ASSERT_TRUE (stringA < stringAB); ASSERT_TRUE (stringA <= stringAB); ASSERT_FALSE (stringA > stringAB); ASSERT_FALSE (stringA >= stringAB); ASSERT_TRUE (stringA < t1); ASSERT_TRUE (t1 == t1); ASSERT_FALSE (t1 == t2); ASSERT_TRUE (t1 == t3); ASSERT_FALSE (t1.rawequal (t3)); ASSERT_FALSE (t1 == t4); ASSERT_TRUE (t2 == t2); ASSERT_FALSE (t2 == t3); ASSERT_FALSE (t2 == t4); ASSERT_TRUE (t3 == t3); ASSERT_FALSE (t3 == t4); ASSERT_FALSE (t1 < t1); ASSERT_TRUE (t1 < t2); ASSERT_FALSE (t1 < t3); ASSERT_FALSE (t2 < t3); ASSERT_TRUE (t1 <= t1); ASSERT_TRUE (t1 <= t2); ASSERT_TRUE (t1 <= t3); ASSERT_FALSE (t2 <= t3); ASSERT_FALSE (t1 > t1); ASSERT_FALSE (t1 > t2); ASSERT_FALSE (t1 > t3); ASSERT_TRUE (t2 > t3); ASSERT_TRUE (t1 >= t1); ASSERT_FALSE (t1 >= t2); ASSERT_TRUE (t1 >= t3); ASSERT_TRUE (t2 >= t3); } TEST_F (LuaRefTests, Assignment) { runLua ("value = {a = 5}"); auto value = luabridge::getGlobal (L, "value"); ASSERT_TRUE (value.isTable ()); ASSERT_TRUE (value ["a"].isNumber ()); ASSERT_EQ (5, value ["a"].cast ()); value = value ["a"]; ASSERT_TRUE (value.isNumber ()); ASSERT_EQ (5, value.cast ()); value = value; ASSERT_EQ (LUA_TNUMBER, value.type ()); ASSERT_TRUE (value.isNumber ()); ASSERT_EQ (5, value.cast ()); runLua ("t = {a = {b = 5}}"); auto table = luabridge::getGlobal (L, "t"); luabridge::LuaRef entry = table ["a"]; luabridge::LuaRef b1 = entry ["b"]; luabridge::LuaRef b2 = table ["a"] ["b"]; ASSERT_TRUE (b1 == b2); } TEST_F (LuaRefTests, Print) { { runLua ("result = true"); std::ostringstream stream; stream << result (); ASSERT_EQ ("true", stream.str ()); } { runLua ("result = false"); std::ostringstream stream; stream << result (); ASSERT_EQ ("false", stream.str ()); } { runLua ("result = 5"); std::ostringstream stream; stream << result (); ASSERT_EQ ("5", stream.str ()); } { runLua ("result = 'abc'"); std::ostringstream stream; stream << result (); ASSERT_EQ ("\"abc\"", stream.str ()); } runLua ( "result = {" " true_ = true," " false_ = false," " five = 5," " abc = 'abc'" "}"); { std::ostringstream stream; stream << result () ["true_"]; ASSERT_EQ ("true", stream.str ()); } { std::ostringstream stream; stream << result () ["false_"]; ASSERT_EQ ("false", stream.str ()); } { std::ostringstream stream; stream << result () ["five"]; ASSERT_EQ ("5", stream.str ()); } { std::ostringstream stream; stream << result () ["abc"]; ASSERT_EQ ("\"abc\"", stream.str ()); } }