Files
plainleaf/client/space_lua/len_test.lua
T
Matouš Jan FialkaandGitHub 5a20a5f8f4 Space Lua: Align arithmetical error messages with Lua 5.4 (#1793)
* Space Lua: `<close>` attribute, `__close` metamethod and extensive tests

Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>

* Space Lua: Align arithmetical error messages with Lua 5.4

**Fixes:**

- Tighten `tonumber` semantics to accept hex floats like `0x1.2` while
  keeping plain hex as integers.

- Improve Lua compatibility by fixing relational `>`/`>=` operand
  ordering to preserve correct error type direction.

**Changes:**

- Update concatenation errors to include the operand type.

- Add `LuaStringCoercionError` from numeric coercion and handle it
  in `luaOp()` to emit correct messages (or fallback).

- Raise

  > `bad argument #2 to 'tonumber' (base out of range)`

  for invalid bases.

- Update test suite

**Notes:**

- The `arithmetic_test.lua` test suite now passes if run with Lua 5.4.

Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>

* Run `make fmt`

Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>

* Rename `assert_throws` to `assertThrows` in Lua test suite

Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>

* Replace `LuaStringCoercionError` class with sentinel constant

Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>

---------

Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
2026-01-29 08:04:27 +01: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 assertThrows(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
assertThrows(
"attempt to get length of a nil value",
function()
return #nil
end
)
assertThrows(
"attempt to get length of a number value",
function()
return #1
end
)
assertThrows(
"attempt to get length of a boolean value",
function()
return #false
end
)
assertThrows(
"attempt to get length of a function value",
function()
local f = function() end
return #f
end
)