test: cover tests.examineMonsterReportsADiseaseCaughtThroughInfighting

This commit is contained in:
dualfroz committed 2026-09-13 13:50:00 +02:00
1 parent 9fc53e4ef4
commit 69dd449825
1 file changed
+173
+173
View File
@@ -13452,6 +13452,179 @@ function tests.examineMonsterListsActiveStatusEffectsWithRemainingDuration()
"the report lists the active status and its remaining duration")
end
-- Only reachable through infighting.lua's own bite chance (a rival monster
-- or the player's own companion/hireling/thrall can now catch a disease
-- from a carrier's bite, see infightingStrikeCanTransmitTheAttackersBite
-- DiseaseToAnyDefenderNotJustThePlayer above) - shown the same way the
-- afflicted-statuses line just above already surfaces a fact invisible on
-- the bare map glyph.
function tests.examineMonsterReportsADiseaseCaughtThroughInfighting()
local game = stagedGame(1, arena(21, 11), 5, 5)
local orc = Monsters.create(Monsters.byKey.orc, 1, 8, 5, 1)
ok(not contains(Examine.monster(game.player, orc), "diseased"), "a healthy monster's report mentions no disease")
Disease.infect(orc, Disease.PLAGUE)
ok(contains(Examine.monster(game.player, orc), "diseased: black plague (incubating)"),
"an incubating infection shows up in a monster's examine report")
orc.disease.stage = 1
ok(contains(Examine.monster(game.player, orc), "diseased: black plague (stage 1)"),
"an erupted infection reports its current stage in a monster's examine report")
end
-- commands.lua: `examine <n>`/`examine monster <n>`, the interface half of
-- examine.lua a typed session reaches through.
function tests.commandsApplyExamineDescribesAnInventoryItemWithoutSpendingATurn()
local game = stagedGame(1, arena(21, 11), 5, 5)
game.player.inventory = { Items.weapon("dagger", 3) }
local turnBefore = game.turn
local consumesTurn, message = Commands.apply(game, "examine 1")
eq(consumesTurn, false, "examine never spends a turn")
eq(game.turn, turnBefore, "the turn counter stays put")
ok(contains(message, "dagger") and contains(message, "power 3"), "the report describes the inventory item")
local aliased = Commands.apply(game, "x 1")
eq(aliased, false, "the x alias behaves identically and never spends a turn")
end
function tests.commandsApplyExamineMonsterDescribesTheSameEntryLookJustNumbered()
local game = stagedGame(1, arena(21, 11), 5, 5)
local rat = Monsters.create(Monsters.byKey.rat, 1, 8, 5, 1)
local orc = Monsters.create(Monsters.byKey.orc, 2, 9, 6, 1)
game.level.entities = { rat, orc }
local _, lookMessage = Commands.apply(game, "look")
ok(contains(lookMessage, "1) " .. rat.name), "look numbers the rat first")
ok(contains(lookMessage, "2) " .. orc.name), "look numbers the orc second")
local consumesTurn, examineMessage = Commands.apply(game, "examine monster 2")
eq(consumesTurn, false, "examining a monster never spends a turn")
ok(contains(examineMessage, orc.name), "examine monster 2 describes the same monster look numbered 2")
end
function tests.commandsApplyExamineFailsCleanlyOnBadOrMissingArgumentsWithoutSpendingATurn()
local game = stagedGame(1, arena(21, 11), 5, 5)
eq(Commands.apply(game, "examine"), false, "examine with no argument spends no turn")
eq(Commands.apply(game, "examine 1"), false, "examining an empty inventory slot spends no turn")
eq(Commands.apply(game, "examine monster"), false, "examine monster with no index spends no turn")
eq(Commands.apply(game, "examine monster 1"), false, "examining with nothing in sight spends no turn")
end
function tests.commandsApplyHelpMentionsExamine()
local game = stagedGame(1, arena(21, 11), 5, 5)
local _, message = Commands.apply(game, "help")
ok(contains(message, "examine"), "help mentions examine")
end
-- commands.lua: crafting/economy verbs (forge/merge/socket/socketrune/
-- temper/enchant/disenchant/repair/steal/dismiss/learn/brew), the interface
-- half of the API a typed session could not reach before this session.
function tests.commandsApplyForgeAndMergeDriveTheGemPipelineAndSpendTheTurn()
local game = stagedGame(1, arena(21, 11), 5, 5)
game.player.essence = Crafting.FORGE_COST * 2
ok(Commands.apply(game, "forge fire"), "forging a known element spends the turn")
ok(Commands.apply(game, "forge fire"), "forging a second matching gem spends the turn")
local a, b
for i, item in ipairs(game.player.inventory) do
if item.kind == Items.GEM then
if not a then a = i else b = i end
end
end
local consumesTurn = Commands.apply(game, "merge " .. a .. " " .. b)
eq(consumesTurn, true, "merging two matching gems spends the turn")
end
function tests.commandsApplyForgeRejectsAMissingOrUnknownElementWithoutSpendingATurn()
local game = stagedGame(1, arena(21, 11), 5, 5)
local missing, message1 = Commands.apply(game, "forge")
eq(missing, false, "forge with no element spends no turn")
ok(message1 ~= nil, "the failure names what is missing")
game.player.essence = Crafting.FORGE_COST
local unknown = Commands.apply(game, "forge lava")
eq(unknown, false, "an unrecognized element spends no turn")
end
function tests.commandsApplyMergeRejectsAMissingOrMismatchedPairWithoutSpendingATurn()
local game = stagedGame(1, arena(21, 11), 5, 5)
local missing, message = Commands.apply(game, "merge")
eq(missing, false, "merge with no indices spends no turn")
ok(message ~= nil, "the failure names what is missing")
game.player.inventory = { Crafting.gem(Crafting.FIRE, 1), Crafting.gem(Crafting.FROST, 1) }
local mismatched = Commands.apply(game, "merge 1 2")
eq(mismatched, false, "mismatched gems spend no turn")
eq(#game.player.inventory, 2, "a rejected merge leaves both gems untouched")
end
function tests.commandsApplySocketTemperEnchantDisenchantDriveTheEquippedWeaponAndSpendTheTurn()
local game = stagedGame(1, arena(21, 11), 5, 5)
local weapon = Items.weapon("dagger", 2)
Items.equipWeapon(weapon, game.player)
game.player.inventory = { Crafting.gem(Crafting.FIRE, 1) }
local socketed = Commands.apply(game, "socket weapon 1")
eq(socketed, true, "socketing a gem into the equipped weapon spends the turn")
eq(weapon.socket.element, Crafting.FIRE, "the socketed gem's element lands on the weapon")
game.player.essence = Crafting.temperCost(weapon)
local tempered = Commands.apply(game, "temper weapon")
eq(tempered, true, "tempering the equipped weapon spends the turn")
game.player.essence = Crafting.ENCHANT_COST
local enchanted = Commands.apply(game, "enchant weapon vicious")
eq(enchanted, true, "enchanting the equipped weapon spends the turn")
eq(weapon.affix.key, "vicious", "the chosen affix lands on the weapon")
local disenchanted = Commands.apply(game, "disenchant weapon")
eq(disenchanted, true, "disenchanting the equipped weapon spends the turn")
eq(weapon.affix, nil, "the affix is gone once disenchanted")
end
function tests.commandsApplySocketRuneCompletesARunewordAndSpendsTheTurn()
local game = stagedGame(1, arena(21, 11), 5, 5)
Items.equipWeapon(Items.weapon("sword", 4), game.player)
game.player.inventory = { Runewords.rune("sol"), Runewords.rune("ith") }
ok(Commands.apply(game, "socketrune weapon 1"), "socketing the first rune spends the turn")
local consumesTurn, message = Commands.apply(game, "socketrune weapon 1")
eq(consumesTurn, true, "completing the runeword spends the turn")
ok(contains(game.log:last(), "Zenith"), "completing a runeword is announced by name")
end
function tests.commandsApplyCraftingVerbsFailCleanlyWithBadTargetsWithoutSpendingATurn()
local game = stagedGame(1, arena(21, 11), 5, 5)
for _, verb in ipairs({ "socket", "socketrune", "temper", "enchant", "disenchant" }) do
local consumesTurn, message = Commands.apply(game, verb)
eq(consumesTurn, false, verb .. " with no target spends no turn")
ok(message ~= nil and #message > 0, verb .. " explains what it needs")
end
Items.equipWeapon(Items.weapon("dagger", 2), game.player)
local badSocket = Commands.apply(game, "socket weapon 1")
eq(badSocket, false, "socketing with an empty inventory slot spends no turn")
end
function tests.commandsApplyRepairFixesTheEquippedWeaponAndSpendsTheTurn()
local game = stagedGame(1, arena(21, 11), 5, 5)
Items.equipWeapon(Items.weapon("sword", 4), game.player)
game.player.weapon.durability = 0
game.player.gold = 1000
local consumesTurn = Commands.apply(game, "repair weapon")
eq(consumesTurn, true, "repairing an affordable broken weapon spends the turn")
eq(game.player.weapon.durability, Durability.MAX, "the weapon comes back to full durability")
end
function tests.commandsApplyRepairRejectsAnUnknownSlotOrAnEmptyPurseWithoutSpendingATurn()
local game = stagedGame(1, arena(21, 11), 5, 5)
local badSlot, message = Commands.apply(game, "repair shield")
eq(badSlot, false, "an unrecognized slot spends no turn")
eq(message, "repair what? weapon, armor or bow", "the failure names the valid slots")
Items.equipWeapon(Items.weapon("sword", 4), game.player)
game.player.weapon.durability = 0
game.player.gold = 0
local shortPurse = Commands.apply(game, "repair weapon")
eq(shortPurse, false, "an empty purse cannot repair, and spends no turn")
end
function tests.commandsApplyStealTakesTheWardedWareUnderfootAndSpendsTheTurn()
local game = stagedGame(1, arena(21, 11), 5, 5)
local keeper = Monsters.create(Monsters.byKey.shopkeeper, 1, 10, 10, 4)
end
local order = {
"rngDeterminism", "mapDeterminism", "tilesRegistry", "fovKnownScene", "losSightLine",
"astarPathing", "combatResolution", "itemsAndEquipment", "affixes", "statusEffects",