prep test/main.lua for running live unit tests

- make test config controllable via commandline params
- enable filtering by mode
- fix test filter code (it would misbehave if multiple filters were
  specified)
- allow done_command to have multiple tokens (before it could only be
  one word)
- remove preemptive check for the title screen. it is still checked when a
  test actually requires that the game is on the title screen
develop
myk002 2021-02-28 22:31:44 -08:00
parent 6d1bd62af9
commit b302289864
No known key found for this signature in database
GPG Key ID: 8A39CA0FA0C16E78
1 changed files with 63 additions and 11 deletions

@ -2,8 +2,41 @@ local json = require 'json'
local script = require 'gui.script' local script = require 'gui.script'
local utils = require 'utils' local utils = require 'utils'
local args = {...} local help_text =
local done_command = args[1] [[
Run DFHack tests.
Usage:
test/main [<options>] <post-test command>
Options:
-h, --help display this help message and exit.
-n, --nocache don't skip tests marked as completed in test_status.json.
-m, --modes only run tests in the given comma separated list of modes.
valid modes are 'none' and 'title'. if not specified, no
modes are filtered.
-t, --tests only run tests that match one of the comma separated list of
patterns. if not specified, no tests are filtered.
Examples:
test/main runs all tests that haven't been run before
test/main -n reruns all tests
test/main -nm none reruns tests that don't need the game to be in a
specific mode
test/main -nt quickfort reruns quickfort tests
]]
local help, nocache, mode_filter, test_filter = false, false, {}, {}
local done_command = utils.processArgsGetopt({...}, {
{'h', 'help', handler=function() help = true end},
{'n', 'nocache', handler=function() nocache = true end},
{'m', 'modes', hasArg=true,
handler=function(arg) mode_filter = arg:split(',') end},
{'t', 'tests', hasArg=true,
handler=function(arg) test_filter = arg:split(',') end},
})
if help then print(help_text) return end
local CONFIG_FILE = 'test_config.json' local CONFIG_FILE = 'test_config.json'
local STATUS_FILE = 'test_status.json' local STATUS_FILE = 'test_status.json'
@ -152,6 +185,10 @@ function load_test_config(config_file)
error('Invalid test folder: ' .. config.test_dir) error('Invalid test folder: ' .. config.test_dir)
end end
-- override config with any params specified on the commandline
if #mode_filter > 0 then config.modes = mode_filter end
if #test_filter > 0 then config.tests = test_filter end
return config return config
end end
@ -207,7 +244,7 @@ function get_test_files(test_dir)
end end
function load_test_status() function load_test_status()
if dfhack.filesystem.isfile(STATUS_FILE) then if not nocache and dfhack.filesystem.isfile(STATUS_FILE) then
return json.decode_file(STATUS_FILE) return json.decode_file(STATUS_FILE)
end end
end end
@ -218,7 +255,7 @@ end
function finish_tests() function finish_tests()
dfhack.internal.IN_TEST = false dfhack.internal.IN_TEST = false
if done_command then if #done_command > 0 then
dfhack.run_command(done_command) dfhack.run_command(done_command)
end end
end end
@ -305,8 +342,6 @@ function main()
} }
local passed = true local passed = true
ensure_title_screen()
print('Loading tests') print('Loading tests')
local tests = {} local tests = {}
for _, file in ipairs(files) do for _, file in ipairs(files) do
@ -316,15 +351,32 @@ function main()
end end
end end
if config.tests or config.modes then
print('Filtering tests') print('Filtering tests')
if config.tests then
local orig_length = #tests local orig_length = #tests
for i = #tests, 1, -1 do for i = #tests, 1, -1 do
local remove = false
if config.modes then
remove = true
-- allow test if it matches any of the given modes
for _, mode in pairs(config.modes) do
if tests[i].config.mode == mode then
remove = false
break
end
end
end
if config.tests and not remove then
remove = true
-- allow test if it matches any of the given patterns
for _, pattern in pairs(config.tests) do for _, pattern in pairs(config.tests) do
if not tests[i].name:match(pattern) then if tests[i].name:match(pattern) then
table.remove(tests, i) remove = false
break
end
end end
end end
if remove then table.remove(tests, i) end
end end
print('Selected tests: ' .. #tests .. '/' .. orig_length) print('Selected tests: ' .. #tests .. '/' .. orig_length)
end end