From cd2c24b9c3aab745344fe2de6a6cb805d7d6f23b Mon Sep 17 00:00:00 2001 From: Alistair-Afton Date: Thu, 17 Sep 2026 19:22:48 +0200 Subject: [PATCH] test: add in-game regression tests for five more plugins Covers reveal, dwarfvet, cleaners, cleanconst, and cleanowned: map reveal/unreveal/revtoggle hidden-flag round-trips, dwarfvet status/checkup, clean subcommand coverage and usage errors, and cleanowned dry-run scans. --- test/plugins/cleanconst.lua | 11 ++++++ test/plugins/cleaners.lua | 48 +++++++++++++++++++++++ test/plugins/cleanowned.lua | 20 ++++++++++ test/plugins/dwarfvet.lua | 42 ++++++++++++++++++++ test/plugins/reveal.lua | 78 +++++++++++++++++++++++++++++++++++++ 5 files changed, 199 insertions(+) create mode 100644 test/plugins/cleanconst.lua create mode 100644 test/plugins/cleaners.lua create mode 100644 test/plugins/cleanowned.lua create mode 100644 test/plugins/dwarfvet.lua create mode 100644 test/plugins/reveal.lua diff --git a/test/plugins/cleanconst.lua b/test/plugins/cleanconst.lua new file mode 100644 index 0000000000..3d06657b18 --- /dev/null +++ b/test/plugins/cleanconst.lua @@ -0,0 +1,11 @@ +config.mode = 'fortress' +config.target = 'cleanconst' + +-- cleanconst scans all items for bogus construction flags. On a healthy map +-- it cleans nothing but still prints its summary; the value here is +-- exercising the full item scan for crashes. +function test.clean_run() + local output, status = dfhack.run_command_silent('cleanconst') + expect.eq(CR_OK, status) + expect.str_find('Done%. %d+ construction items cleaned up%.', output) +end diff --git a/test/plugins/cleaners.lua b/test/plugins/cleaners.lua new file mode 100644 index 0000000000..1136e69634 --- /dev/null +++ b/test/plugins/cleaners.lua @@ -0,0 +1,48 @@ +config.mode = 'fortress' +config.target = 'cleaners' + +-- the plugin's command is `clean` (the plugin binary is named cleaners). +-- each subcommand prints a summary only when it actually removed something, +-- so on a clean map the output is empty but the status is still CR_OK. + +local function expect_clean_ok(output, status, pattern) + expect.eq(CR_OK, status) + if #output > 0 then + expect.str_find(pattern, output) + end +end + +function test.clean_map() + local output, status = dfhack.run_command_silent('clean', 'map') + expect_clean_ok(output, status, 'Cleaned %d+ of %d+ map blocks%.') +end + +function test.clean_units() + local output, status = dfhack.run_command_silent('clean', 'units') + expect_clean_ok(output, status, 'Removed %d+ contaminants from %d+ creatures%.') +end + +function test.clean_items() + local output, status = dfhack.run_command_silent('clean', 'items') + expect_clean_ok(output, status, 'Removed %d+ contaminants from %d+ items%.') +end + +function test.clean_plants() + local output, status = dfhack.run_command_silent('clean', 'plants') + expect_clean_ok(output, status, 'Removed %d+ contaminants from %d+ plants%.') +end + +function test.clean_all() + local _, status = dfhack.run_command_silent('clean', 'all') + expect.eq(CR_OK, status) +end + +function test.no_args_is_wrong_usage() + local _, status = dfhack.run_command_silent('clean') + expect.eq(CR_WRONG_USAGE, status) +end + +function test.unknown_option_is_wrong_usage() + local _, status = dfhack.run_command_silent('clean', 'bogus') + expect.eq(CR_WRONG_USAGE, status) +end diff --git a/test/plugins/cleanowned.lua b/test/plugins/cleanowned.lua new file mode 100644 index 0000000000..78e4fc28a6 --- /dev/null +++ b/test/plugins/cleanowned.lua @@ -0,0 +1,20 @@ +config.mode = 'fortress' +config.target = 'cleanowned' + +-- `cleanowned dryrun` scans all owned items on the map and prints what it +-- would confiscate without mutating anything; the value here is exercising +-- the full item scan plus the per-item report path. +function test.dryrun_is_side_effect_free() + local _, status = dfhack.run_command_silent('cleanowned', 'dryrun') + expect.eq(CR_OK, status) +end + +function test.dryrun_with_filters() + local _, status = dfhack.run_command_silent('cleanowned', 'dryrun', 'scattered', 'x', 'X', 'all', 'nodump') + expect.eq(CR_OK, status) +end + +function test.unknown_option_is_wrong_usage() + local _, status = dfhack.run_command_silent('cleanowned', 'bogus') + expect.eq(CR_WRONG_USAGE, status) +end diff --git a/test/plugins/dwarfvet.lua b/test/plugins/dwarfvet.lua new file mode 100644 index 0000000000..6e454a77d4 --- /dev/null +++ b/test/plugins/dwarfvet.lua @@ -0,0 +1,42 @@ +config.mode = 'fortress' +config.target = 'dwarfvet' + +local function status_output() + local output, status = dfhack.run_command_silent('dwarfvet', 'status') + expect.eq(CR_OK, status) + return output +end + +function test.status_reports_state_and_patients() + dfhack.run_command_silent('disable', 'dwarfvet') + local output = status_output() + expect.str_find('dwarfvet is not running', output) + expect.str_find('The following animals are receiving treatment:', output) + + dfhack.run_command_silent('enable', 'dwarfvet') + output = status_output() + expect.str_find('dwarfvet is running', output) + dfhack.run_command_silent('disable', 'dwarfvet') +end + +function test.bare_command_is_status() + local output, status = dfhack.run_command_silent('dwarfvet') + expect.eq(CR_OK, status) + expect.str_find('dwarfvet is ', output) +end + +function test.unknown_command_is_wrong_usage() + local _, status = dfhack.run_command_silent('dwarfvet', 'bogus') + expect.eq(CR_WRONG_USAGE, status) +end + +function test.now_runs_checkup() + -- checkup scans hospital zones and animal patients; safe on any fort + dfhack.run_command_silent('enable', 'dwarfvet') + return dfhack.with_finalize(function() + dfhack.run_command_silent('disable', 'dwarfvet') + end, function() + local _, status = dfhack.run_command_silent('dwarfvet', 'now') + expect.eq(CR_OK, status) + end) +end diff --git a/test/plugins/reveal.lua b/test/plugins/reveal.lua new file mode 100644 index 0000000000..7c9fe6a45f --- /dev/null +++ b/test/plugins/reveal.lua @@ -0,0 +1,78 @@ +config.mode = 'fortress' +config.target = 'reveal' + +-- reveal/unreveal mutate every map block's hidden flag, and the plugin +-- force-pauses the game while the map is revealed. Every test that reveals +-- must unreveal in a finalize so a failed check can't leave the game +-- revealed (and stuck paused) for the rest of the suite. +local function ensure_unrevealed() + dfhack.run_command_silent('unreveal') +end + +local function count_hidden() + local count = 0 + for _, block in ipairs(df.global.world.map.map_blocks) do + for x = 0, 15 do + for y = 0, 15 do + if block.designation[x][y].hidden then + count = count + 1 + end + end + end + end + return count +end + +function test.reveal_and_unreveal() + local before = count_hidden() + expect.true_(before > 0, 'test needs at least one hidden tile on the map') + + return dfhack.with_finalize(ensure_unrevealed, function() + local output, status = dfhack.run_command_silent('reveal') + expect.eq(CR_OK, status) + expect.str_find('Map revealed%.', output) + -- blocks containing trigger events (encased horrors, treasure veins) + -- stay hidden by design, so compare counts rather than spot tiles + expect.lt(count_hidden(), before) + + output, status = dfhack.run_command_silent('unreveal') + expect.eq(CR_OK, status) + expect.eq(before, count_hidden()) + end) +end + +function test.reveal_twice_fails() + return dfhack.with_finalize(ensure_unrevealed, function() + dfhack.run_command_silent('reveal') + local output, status = dfhack.run_command_silent('reveal') + expect.eq(CR_FAILURE, status) + expect.str_find('already revealed', output) + end) +end + +function test.unreveal_nothing_fails() + local output, status = dfhack.run_command_silent('unreveal') + expect.eq(CR_FAILURE, status) + expect.str_find('nothing to revert', output) +end + +function test.demon_is_disabled() + local output, status = dfhack.run_command_silent('reveal', 'demon') + expect.eq(CR_FAILURE, status) + expect.str_find('currently disabled', output) +end + +function test.revtoggle_toggles() + local before = count_hidden() + expect.true_(before > 0, 'test needs at least one hidden tile on the map') + + return dfhack.with_finalize(ensure_unrevealed, function() + local _, status = dfhack.run_command_silent('revtoggle') + expect.eq(CR_OK, status) + expect.lt(count_hidden(), before) + + _, status = dfhack.run_command_silent('revtoggle') + expect.eq(CR_OK, status) + expect.eq(before, count_hidden()) + end) +end