dfhack/test/main.lua

173 lines
5.1 KiB
Lua

local script = require 'gui.script'
local utils = require 'utils'
local args = {...}
local done_command = args[1]
expect = {}
function expect.true_(value, comment)
return not not value, comment, 'expected true'
end
function expect.false_(value, comment)
return not value, comment, 'expected false'
end
function expect.eq(a, b, comment)
return a == b, comment, ('%s ~= %s'):format(a, b)
end
function expect.ne(a, b, comment)
return a ~= b, comment, ('%s == %s'):format(a, b)
end
function expect.error(func, ...)
local ok, ret = pcall(func, ...)
if ok then
return false, 'no error raised by function call'
else
return true
end
end
function delay(frames)
frames = frames or 1
script.sleep(frames, 'frames')
end
function build_test_env()
local env = {
test = utils.OrderedTable(),
expect = {},
delay = delay,
}
local private = {
checks = 0,
checks_ok = 0,
}
for name, func in pairs(expect) do
env.expect[name] = function(...)
private.checks = private.checks + 1
local ret = {func(...)}
local ok = table.remove(ret, 1)
local msg = ''
for _, part in pairs(ret) do
if part then
msg = msg .. ': ' .. tostring(part)
end
end
msg = msg:sub(3) -- strip leading ': '
if ok then
private.checks_ok = private.checks_ok + 1
else
dfhack.printerr('Check failed! ' .. (msg or '(no message)'))
local info = debug.getinfo(2)
dfhack.printerr((' at %s:%d'):format(info.short_src, info.currentline))
print('')
end
end
end
setmetatable(env, {__index = _G})
return env, private
end
function get_test_files()
local files = {}
for _, entry in ipairs(dfhack.filesystem.listdir_recursive(dfhack.getHackPath() .. 'test')) do
if not entry.isdir and not entry.path:match('main.lua') then
table.insert(files, entry.path)
end
end
table.sort(files)
return files
end
function set_test_stage(stage)
local f = io.open('test_stage.txt', 'w')
f:write(stage)
f:close()
end
function finish_tests(ok)
if ok then
print('Tests finished')
else
dfhack.printerr('Tests failed!')
end
if done_command then
dfhack.run_command(done_command)
end
end
function main()
local files = get_test_files()
local counts = {
tests = 0,
tests_ok = 0,
checks = 0,
checks_ok = 0,
file_errors = 0,
}
local passed = true
print('Looking for title screen...')
for i = 0, 100 do
local scr = dfhack.gui.getCurViewscreen()
if df.viewscreen_titlest:is_instance(scr) then
print('Found title screen')
break
else
scr:feed_key(df.interface_key.LEAVESCREEN)
delay(10)
end
end
if not df.viewscreen_titlest:is_instance(dfhack.gui.getCurViewscreen()) then
qerror('Could not find title screen')
end
print('Running tests')
for _, file in ipairs(files) do
print('Running file: ' .. file:sub(file:find('test'), -1))
local env, env_private = build_test_env()
local code, err = loadfile(file, 't', env)
if not code then
passed = false
counts.file_errors = counts.file_errors + 1
dfhack.printerr('Failed to load file: ' .. tostring(err))
else
local ok, err = pcall(code)
if not ok then
passed = false
counts.file_errors = counts.file_errors + 1
dfhack.printerr('Error when running file: ' .. tostring(err))
else
for name, test in pairs(env.test) do
env_private.checks = 0
env_private.checks_ok = 0
counts.tests = counts.tests + 1
local ok, err = pcall(test)
if not ok then
dfhack.printerr('test errored: ' .. name .. ': ' .. tostring(err))
passed = false
elseif env_private.checks ~= env_private.checks_ok then
dfhack.printerr('test failed: ' .. name)
passed = false
else
print('test passed: ' .. name)
counts.tests_ok = counts.tests_ok + 1
end
counts.checks = counts.checks + (tonumber(env_private.checks) or 0)
counts.checks_ok = counts.checks_ok + (tonumber(env_private.checks_ok) or 0)
end
end
end
end
print('\nTest summary:')
print(('%d/%d tests passed'):format(counts.tests_ok, counts.tests))
print(('%d/%d checks passed'):format(counts.checks_ok, counts.checks))
print(('%d test files failed to load'):format(counts.file_errors))
set_test_stage(passed and 'done' or 'fail')
finish_tests(passed)
end
script.start(main)