local M = { passed = 0, failed = 0, failures = {} } local current = '?' function M.describe(name, fn) current = name fn() end function M.it(name, fn) local ok, err = pcall(fn) if ok then M.passed = M.passed + 1 else M.failed = M.failed + 1 table.insert(M.failures, string.format('%s > %s\n %s', current, name, tostring(err))) end end local function render(v) if type(v) == 'table' then return vim.inspect(v) end return string.format('%q', tostring(v)) end function M.eq(expected, actual, msg) if not vim.deep_equal(expected, actual) then error(string.format('%sexpected %s, got %s', msg and (msg .. ': ') or '', render(expected), render(actual)), 2) end end function M.truthy(value, msg) if not value then error((msg or 'expected a truthy value') .. ', got ' .. render(value), 2) end end function M.falsy(value, msg) if value then error((msg or 'expected a falsy value') .. ', got ' .. render(value), 2) end end function M.matches(pattern, actual, msg) if type(actual) ~= 'string' or not actual:find(pattern) then error(string.format('%sexpected %s to match %q', msg and (msg .. ': ') or '', render(actual), pattern), 2) end end function M.report() for _, failure in ipairs(M.failures) do io.stderr:write('FAIL ' .. failure .. '\n') end io.stdout:write(string.format('\n%d passed, %d failed\n', M.passed, M.failed)) return M.failed == 0 end return M