mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2025-06-30 23:06:05 +00:00
fix lua number handling, add lua unit tests for json encode + decode
This commit is contained in:
parent
0c740ccedf
commit
a0f649288e
@ -60,7 +60,11 @@ std::string LuaAPI::LuaToString(const sol::object Value, size_t Indent, bool Quo
|
|||||||
}
|
}
|
||||||
case sol::type::number: {
|
case sol::type::number: {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << Value.as<float>();
|
if (Value.is<int>()) {
|
||||||
|
ss << Value.as<int>();
|
||||||
|
} else {
|
||||||
|
ss << Value.as<float>();
|
||||||
|
}
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
case sol::type::lua_nil:
|
case sol::type::lua_nil:
|
||||||
@ -561,7 +565,11 @@ static void JsonEncodeRecursive(nlohmann::json& json, const sol::object& left, c
|
|||||||
key = left.as<std::string>();
|
key = left.as<std::string>();
|
||||||
break;
|
break;
|
||||||
case sol::type::number:
|
case sol::type::number:
|
||||||
key = std::to_string(left.as<double>());
|
if (left.is<int>()) {
|
||||||
|
key = std::to_string(left.as<int>());
|
||||||
|
} else {
|
||||||
|
key = std::to_string(left.as<double>());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
beammp_assert_not_reachable();
|
beammp_assert_not_reachable();
|
||||||
@ -589,21 +597,30 @@ static void JsonEncodeRecursive(nlohmann::json& json, const sol::object& left, c
|
|||||||
case sol::type::string:
|
case sol::type::string:
|
||||||
value = right.as<std::string>();
|
value = right.as<std::string>();
|
||||||
break;
|
break;
|
||||||
case sol::type::number:
|
case sol::type::number: {
|
||||||
value = right.as<double>();
|
if (right.is<int>()) {
|
||||||
|
value = right.as<int>();
|
||||||
|
} else {
|
||||||
|
value = right.as<double>();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case sol::type::function:
|
case sol::type::function:
|
||||||
beammp_lua_warn("unsure what to do with function in JsonEncode, ignoring");
|
beammp_lua_warn("unsure what to do with function in JsonEncode, ignoring");
|
||||||
return;
|
return;
|
||||||
case sol::type::table: {
|
case sol::type::table: {
|
||||||
bool local_is_array = true;
|
if (right.as<sol::table>().empty()) {
|
||||||
for (const auto& pair : right.as<sol::table>()) {
|
value = nlohmann::json::object();
|
||||||
if (pair.first.get_type() != sol::type::number) {
|
} else {
|
||||||
local_is_array = false;
|
bool local_is_array = true;
|
||||||
|
for (const auto& pair : right.as<sol::table>()) {
|
||||||
|
if (pair.first.get_type() != sol::type::number) {
|
||||||
|
local_is_array = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto& pair : right.as<sol::table>()) {
|
||||||
|
JsonEncodeRecursive(value, pair.first, pair.second, local_is_array, depth + 1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for (const auto& pair : right.as<sol::table>()) {
|
|
||||||
JsonEncodeRecursive(value, pair.first, pair.second, local_is_array, depth + 1);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -620,14 +637,18 @@ static void JsonEncodeRecursive(nlohmann::json& json, const sol::object& left, c
|
|||||||
std::string LuaAPI::MP::JsonEncode(const sol::table& object) {
|
std::string LuaAPI::MP::JsonEncode(const sol::table& object) {
|
||||||
nlohmann::json json;
|
nlohmann::json json;
|
||||||
// table
|
// table
|
||||||
bool is_array = true;
|
if (object.as<sol::table>().empty()) {
|
||||||
for (const auto& pair : object.as<sol::table>()) {
|
json = nlohmann::json::object();
|
||||||
if (pair.first.get_type() != sol::type::number) {
|
} else {
|
||||||
is_array = false;
|
bool is_array = true;
|
||||||
|
for (const auto& pair : object.as<sol::table>()) {
|
||||||
|
if (pair.first.get_type() != sol::type::number) {
|
||||||
|
is_array = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto& entry : object) {
|
||||||
|
JsonEncodeRecursive(json, entry.first, entry.second, is_array);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for (const auto& entry : object) {
|
|
||||||
JsonEncodeRecursive(json, entry.first, entry.second, is_array);
|
|
||||||
}
|
}
|
||||||
return json.dump();
|
return json.dump();
|
||||||
}
|
}
|
||||||
|
66
test/Server/JsonTests/main.lua
Normal file
66
test/Server/JsonTests/main.lua
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
local function assert_eq(x, y, explain)
|
||||||
|
if x ~= y then
|
||||||
|
print("assertion '"..explain.."' failed:\n\tgot:\t", x, "\n\texpected:", y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param o1 any|table First object to compare
|
||||||
|
---@param o2 any|table Second object to compare
|
||||||
|
---@param ignore_mt boolean True to ignore metatables (a recursive function to tests tables inside tables)
|
||||||
|
function equals(o1, o2, ignore_mt)
|
||||||
|
if o1 == o2 then return true end
|
||||||
|
local o1Type = type(o1)
|
||||||
|
local o2Type = type(o2)
|
||||||
|
if o1Type ~= o2Type then return false end
|
||||||
|
if o1Type ~= 'table' then return false end
|
||||||
|
|
||||||
|
if not ignore_mt then
|
||||||
|
local mt1 = getmetatable(o1)
|
||||||
|
if mt1 and mt1.__eq then
|
||||||
|
--compare using built in method
|
||||||
|
return o1 == o2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local keySet = {}
|
||||||
|
|
||||||
|
for key1, value1 in pairs(o1) do
|
||||||
|
local value2 = o2[key1]
|
||||||
|
if value2 == nil or equals(value1, value2, ignore_mt) == false then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
keySet[key1] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
for key2, _ in pairs(o2) do
|
||||||
|
if not keySet[key2] then return false end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function assert_table_eq(x, y, explain)
|
||||||
|
if not equals(x, y, true) then
|
||||||
|
print("assertion '"..explain.."' failed:\n\tgot:\t", x, "\n\texpected:", y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_eq(Util.JsonEncode({1, 2, 3, 4, 5}), "[1,2,3,4,5]", "table to array")
|
||||||
|
assert_eq(Util.JsonEncode({"a", 1, 2, 3, 4, 5}), '["a",1,2,3,4,5]', "table to array")
|
||||||
|
assert_eq(Util.JsonEncode({"a", 1, 2.0, 3, 4, 5}), '["a",1,2.0,3,4,5]', "table to array")
|
||||||
|
assert_eq(Util.JsonEncode({hello="world", john={doe = 1, jane = 2.5, mike = {2, 3, 4}}, dave={}}), '{"dave":{},"hello":"world","john":{"doe":1,"jane":2.5,"mike":[2,3,4]}}', "table to obj")
|
||||||
|
assert_eq(Util.JsonEncode({a = nil}), "{}", "null obj member")
|
||||||
|
assert_eq(Util.JsonEncode({1, nil, 3}), "[1,3]", "null array member")
|
||||||
|
assert_eq(Util.JsonEncode({}), "{}", "empty array/table")
|
||||||
|
assert_eq(Util.JsonEncode({1234}), "[1234]", "int")
|
||||||
|
assert_eq(Util.JsonEncode({1234.0}), "[1234.0]", "double")
|
||||||
|
|
||||||
|
assert_table_eq(Util.JsonDecode("[1,2,3,4,5]"), {1, 2, 3, 4, 5}, "decode table to array")
|
||||||
|
assert_table_eq(Util.JsonDecode('["a",1,2,3,4,5]'), {"a", 1, 2, 3, 4, 5}, "decode table to array")
|
||||||
|
assert_table_eq(Util.JsonDecode('["a",1,2.0,3,4,5]'), {"a", 1, 2.0, 3, 4, 5}, "decode table to array")
|
||||||
|
assert_table_eq(Util.JsonDecode('{"dave":{},"hello":"world","john":{"doe":1,"jane":2.5,"mike":[2,3,4]}}'), {hello="world", john={doe = 1, jane = 2.5, mike = {2, 3, 4}}, dave={}}, "decode table to obj")
|
||||||
|
assert_table_eq(Util.JsonDecode("{}"), {a = nil}, "decode null obj member")
|
||||||
|
assert_table_eq(Util.JsonDecode("[1,3]"), {1, 3}, "decode null array member")
|
||||||
|
assert_table_eq(Util.JsonDecode("{}"), {}, "decode empty array/table")
|
||||||
|
assert_table_eq(Util.JsonDecode("[1234]"), {1234}, "decode int")
|
||||||
|
assert_table_eq(Util.JsonDecode("[1234.0]"), {1234.0}, "decode double")
|
Loading…
x
Reference in New Issue
Block a user