mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-01 17:38:41 +00:00
Try to preserve metatable information in serialzed data
This commit is contained in:
parent
75dcd94b90
commit
24f0eb6bc1
5 changed files with 140 additions and 12 deletions
|
@ -4,6 +4,7 @@ _G.setfenv = require 'busted.compatibility'.setfenv
|
|||
|
||||
dofile("builtin/common/serialize.lua")
|
||||
dofile("builtin/common/vector.lua")
|
||||
dofile("builtin/common/metatable.lua")
|
||||
|
||||
-- Supports circular tables; does not support table keys
|
||||
-- Correctly checks whether a mapping of references ("same") exists
|
||||
|
@ -40,11 +41,32 @@ local t1, t2 = {x, x, y, y}, {x, y, x, y}
|
|||
assert.same(t1, t2) -- will succeed because it only checks whether the depths match
|
||||
assert(not pcall(assert_same, t1, t2)) -- will correctly fail because it checks whether the refs match
|
||||
|
||||
local pair_mt = {
|
||||
__eq = function(x, y)
|
||||
return x[1] == y[1] and x[2] == y[2]
|
||||
end,
|
||||
}
|
||||
local function pair(x, y)
|
||||
return setmetatable({x, y}, pair_mt)
|
||||
end
|
||||
-- Use our own serialization functions to avoid incorrectly passing test related to references.
|
||||
core.register_metatable("pair", pair_mt)
|
||||
assert.equals(pair(1, 2), pair(1, 2))
|
||||
assert.not_equals(pair(1, 2), pair(3, 4))
|
||||
|
||||
describe("serialize", function()
|
||||
local function assert_preserves(value)
|
||||
local preserved_value = core.deserialize(core.serialize(value))
|
||||
assert_same(value, preserved_value)
|
||||
end
|
||||
local function assert_strictly_preserves(value)
|
||||
local preserved_value = core.deserialize(core.serialize(value))
|
||||
assert.equals(value, preserved_value)
|
||||
end
|
||||
local function assert_compatibly_preserves(value)
|
||||
local preserved_value = loadstring(core.serialize(value))()
|
||||
assert_same(value, preserved_value)
|
||||
end
|
||||
it("works", function()
|
||||
assert_preserves({cat={sound="nyan", speed=400}, dog={sound="woof"}})
|
||||
end)
|
||||
|
@ -53,6 +75,10 @@ describe("serialize", function()
|
|||
assert_preserves({escape_chars="\n\r\t\v\\\"\'", non_european="θשׁ٩∂"})
|
||||
end)
|
||||
|
||||
it("handles nil", function()
|
||||
assert_strictly_preserves(nil)
|
||||
end)
|
||||
|
||||
it("handles NaN & infinities", function()
|
||||
local nan = core.deserialize(core.serialize(0/0))
|
||||
assert(nan ~= nan)
|
||||
|
@ -113,7 +139,10 @@ describe("serialize", function()
|
|||
it("vectors work", function()
|
||||
local v = vector.new(1, 2, 3)
|
||||
assert_preserves({v})
|
||||
assert_preserves(v)
|
||||
assert_compatibly_preserves({v})
|
||||
assert_strictly_preserves(v)
|
||||
assert_compatibly_preserves(v)
|
||||
assert(core.deserialize(core.serialize(v)):check())
|
||||
|
||||
-- abuse
|
||||
v = vector.new(1, 2, 3)
|
||||
|
@ -121,6 +150,43 @@ describe("serialize", function()
|
|||
assert_preserves(v)
|
||||
end)
|
||||
|
||||
it("correctly handles typed objects with multiple references", function()
|
||||
local x, y = pair(1, 2), pair(1, 2)
|
||||
local t = core.deserialize(core.serialize{x, x, y})
|
||||
assert.equals(x, t[1])
|
||||
assert.equals(x, t[3])
|
||||
assert(rawequal(t[1], t[2]))
|
||||
assert(not rawequal(t[1], t[3]))
|
||||
end)
|
||||
|
||||
it("correctly handles recursive typed objects with the identity function as serializer", function()
|
||||
local mt = {
|
||||
__eq = function(x, y)
|
||||
return x[1] == y[1]
|
||||
end,
|
||||
}
|
||||
core.register_metatable("test_recursive_typed", mt)
|
||||
local t = setmetatable({1}, mt)
|
||||
t[2] = t
|
||||
assert_strictly_preserves(t)
|
||||
end)
|
||||
|
||||
it("correctly handles binary trees", function()
|
||||
local child = {pair(1, 1)}
|
||||
local layers = 4
|
||||
for i = 2, layers do
|
||||
child[i] = pair(child[i-1], child[i-1])
|
||||
end
|
||||
local tree = child[layers]
|
||||
assert_strictly_preserves(tree)
|
||||
local node = core.deserialize(core.serialize(tree))
|
||||
for i = 2, layers do
|
||||
assert(rawequal(node[1], node[2]))
|
||||
node = node[1]
|
||||
end
|
||||
assert_compatibly_preserves(tree)
|
||||
end)
|
||||
|
||||
it("handles keywords as keys", function()
|
||||
assert_preserves({["and"] = "keyword", ["for"] = "keyword"})
|
||||
end)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue