local print = print local output = {} function _G.print(...) local args = {...} for i, v in ipairs(args) do args[i] = tostring(v) end table.insert(output, table.concat(args, " ")) end local function test_pcall(fn) return xpcall(fn, function(msg) return debug.traceback(msg), msg end) end function love.errorhandler(msg) print(msg) love.event.quit() end global "assert_error" function assert_error(fn, ...) local ok, traceback, err = test_pcall(fn, ...) if ok then error("expected error to occur", 2) end end local function print_output(name, traceback, output) local function log(msg) if msg:sub(#msg, #msg) ~= '\n' then msg = msg .. '\n' end for l in msg:gmatch '(.-)\n' do print("["..name.."] "..l) end end for _, msg in ipairs(output) do log(msg) end log(traceback) end local test_results = {} local passed = 0 local failed = 0 local function test(name, fn) if not test_results[fn] then local ok, traceback, err = test_pcall(fn) if not ok then failed = failed + 1 test_results[fn] = {ok, output, err, traceback} print_output(name, traceback, output) else passed = passed + 1 test_results[fn] = {ok, output} end end output = {} return unpack(test_results[fn]) end for _, mod_name in ipairs({...}) do local mod = require("tests."..mod_name) for name, fn in pairs(mod) do test(mod_name.."."..name, fn) end end if failed > 0 then print(failed.." tests FAILED.") end print(passed.." tests passed.") love.event.quit()