Merge branch 'myk_move_main' into develop

develop
lethosor 2021-03-24 22:07:21 -04:00
commit 2249b32ef0
No known key found for this signature in database
GPG Key ID: 76A269552F4F58C1
6 changed files with 161 additions and 135 deletions

@ -503,6 +503,7 @@ if(BUILD_TESTS)
endif()
install(DIRECTORY ${dfhack_SOURCE_DIR}/test
DESTINATION ${DFHACK_DATA_DESTINATION}/scripts)
install(FILES ci/test.lua DESTINATION ${DFHACK_DATA_DESTINATION}/scripts)
endif()
# Packaging with CPack!

@ -1,6 +1,7 @@
-- DFHack developer test harness
--@ module = true
local expect = require 'test.expect'
local json = require 'json'
local script = require 'gui.script'
local utils = require 'utils'
@ -8,14 +9,14 @@ local utils = require 'utils'
local help_text =
[====[
test/main
=========
test
====
Run DFHack tests.
Usage:
test/main [<options>] [<done_command>]
test [<options>] [<done_command>]
If a done_command is specified, it will be run after the tests complete.
@ -35,14 +36,13 @@ Options:
Examples:
test/main runs all tests
test/main -r runs all tests that haven't been run before
test/main -m none runs tests that don't need the game to be in a
specific mode
test/main -t quickfort runs quickfort tests
test/main -d /path/to/dfhack-scripts/repo/test
runs tests in your in-development branch of the
scripts repo
test runs all tests
test -r runs all tests that haven't been run before
test -m none runs tests that don't need the game to be in a
specific mode
test -t quickfort runs quickfort tests
test -d /path/to/dfhack-scripts/repo/test
runs tests in your dev scripts repo
Default values for the options may be set in a file named test_config.json in
your DF folder. Options with comma-separated values should be written as json
@ -67,127 +67,6 @@ local TestStatus = {
local VALID_MODES = utils.invert{'none', 'title', 'fortress'}
expect = {}
function expect.true_(value, comment)
return not not value, comment, 'expected true, got ' .. tostring(value)
end
function expect.false_(value, comment)
return not value, comment, 'expected false, got ' .. tostring(value)
end
function expect.fail(comment)
return false, comment or 'check failed, no reason provided'
end
function expect.nil_(value, comment)
return value == nil, comment, 'expected nil, got ' .. tostring(value)
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.lt(a, b, comment)
return a < b, comment, ('%s >= %s'):format(a, b)
end
function expect.le(a, b, comment)
return a <= b, comment, ('%s > %s'):format(a, b)
end
function expect.gt(a, b, comment)
return a > b, comment, ('%s <= %s'):format(a, b)
end
function expect.ge(a, b, comment)
return a >= b, comment, ('%s < %s'):format(a, b)
end
local function table_eq_recurse(a, b, keys, known_eq)
if a == b then return true end
local checked = {}
for k,v in pairs(a) do
if type(a[k]) == 'table' then
if known_eq[a[k]] and known_eq[a[k]][b[k]] then goto skip end
table.insert(keys, tostring(k))
if type(b[k]) ~= 'table' then
return false, keys, {tostring(a[k]), tostring(b[k])}
end
if not known_eq[a[k]] then known_eq[a[k]] = {} end
for eq_tab,_ in pairs(known_eq[a[k]]) do
known_eq[eq_tab][b[k]] = true
end
known_eq[a[k]][b[k]] = true
if not known_eq[b[k]] then known_eq[b[k]] = {} end
for eq_tab,_ in pairs(known_eq[b[k]]) do
known_eq[eq_tab][a[k]] = true
end
known_eq[b[k]][a[k]] = true
local matched, keys_at_diff, diff =
table_eq_recurse(a[k], b[k], keys, known_eq)
if not matched then return false, keys_at_diff, diff end
keys[#keys] = nil
elseif a[k] ~= b[k] then
table.insert(keys, tostring(k))
return false, keys, {tostring(a[k]), tostring(b[k])}
end
::skip::
checked[k] = true
end
for k in pairs(b) do
if not checked[k] then
table.insert(keys, tostring(k))
return false, keys, {tostring(a[k]), tostring(b[k])}
end
end
return true
end
function expect.table_eq(a, b, comment)
if (type(a) ~= 'table' and type(a) ~= 'userdata') or
(type(b) ~= 'table' and type(b) ~= 'userdata') then
return false, comment, 'operands to table_eq must be tables or userdata'
end
local keys, known_eq = {}, {}
local matched, keys_at_diff, diff = table_eq_recurse(a, b, keys, known_eq)
if matched then return true end
local keystr = '['..keys_at_diff[1]..']'
for i=2,#keys_at_diff do keystr = keystr..'['..keys_at_diff[i]..']' end
return false, comment,
('key %s: "%s" ~= "%s"'):format(keystr, diff[1], diff[2])
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 expect.error_match(func, matcher, ...)
local ok, err = pcall(func, ...)
if ok then
return false, 'no error raised by function call'
elseif type(matcher) == 'string' then
if not tostring(err):match(matcher) then
return false, ('error "%s" did not match "%s"'):format(err, matcher)
end
elseif not matcher(err) then
return false, ('error "%s" did not satisfy matcher'):format(err)
end
return true
end
function expect.pairs_contains(table, key, comment)
for k, v in pairs(table) do
if k == key then
return true
end
end
return false, comment, ('could not find key "%s" in table'):format(key)
end
function expect.not_pairs_contains(table, key, comment)
for k, v in pairs(table) do
if k == key then
return false, comment, ('found key "%s" in table'):format(key)
end
end
return true
end
local function delay(frames)
frames = frames or 1
script.sleep(frames, 'frames')
@ -285,7 +164,7 @@ local function get_test_files(test_dir)
local files = {}
print('Loading tests from ' .. test_dir)
for _, entry in ipairs(dfhack.filesystem.listdir_recursive(test_dir)) do
if not entry.isdir and not entry.path:match('main.lua') then
if not entry.isdir then
table.insert(files, entry.path)
end
end

@ -38,6 +38,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
## Internals
- The DFHack test harness is now much easier to use for iterative development. Configuration can now be specified on the commandline, there are more test filter options, and the test harness can now easily rerun tests that have been run before.
- The ``test/main`` command to invoke the test harness has been renamed to just ``test``
# 0.47.05-r1

@ -0,0 +1,145 @@
-- Internal implementations of expect.*() functions for tests
-- NOTE: do not use this module in tests directly! The test wrapper (ci/test.lua)
-- wraps these functions to track which tests have passed/failed, and calling
-- these functions directly will not work as expected.
local expect = mkmodule('test.expect')
function expect.true_(value, comment)
return not not value, comment, 'expected true, got ' .. tostring(value)
end
function expect.false_(value, comment)
return not value, comment, 'expected false, got ' .. tostring(value)
end
function expect.fail(comment)
return false, comment or 'check failed, no reason provided'
end
function expect.nil_(value, comment)
return value == nil, comment, 'expected nil, got ' .. tostring(value)
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.lt(a, b, comment)
return a < b, comment, ('%s >= %s'):format(a, b)
end
function expect.le(a, b, comment)
return a <= b, comment, ('%s > %s'):format(a, b)
end
function expect.gt(a, b, comment)
return a > b, comment, ('%s <= %s'):format(a, b)
end
function expect.ge(a, b, comment)
return a >= b, comment, ('%s < %s'):format(a, b)
end
local function table_eq_recurse(a, b, keys, known_eq)
if a == b then return true end
local checked = {}
for k,v in pairs(a) do
if type(a[k]) == 'table' then
if known_eq[a[k]] and known_eq[a[k]][b[k]] then goto skip end
table.insert(keys, tostring(k))
if type(b[k]) ~= 'table' then
return false, keys, {tostring(a[k]), tostring(b[k])}
end
if not known_eq[a[k]] then known_eq[a[k]] = {} end
for eq_tab,_ in pairs(known_eq[a[k]]) do
known_eq[eq_tab][b[k]] = true
end
known_eq[a[k]][b[k]] = true
if not known_eq[b[k]] then known_eq[b[k]] = {} end
for eq_tab,_ in pairs(known_eq[b[k]]) do
known_eq[eq_tab][a[k]] = true
end
known_eq[b[k]][a[k]] = true
local matched, keys_at_diff, diff =
table_eq_recurse(a[k], b[k], keys, known_eq)
if not matched then return false, keys_at_diff, diff end
keys[#keys] = nil
elseif a[k] ~= b[k] then
table.insert(keys, tostring(k))
return false, keys, {tostring(a[k]), tostring(b[k])}
end
::skip::
checked[k] = true
end
for k in pairs(b) do
if not checked[k] then
table.insert(keys, tostring(k))
return false, keys, {tostring(a[k]), tostring(b[k])}
end
end
return true
end
function expect.table_eq(a, b, comment)
if (type(a) ~= 'table' and type(a) ~= 'userdata') or
(type(b) ~= 'table' and type(b) ~= 'userdata') then
return false, comment, 'operands to table_eq must be tables or userdata'
end
local keys, known_eq = {}, {}
local matched, keys_at_diff, diff = table_eq_recurse(a, b, keys, known_eq)
if matched then return true end
local keystr = '['..keys_at_diff[1]..']'
for i=2,#keys_at_diff do keystr = keystr..'['..keys_at_diff[i]..']' end
return false, comment,
('key %s: "%s" ~= "%s"'):format(keystr, diff[1], diff[2])
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 expect.error_match(func, matcher, ...)
local ok, err = pcall(func, ...)
if ok then
return false, 'no error raised by function call'
elseif type(matcher) == 'string' then
if not tostring(err):match(matcher) then
return false, ('error "%s" did not match "%s"'):format(err, matcher)
end
elseif not matcher(err) then
return false, ('error "%s" did not satisfy matcher'):format(err)
end
return true
end
function expect.pairs_contains(table, key, comment)
for k, v in pairs(table) do
if k == key then
return true
end
end
return false, comment, ('could not find key "%s" in table'):format(key)
end
function expect.not_pairs_contains(table, key, comment)
for k, v in pairs(table) do
if k == key then
return false, comment, ('found key "%s" in table'):format(key)
end
end
return true
end
return expect

@ -1,4 +1,4 @@
local expect_raw = reqscript('test/main').expect
local expect_raw = require('test.expect')
function test.internal_in_test()
expect.true_(dfhack.internal.IN_TEST)

@ -73,7 +73,7 @@ with open(test_init_file, 'w') as f:
f.write('''
devel/dump-rpc dfhack-rpc.txt
:lua dfhack.internal.addScriptPath(dfhack.getHackPath())
test/main --resume "lua scr.breakdown_level=df.interface_breakdown_types.%s"
test --resume "lua scr.breakdown_level=df.interface_breakdown_types.%s"
''' % ('NONE' if args.no_quit else 'QUIT'))
test_config_file = 'test_config.json'