You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
3.8 KiB
Lua
145 lines
3.8 KiB
Lua
--- `assert_` macro library support.
|
|
-- This module may of course be used on its own; `assert_` merely provides
|
|
-- some syntactical sugar for its functionality. It is based on Penlight's
|
|
-- `pl.test` module.
|
|
-- @module macro.libs.test
|
|
|
|
local test = {}
|
|
|
|
local _eq,_tostring
|
|
|
|
-- very much like tablex.deepcompare from Penlight
|
|
function _eq (v1,v2)
|
|
if type(v1) ~= type(v2) then return false end
|
|
-- if the value isn't a table, or it has defined the equality operator..
|
|
local mt = getmetatable(v1)
|
|
if (mt and mt.__eq) or type(v1) ~= 'table' then
|
|
return v1 == v2
|
|
end
|
|
-- both values are plain tables
|
|
if v1 == v2 then return true end -- they were the same table...
|
|
for k1,x1 in pairs(v1) do
|
|
local x2 = v2[k1]
|
|
if x2 == nil or not _eq(x1,x2) then return false end
|
|
end
|
|
for k2,x2 in pairs(v2) do
|
|
local x1 = v1[k2]
|
|
if x1 == nil or not _eq(x1,x2) then return false end
|
|
end
|
|
return true
|
|
end
|
|
|
|
local function keyv (k)
|
|
if type(k) ~= 'string' then
|
|
k = '['..k..']'
|
|
end
|
|
return k
|
|
end
|
|
|
|
function _tostring (val)
|
|
local mt = getmetatable(val)
|
|
if (mt and mt.__tostring) or type(val) ~= 'table' then
|
|
if type(val) == 'string' then
|
|
return '"'..tostring(val)..'"'
|
|
else
|
|
return tostring(val)
|
|
end
|
|
end
|
|
-- dump the table; doesn't need to be pretty!
|
|
local res = {}
|
|
local function put(s) res[#res+1] = s end
|
|
put '{'
|
|
for k,v in pairs(val) do
|
|
put(keyv(k)..'=')
|
|
put(_tostring(v))
|
|
put ','
|
|
end
|
|
table.remove(res) -- remove last ','
|
|
put '}'
|
|
return table.concat(res)
|
|
end
|
|
|
|
local function _lt (v1,v2) return v1 < v2 end
|
|
local function _gt (v1,v2) return v1 > v2 end
|
|
local function _match (v1,v2) return v1:match(v2) end
|
|
|
|
local function _assert (v1,v2,cmp,msg)
|
|
if not cmp(v1,v2) then
|
|
print('first:',_tostring(v1))
|
|
print(msg)
|
|
print('second:',_tostring(v2))
|
|
error('assertion failed',3)
|
|
end
|
|
end
|
|
|
|
--- assert if parameters are not equal. If the values are tables,
|
|
-- they will be compared by value.
|
|
-- @param v1 given value
|
|
-- @param v2 test value
|
|
function test.assert_eq (v1,v2)
|
|
_assert(v1,v2,_eq,"is not equal to");
|
|
end
|
|
|
|
--- assert if first parameter is not less than second.
|
|
-- @param v1 given value
|
|
-- @param v2 test value
|
|
function test.assert_lt (v1,v2)
|
|
_assert(v1,v2,_lt,"is not less than")
|
|
end
|
|
|
|
--- assert if first parameter is not greater than second.
|
|
-- @param v1 given value
|
|
-- @param v2 test value
|
|
function test.assert_gt (v1,v2)
|
|
_assert(v1,v2,_gt,"is not greater than")
|
|
end
|
|
|
|
--- assert if first parameter string does not match the second.
|
|
-- The condition is `v1:match(v2)`.
|
|
-- @param v1 given value
|
|
-- @param v2 test value
|
|
function test.assert_match (v1,v2)
|
|
_assert(v1,v2,_match,"does not match")
|
|
end
|
|
|
|
-- return the error message from a function that raises an error.
|
|
-- Will raise an error if the function did not raise an error.
|
|
-- @param fun the function
|
|
-- @param ... any arguments to the function
|
|
-- @return the error message
|
|
function test.pcall_no(fun,...)
|
|
local ok,err = pcall(fun,...)
|
|
if ok then error('expression did not throw error',3) end
|
|
return err
|
|
end
|
|
|
|
local tuple = {}
|
|
|
|
function tuple.__eq (a,b)
|
|
if a.n ~= b.n then return false end
|
|
for i=1, a.n do
|
|
if not _eq(a[i],b[i]) then return false end
|
|
end
|
|
return true
|
|
end
|
|
|
|
function tuple.__tostring (self)
|
|
local ts = {}
|
|
for i = 1,self.n do
|
|
ts[i] = _tostring(self[i])
|
|
end
|
|
return '('..table.concat(ts,',')..')'
|
|
end
|
|
|
|
--- create a tuple capturing multiple return values.
|
|
-- Equality between tuples means that all of their values are equal;
|
|
-- values may be `nil`
|
|
-- @param ... any values
|
|
-- @return a tuple object
|
|
function test.tuple(...)
|
|
return setmetatable({n=select('#',...),...},tuple)
|
|
end
|
|
|
|
return test
|
|
|