From 36969cabc9c4af3e3fff07bad4dbaaaf3cfc1ae2 Mon Sep 17 00:00:00 2001 From: Bertie690 Date: Sun, 3 Aug 2025 19:51:04 -0400 Subject: [PATCH 1/2] Added arena trap tests and such --- test/abilities/arena-trap.test.ts | 103 ++++++++++++++++++------------ 1 file changed, 63 insertions(+), 40 deletions(-) diff --git a/test/abilities/arena-trap.test.ts b/test/abilities/arena-trap.test.ts index f85fae5b259..2c0ff37eaed 100644 --- a/test/abilities/arena-trap.test.ts +++ b/test/abilities/arena-trap.test.ts @@ -1,10 +1,15 @@ +import { getPokemonNameWithAffix } from "#app/messages"; import { allAbilities } from "#data/data-lists"; import { AbilityId } from "#enums/ability-id"; +import { Button } from "#enums/buttons"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; +import { UiMode } from "#enums/ui-mode"; import { GameManager } from "#test/test-utils/game-manager"; +import type { CommandUiHandler } from "#ui/command-ui-handler"; +import i18next from "i18next"; import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Abilities - Arena Trap", () => { let phaserGame: Phaser.Game; @@ -23,68 +28,86 @@ describe("Abilities - Arena Trap", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset(MoveId.SPLASH) .ability(AbilityId.ARENA_TRAP) .enemySpecies(SpeciesId.RALTS) .enemyAbility(AbilityId.BALL_FETCH) - .enemyMoveset(MoveId.TELEPORT); + .enemyMoveset(MoveId.SPLASH); }); - // TODO: Enable test when Issue #935 is addressed - it.todo("should not allow grounded Pokémon to flee", async () => { + // NB: Since switching moves bypass trapping, the only way fleeing can occur in PKR is from the player + // TODO: Implement once forced flee helper exists + it.todo("should interrupt player flee attempt and display message, unless user has Run Away", async () => { game.override.battleStyle("single"); + await game.classicMode.startBattle([SpeciesId.DUGTRIO, SpeciesId.GOTHITELLE]); - await game.classicMode.startBattle(); + const enemy = game.field.getEnemyPokemon(); - const enemy = game.scene.getEnemyPokemon(); + // flee stuff goes here - game.move.select(MoveId.SPLASH); + game.onNextPrompt("CommandPhase", UiMode.COMMAND, () => { + // no switch out command should be queued due to arena trap + expect(game.scene.currentBattle.turnCommands[0]).toBeNull(); + + // back out and cancel the flee to avoid timeout + (game.scene.ui.getHandler() as CommandUiHandler).processInput(Button.CANCEL); + game.move.use(MoveId.SPLASH); + }); await game.toNextTurn(); + expect(game.textInterceptor.logs).toContain( + i18next.t("abilityTriggers:arenaTrap", { + pokemonNameWithAffix: getPokemonNameWithAffix(enemy), + abilityName: allAbilities[AbilityId.ARENA_TRAP].name, + }), + ); + }); - expect(enemy).toBe(game.scene.getEnemyPokemon()); + it("should interrupt player switch attempt and display message", async () => { + game.override.battleStyle("single").enemyAbility(AbilityId.ARENA_TRAP); + await game.classicMode.startBattle([SpeciesId.DUGTRIO, SpeciesId.GOTHITELLE]); + + const enemy = game.field.getEnemyPokemon(); + + game.doSwitchPokemon(1); + game.onNextPrompt("CommandPhase", UiMode.PARTY, () => { + // no switch out command should be queued due to arena trap + expect(game.scene.currentBattle.turnCommands[0]).toBeNull(); + + // back out and cancel the switch to avoid timeout + (game.scene.ui.getHandler() as CommandUiHandler).processInput(Button.CANCEL); + game.move.use(MoveId.SPLASH); + }); + + await game.toNextTurn(); + expect(game.textInterceptor.logs).toContain( + i18next.t("abilityTriggers:arenaTrap", { + pokemonNameWithAffix: getPokemonNameWithAffix(enemy), + abilityName: allAbilities[AbilityId.ARENA_TRAP].name, + }), + ); }); it("should guarantee double battle with any one LURE", async () => { game.override.startingModifier([{ name: "LURE" }]).startingWave(2); + await game.classicMode.startBattle([SpeciesId.DUGTRIO]); - await game.classicMode.startBattle(); - - expect(game.scene.getEnemyField().length).toBe(2); + expect(game.scene.getEnemyField()).toHaveLength(2); }); - /** - * This checks if the Player Pokemon is able to switch out/run away after the Enemy Pokemon with {@linkcode AbilityId.ARENA_TRAP} - * is forcefully moved out of the field from moves such as Roar {@linkcode MoveId.ROAR} - * - * Note: It should be able to switch out/run away - */ it("should lift if pokemon with this ability leaves the field", async () => { - game.override - .battleStyle("double") - .enemyMoveset(MoveId.SPLASH) - .moveset([MoveId.ROAR, MoveId.SPLASH]) - .ability(AbilityId.BALL_FETCH); - await game.classicMode.startBattle([SpeciesId.MAGIKARP, SpeciesId.SUDOWOODO, SpeciesId.LUNATONE]); + game.override.battleStyle("single"); + await game.classicMode.startBattle([SpeciesId.MAGIKARP]); - const [enemy1, enemy2] = game.scene.getEnemyField(); - const [player1, player2] = game.scene.getPlayerField(); + const player = game.field.getPlayerPokemon(); + const enemy = game.field.getEnemyPokemon(); - vi.spyOn(enemy1, "getAbility").mockReturnValue(allAbilities[AbilityId.ARENA_TRAP]); + expect(player.isTrapped()).toBe(true); + expect(enemy.isOnField()).toBe(true); - game.move.select(MoveId.ROAR); - game.move.select(MoveId.SPLASH, 1); + game.move.use(MoveId.ROAR); + await game.toEndOfTurn(); - // This runs the fist command phase where the moves are selected - await game.toNextTurn(); - // During the next command phase the player pokemons should not be trapped anymore - game.move.select(MoveId.SPLASH); - game.move.select(MoveId.SPLASH, 1); - await game.toNextTurn(); - - expect(player1.isTrapped()).toBe(false); - expect(player2.isTrapped()).toBe(false); - expect(enemy1.isOnField()).toBe(false); - expect(enemy2.isOnField()).toBe(true); + expect(player.isTrapped()).toBe(false); + expect(enemy.isOnField()).toBe(false); }); }); From c51c5a2b3447f61f0694c298e9d6f4220d0d70c6 Mon Sep 17 00:00:00 2001 From: Bertie690 Date: Sun, 3 Aug 2025 23:13:25 -0400 Subject: [PATCH 2/2] hopefullt fixed tests --- test/abilities/arena-trap.test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/abilities/arena-trap.test.ts b/test/abilities/arena-trap.test.ts index 2c0ff37eaed..4f6a4bb5125 100644 --- a/test/abilities/arena-trap.test.ts +++ b/test/abilities/arena-trap.test.ts @@ -29,8 +29,8 @@ describe("Abilities - Arena Trap", () => { game = new GameManager(phaserGame); game.override .ability(AbilityId.ARENA_TRAP) + .enemyAbility(AbilityId.ARENA_TRAP) .enemySpecies(SpeciesId.RALTS) - .enemyAbility(AbilityId.BALL_FETCH) .enemyMoveset(MoveId.SPLASH); }); @@ -63,7 +63,7 @@ describe("Abilities - Arena Trap", () => { }); it("should interrupt player switch attempt and display message", async () => { - game.override.battleStyle("single").enemyAbility(AbilityId.ARENA_TRAP); + game.override.battleStyle("single"); await game.classicMode.startBattle([SpeciesId.DUGTRIO, SpeciesId.GOTHITELLE]); const enemy = game.field.getEnemyPokemon(); @@ -74,6 +74,7 @@ describe("Abilities - Arena Trap", () => { expect(game.scene.currentBattle.turnCommands[0]).toBeNull(); // back out and cancel the switch to avoid timeout + (game.scene.ui.getHandler() as CommandUiHandler).processInput(Button.ACTION); (game.scene.ui.getHandler() as CommandUiHandler).processInput(Button.CANCEL); game.move.use(MoveId.SPLASH); });