// https://github.com/vinniefalco/LuaBridge
// Copyright 2019, Dmitry Tarakanov
// SPDX-License-Identifier: MIT
#include "TestBase.h"
#include "LuaBridge/Map.h"
#include <map>
struct MapTests : TestBase
{
};
TEST_F(MapTests, LuaRef)
{
{
runLua("result = {[false] = true, a = 'abc', [1] = 5, [3.14] = -1.1}");
using Map = std::map<luabridge::LuaRef, luabridge::LuaRef>;
Map expected{
{luabridge::LuaRef(L, false), luabridge::LuaRef(L, true)},
{luabridge::LuaRef(L, 'a'), luabridge::LuaRef(L, "abc")},
{luabridge::LuaRef(L, 1), luabridge::LuaRef(L, 5)},
{luabridge::LuaRef(L, 3.14), luabridge::LuaRef(L, -1.1)},
};
Map actual = result();
ASSERT_EQ(expected, actual);
ASSERT_EQ(expected, result<Map>());
}
{
runLua("result = {'a', 'b', 'c'}");
using Int2Char = std::map<int, char>;
Int2Char expected{{1, 'a'}, {2, 'b'}, {3, 'c'}};
Int2Char actual = result();
ASSERT_EQ(expected, actual);
ASSERT_EQ(expected, result<Int2Char>());
}
}
TEST_F(MapTests, CastToMap)
{
luabridge::LuaException::enableExceptions(L);
using StrToInt = std::map<std::string, int>;
runLua("result = {[1] = 2, a = 3}");
ASSERT_EQ((StrToInt{{"1", 2}, {"a", 3}}), result().cast<StrToInt>());
using IntToInt = std::map<int, int>;
runLua("result = {[1] = 2, a = 3}");
ASSERT_THROW((result().cast<IntToInt>()), std::exception);
}
TEST_F(MapTests, PassToFunction)
{
runLua("function foo (map) "
" result = map "
"end");
auto foo = luabridge::getGlobal(L, "foo");
using Int2Bool = std::map<int, bool>;
resetResult();
Int2Bool lvalue{{10, false}, {20, true}, {30, true}};
foo(lvalue);
ASSERT_TRUE(result().isTable());
ASSERT_EQ(lvalue, result<Int2Bool>());
resetResult();
const Int2Bool constLvalue = lvalue;
foo(constLvalue);
ASSERT_TRUE(result().isTable());
ASSERT_EQ(constLvalue, result<Int2Bool>());
}
namespace {
struct Data
{
/* explicit */ Data(int i) : i(i) {}
int i;
};
bool operator==(const Data& lhs, const Data& rhs)
{
return lhs.i == rhs.i;
}
bool operator<(const Data& lhs, const Data& rhs)
{
return lhs.i < rhs.i;
}
std::ostream& operator<<(std::ostream& lhs, const Data& rhs)
{
lhs << "{" << rhs.i << "}";
return lhs;
}
std::map<Data, Data> processValues(const std::map<Data, Data>& data)
{
return data;
}
std::map<Data, Data> processPointers(const std::map<Data, const Data*>& data)
{
std::map<Data, Data> result;
for (const auto& item : data)
{
result.emplace(item.first, *item.second);
}
return result;
}
} // namespace
TEST_F(MapTests, PassFromLua)
{
luabridge::getGlobalNamespace(L)
.beginClass<Data>("Data")
.addConstructor<void (*)(int)>()
.endClass()
.addFunction("processValues", &processValues)
.addFunction("processPointers", &processPointers);
{
resetResult();
runLua("result = processValues ({[Data (-1)] = Data (2)})");
std::map<Data, Data> expected{{Data(-1), Data(2)}};
const auto actual = result<std::map<Data, Data>>();
ASSERT_EQ(expected, actual);
}
{
resetResult();
runLua("result = processPointers ({[Data (3)] = Data (-4)})");
std::map<Data, Data> expected{{Data(3), Data(-4)}};
const auto actual = result<std::map<Data, Data>>();
ASSERT_EQ(expected, actual);
}
}