Files
plainleaf/client/space_lua/len_test.lua
T
Matouš Jan FialkaandGitHub 9292ae4b74 Space Lua: Align length features with standard Lua (#1637)
* Align `#` operator and `__len` metamethod with Lua and add `rawlen` function

Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
2025-10-21 09:55:38 +02:00

107 lines
1.8 KiB
Lua

local function assert_eq(actual, expected, msg)
if actual ~= expected then
error('assert_eq failed: ' .. msg)
end
end
local function assert_throws(substr, fn)
local ok, err = pcall(fn)
if ok then
error("expected error containing: " .. substr)
end
err = tostring(err)
if not string.find(err, substr, 1, true) then
error("error message mismatch: got: " .. err)
end
end
-- 1. Strings: raw length, ignore metamethods
assert_eq(#"", 0, "empty string length")
assert_eq(#"abc", 3, "string length")
-- 2. Tables (raw length for sequence or `__len`)
assert_eq(#{}, 0, "empty table length")
assert_eq(#{1,2,3}, 3, "array length")
do
local t = {}
setmetatable(t,
{
__len = function(_)
return 42
end,
})
assert_eq(#t, 42, "__len should override raw table length")
end
-- 2.1. Metamethod result handling
do
local t = {}
setmetatable(t,
{
__len = function(_)
return 42, 1, 2, 3
end,
})
assert_eq(#t, 42, "__len must use only first return value")
end
-- 2.2. Raw length when no array part
do
local t = {
a = 1,
b = 2,
}
assert_eq(#t, 0, "table with only non-integer keys has length 0")
end
-- 2.3. Length when both array and key-value parts
do
local t = {
a = 1,
b = 2,
1,
2,
c = 3,
3,
}
assert_eq(#t, 3, "table with mixed non-integer and integer keys")
end
-- 3. Non-strings and non-tables
assert_throws(
"attempt to get length of a nil value",
function()
return #nil
end
)
assert_throws(
"attempt to get length of a number value",
function()
return #1
end
)
assert_throws(
"attempt to get length of a boolean value",
function()
return #false
end
)
assert_throws(
"attempt to get length of a function value",
function()
local f = function() end
return #f
end
)