test: cover tests.commandsApplyItemCommandsRejectAMissingOrNonNumeric...
This commit is contained in:
1 parent
f710e182dd
commit
ef064dfe9d
1 file changed
+173
+173
@@ -12931,6 +12931,179 @@ function tests.commandsApplyUseDrinksAPotionByInventoryIndexAndSpendsTheTurn()
|
||||
eq(#game.player.inventory, before - 1, "the consumed potion leaves the inventory")
|
||||
end
|
||||
|
||||
function tests.commandsApplyItemCommandsRejectAMissingOrNonNumericIndexWithoutSpendingATurn()
|
||||
local game = stagedGame(1, arena(21, 11), 5, 5)
|
||||
for _, verb in ipairs({ "use", "drop", "sell", "throw", "capture" }) do
|
||||
local consumesTurn, message = Commands.apply(game, verb)
|
||||
eq(consumesTurn, false, verb .. " with no inventory number spends no turn")
|
||||
ok(message ~= nil and #message > 0, verb .. " explains what index it needs")
|
||||
end
|
||||
local consumesTurn, message = Commands.apply(game, "use ninety")
|
||||
eq(consumesTurn, false, "a non-numeric inventory argument spends no turn")
|
||||
ok(message ~= nil, "the non-numeric argument still gets a clear reason")
|
||||
end
|
||||
|
||||
function tests.commandsApplyCastAutoTargetsTheNearestVisibleHostile()
|
||||
local game = stagedGame(1, arena(21, 11), 5, 5)
|
||||
local near = Monsters.create(Monsters.byKey.rat, 5, 8, 5, 1)
|
||||
local far = Monsters.create(Monsters.byKey.rat, 9, 15, 5, 1)
|
||||
near.hp, far.hp = 30, 30
|
||||
game.level.entities = { near, far }
|
||||
local consumesTurn = Commands.apply(game, "cast missile")
|
||||
eq(consumesTurn, true, "casting a known targeted spell at a visible hostile spends the turn")
|
||||
ok(near.hp < 30, "the nearer visible hostile takes the hit")
|
||||
eq(far.hp, 30, "the farther hostile is left untouched")
|
||||
end
|
||||
|
||||
function tests.commandsApplyCastBreaksATiedDistanceByAscendingMonsterId()
|
||||
local game = stagedGame(1, arena(21, 11), 5, 5)
|
||||
local higherId = Monsters.create(Monsters.byKey.rat, 9, 8, 5, 1)
|
||||
local lowerId = Monsters.create(Monsters.byKey.rat, 3, 5, 8, 1)
|
||||
higherId.hp, lowerId.hp = 30, 30
|
||||
game.level.entities = { higherId, lowerId }
|
||||
Commands.apply(game, "cast missile")
|
||||
ok(lowerId.hp < 30, "a tied Chebyshev distance is broken toward the lower monster id")
|
||||
eq(higherId.hp, 30, "the higher-id tied hostile is left untouched")
|
||||
end
|
||||
|
||||
function tests.commandsApplyCastFailsWithoutSpendingATurnWhenNoHostileIsVisible()
|
||||
local game = stagedGame(1, arena(21, 11), 5, 5)
|
||||
local consumesTurn, message = Commands.apply(game, "cast missile")
|
||||
eq(consumesTurn, false, "a targeted spell with nothing to target spends no turn")
|
||||
eq(message, "there is nothing in sight to cast that at", "the failure explains itself")
|
||||
end
|
||||
|
||||
function tests.commandsApplyCastRejectsAnUnknownOrUnlearnedSpellWithoutSpendingATurn()
|
||||
local game = stagedGame(1, arena(21, 11), 5, 5)
|
||||
local consumesTurn, message = Commands.apply(game, "cast nonsense")
|
||||
eq(consumesTurn, false, "an unknown spell key spends no turn")
|
||||
eq(message, "you know no spell by that name", "the failure names the problem")
|
||||
end
|
||||
|
||||
function tests.commandsApplyCastConfuseAppliesTheStatusThroughTheFullCommandPipeline()
|
||||
local game = stagedGame(1, arena(21, 11), 5, 5)
|
||||
Spells.learn(game.player, "confuse")
|
||||
local rat = Monsters.create(Monsters.byKey.rat, 1, 8, 5, 1)
|
||||
game.level.entities = { rat }
|
||||
local consumesTurn = Commands.apply(game, "cast confuse")
|
||||
eq(consumesTurn, true, "casting confuse on a visible hostile spends the turn")
|
||||
eq(Status.has(rat, Status.CONFUSE), true, "the nearest visible hostile carries the confuse status afterward")
|
||||
end
|
||||
|
||||
function tests.commandsApplyCastBlindAppliesTheStatusThroughTheFullCommandPipeline()
|
||||
local game = stagedGame(1, arena(21, 11), 5, 5)
|
||||
Spells.learn(game.player, "blind")
|
||||
local rat = Monsters.create(Monsters.byKey.rat, 1, 8, 5, 1)
|
||||
game.level.entities = { rat }
|
||||
local consumesTurn = Commands.apply(game, "cast blind")
|
||||
eq(consumesTurn, true, "casting blind on a visible hostile spends the turn")
|
||||
eq(Status.has(rat, Status.BLIND), true, "the nearest visible hostile carries the blind status afterward")
|
||||
end
|
||||
|
||||
function tests.commandsApplyCastWeakenAppliesTheStatusThroughTheFullCommandPipeline()
|
||||
local game = stagedGame(1, arena(21, 11), 5, 5)
|
||||
Spells.learn(game.player, "weaken")
|
||||
local rat = Monsters.create(Monsters.byKey.rat, 1, 8, 5, 1)
|
||||
game.level.entities = { rat }
|
||||
local consumesTurn = Commands.apply(game, "cast weaken")
|
||||
eq(consumesTurn, true, "casting weaken on a visible hostile spends the turn")
|
||||
eq(Status.has(rat, Status.WEAKEN), true, "the nearest visible hostile carries the weaken status afterward")
|
||||
end
|
||||
|
||||
-- levitate is self-targeted (Spells.catalog.levitate.targeted == false), so
|
||||
-- unlike cast confuse/blind above there is no hostile to resolve at all -
|
||||
-- this is the pipeline's only self-buff cast covered end to end.
|
||||
function tests.commandsApplyCastLevitateAppliesTheStatusToTheCasterThroughTheFullCommandPipeline()
|
||||
local game = stagedGame(1, arena(21, 11), 5, 5)
|
||||
Spells.learn(game.player, "levitate")
|
||||
local consumesTurn = Commands.apply(game, "cast levitate")
|
||||
eq(consumesTurn, true, "casting levitate spends the turn")
|
||||
eq(Status.has(game.player, Status.LEVITATE), true, "the caster carries the levitate status afterward")
|
||||
end
|
||||
|
||||
-- cleanse is self-targeted like levitate, so no hostile needs to be in sight
|
||||
-- at all - the pipeline still finds and lifts the caster's own status.
|
||||
function tests.commandsApplyCastCleanseLiftsTheCastersOwnStatusThroughTheFullCommandPipeline()
|
||||
local game = stagedGame(1, arena(21, 11), 5, 5)
|
||||
Spells.learn(game.player, "cleanse")
|
||||
Status.apply(game.player, Status.POISON, 5, 2)
|
||||
local consumesTurn = Commands.apply(game, "cast cleanse")
|
||||
eq(consumesTurn, true, "casting cleanse spends the turn")
|
||||
eq(Status.has(game.player, Status.POISON), false, "the caster's own poison is gone afterward")
|
||||
end
|
||||
|
||||
function tests.commandsApplyThrowAndFireFailWithoutSpendingATurnWhenNoHostileIsVisible()
|
||||
local game = stagedGame(1, arena(21, 11), 5, 5)
|
||||
local consumesTurn1, message1 = Commands.apply(game, "throw 1")
|
||||
eq(consumesTurn1, false, "throwing with nothing in sight spends no turn")
|
||||
eq(message1, "there is nothing in sight to throw at", "the failure explains itself")
|
||||
local consumesTurn2, message2 = Commands.apply(game, "fire")
|
||||
eq(consumesTurn2, false, "firing with nothing in sight spends no turn")
|
||||
eq(message2, "there is nothing in sight to fire at", "the failure explains itself")
|
||||
end
|
||||
|
||||
function tests.commandsApplyUseskillRejectsAnUnknownOrUnlearnedSkillWithoutSpendingATurn()
|
||||
local game = stagedGame(1, arena(21, 11), 5, 5)
|
||||
local unknown = Commands.apply(game, "useskill nonsense")
|
||||
eq(unknown, false, "an unknown skill key spends no turn")
|
||||
local unlearned = Commands.apply(game, "useskill cleave")
|
||||
eq(unlearned, false, "a skill the player never learned spends no turn")
|
||||
end
|
||||
|
||||
function tests.commandsApplyUseskillCleaveAutoTargetsAnAdjacentHostile()
|
||||
local game = stagedGame(1, arena(21, 11), 5, 5)
|
||||
game.player.class = "fighter"
|
||||
Skills.learn(game.player, "cleave")
|
||||
local rat = Monsters.create(Monsters.byKey.rat, 1, 6, 5, 1)
|
||||
rat.hp = 20
|
||||
game.level.entities = { rat }
|
||||
local consumesTurn = Commands.apply(game, "useskill cleave")
|
||||
eq(consumesTurn, true, "cleave against an adjacent hostile spends the turn")
|
||||
ok(rat.hp < 20, "cleave's own attack lands on the auto-targeted adjacent hostile")
|
||||
end
|
||||
|
||||
-- Every targeted handler (throw/capture/fire/cast/useskill) accepts an
|
||||
-- optional trailing target number, resolved against the exact same 1-based
|
||||
-- listing Handlers.look/examine already print. These tests all set up a
|
||||
-- nearer hostile the OLD nearest-only auto-target would have picked, plus a
|
||||
-- farther one at a later position in game.level.entities (the same order
|
||||
-- look numbers its list in), and confirm the explicit number reaches past
|
||||
-- the nearer default to the one actually named.
|
||||
function tests.commandsApplyThrowWithAnExplicitTargetNumberHitsThatHostileInsteadOfTheNearestOne()
|
||||
local game = stagedGame(4, arena(21, 11), 5, 5)
|
||||
local near = Monsters.create(Monsters.byKey.rat, 1, 5, 6, 1)
|
||||
local far = Monsters.create(Monsters.byKey.rat, 1, 5, 8, 1)
|
||||
near.hp, far.hp = 20, 20
|
||||
game.level.entities = { near, far }
|
||||
game.player.inventory[#game.player.inventory + 1] = Items.weapon("dagger", 2)
|
||||
local index = #game.player.inventory
|
||||
local consumesTurn = Commands.apply(game, "throw " .. index .. " 2")
|
||||
eq(consumesTurn, true, "throwing at an explicit in-sight target number spends the turn")
|
||||
ok(far.hp < 20, "the explicitly named second hostile takes the hit")
|
||||
eq(near.hp, 20, "the nearer, non-targeted hostile is left untouched")
|
||||
end
|
||||
|
||||
function tests.commandsApplyThrowRejectsAnExplicitTargetNumberThatIsNotInSightWithoutSpendingATurn()
|
||||
local game = stagedGame(4, arena(21, 11), 5, 5)
|
||||
local rat = Monsters.create(Monsters.byKey.rat, 1, 5, 6, 1)
|
||||
game.level.entities = { rat }
|
||||
game.player.inventory[#game.player.inventory + 1] = Items.weapon("dagger", 2)
|
||||
local index = #game.player.inventory
|
||||
local before = #game.player.inventory
|
||||
local consumesTurn, message = Commands.apply(game, "throw " .. index .. " 5")
|
||||
eq(consumesTurn, false, "naming a target number nothing is visible at spends no turn")
|
||||
eq(message, "no monster in sight at that number", "the failure names the specific problem")
|
||||
eq(#game.player.inventory, before, "the item is never spent on a rejected target number")
|
||||
end
|
||||
|
||||
function tests.commandsApplyFireWithAnExplicitTargetNumberShootsThatHostileInsteadOfTheNearestOne()
|
||||
local game = stagedGame(4, arena(21, 11), 5, 5)
|
||||
local near = Monsters.create(Monsters.byKey.rat, 1, 5, 6, 1)
|
||||
local far = Monsters.create(Monsters.byKey.rat, 1, 5, 8, 1)
|
||||
near.hp, far.hp = 20, 20
|
||||
game.level.entities = { near, far }
|
||||
game.player.bow = Items.bow("short bow", 2, 6)
|
||||
game.player.inventory[#game.player.inventory + 1] = Items.ammo("arrow", 2)
|
||||
end
|
||||
|
||||
local order = {
|
||||
|
||||
Reference in new issue
Block a user