From 96a553b8d08825e1db2e65fcd65be699e8c2bbb6 Mon Sep 17 00:00:00 2001 From: Eucalyptus Date: Wed, 7 Aug 2024 18:25:57 -0400 Subject: [PATCH] Add tests for Trick --- src/test/moves/trick.test.ts | 218 +++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 src/test/moves/trick.test.ts diff --git a/src/test/moves/trick.test.ts b/src/test/moves/trick.test.ts new file mode 100644 index 00000000000..56e7a9eb193 --- /dev/null +++ b/src/test/moves/trick.test.ts @@ -0,0 +1,218 @@ +import GameManager from "#app/test/utils/gameManager"; +import Phaser from "phaser"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { TurnEndPhase } from "#app/phases"; +import { PokemonHeldItemModifier } from "#app/modifier/modifier.js"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; +import { deepCopy } from "#app/utils"; +import { Abilities } from "#app/enums/abilities.js"; + +const TIMEOUT = 20000; +const TRICK_ONLY = [Moves.TRICK, Moves.TRICK, Moves.TRICK, Moves.TRICK]; + +/** + * Gets the PokemonHeldItemModifier for a given item ID, if the Pokemon has that item + * @param {PokemonHeldItemModifier[]} inventory Held items of a Pokemon + * @param {string} itemId The ID of the item to search for + * @returns PokemonHeldItemModifier if the item is found, undefined if not + */ +function getHeldItemModifierFromId(inventory: PokemonHeldItemModifier[], itemId: string) { + let idxOfSearchedItem = -1; + for (let idx = 0; idx < inventory.length; idx++) { + if (inventory[idx].type.id === itemId) { + idxOfSearchedItem = idx; + break; + } + } + return idxOfSearchedItem !== -1 ? inventory[idxOfSearchedItem] : undefined; +} + +/** + * Prints a string to the console showing how many of an item a Pokemon currently has + * @param {string} pokemonName The name of the checked Pokemon + * @param {string} itemId The ID of the checked item + * @param {number} stackCount How many of this item ID the checked Pokemon has + */ +function printStackCount(pokemonName: string, itemId: string, stackCount: number) { + console.log(`${pokemonName} has ${stackCount} of ${itemId}`); +} + +describe("Moves - Trick", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override.battleType("single"); + }); + + it( + "both pokemon have at least one item, and therefore swap their selected items", + async () => { + game.override.startingHeldItems([{name: "LUCKY_EGG"}]); + game.override.enemyHeldItems([{name: "LEFTOVERS"}, {name: "LUCKY_EGG"}]); + game.override.moveset(TRICK_ONLY); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset(SPLASH_ONLY); + await game.startBattle([Species.MIME_JR]); + + const playerPokemon = game.scene.getPlayerPokemon(); + const enemyPokemon = game.scene.getEnemyPokemon(); + + vi.spyOn(playerPokemon, "randSeedInt").mockReturnValue(0); + vi.spyOn(enemyPokemon, "randSeedInt").mockReturnValue(0); + + const playerLostItem = playerPokemon.getHeldItems()[0]; + const enemyLostItem = enemyPokemon.getHeldItems()[0]; + const prevPlayerLostItemStack = playerLostItem.stackCount; + const prevEnemyLostItemStack = enemyLostItem.stackCount; + const prevPlayerGainedItemModifier = getHeldItemModifierFromId(playerPokemon.getHeldItems(), enemyLostItem.type.id); + const prevEnemyGainedItemModifier = getHeldItemModifierFromId(enemyPokemon.getHeldItems(), playerLostItem.type.id); + + + let prevPlayerGainedItemStackCount = 0; + let prevEnemyGainedItemStackCount = 0; + + if (prevPlayerGainedItemModifier !== undefined) { + prevPlayerGainedItemStackCount = prevPlayerGainedItemModifier.stackCount; + } + + if (prevEnemyGainedItemModifier !== undefined) { + prevEnemyGainedItemStackCount = prevEnemyGainedItemModifier.stackCount; + } + + printStackCount(playerPokemon.name, playerLostItem.type.id, prevPlayerLostItemStack); + printStackCount(playerPokemon.name, enemyLostItem.type.id, prevPlayerGainedItemStackCount); + printStackCount(enemyPokemon.name, enemyLostItem.type.id, prevEnemyLostItemStack); + printStackCount(enemyPokemon.name, playerLostItem.type.id, prevEnemyGainedItemStackCount); + + game.doAttack(0); + await game.phaseInterceptor.to(TurnEndPhase); + + const currPlayerLostItemStack = playerLostItem.stackCount; + const currEnemyLostItemStack = enemyLostItem.stackCount; + const currPlayerGainedItemModifier = getHeldItemModifierFromId(playerPokemon.getHeldItems(), enemyLostItem.type.id); + const currEnemyGainedItemModifier = getHeldItemModifierFromId(enemyPokemon.getHeldItems(), playerLostItem.type.id); + + expect(currPlayerGainedItemModifier).toBeDefined(); + expect(currEnemyGainedItemModifier).toBeDefined(); + + const currPlayerGainedItemStackCount = currPlayerGainedItemModifier.stackCount; + const currEnemyGainedItemStackCount = currEnemyGainedItemModifier.stackCount; + + printStackCount(playerPokemon.name, playerLostItem.type.id, currPlayerLostItemStack); + printStackCount(playerPokemon.name, enemyLostItem.type.id, currPlayerGainedItemStackCount); + printStackCount(enemyPokemon.name, enemyLostItem.type.id, currEnemyLostItemStack); + printStackCount(enemyPokemon.name, playerLostItem.type.id, currEnemyGainedItemStackCount); + + const didPlayerTransferItems = prevPlayerLostItemStack > currPlayerLostItemStack && prevPlayerGainedItemStackCount < currPlayerGainedItemStackCount; + const didEnemyTransferItems = prevEnemyLostItemStack > currEnemyLostItemStack && prevEnemyGainedItemStackCount < currEnemyGainedItemStackCount; + + expect(didPlayerTransferItems && didEnemyTransferItems).toBeTruthy(); + }, TIMEOUT + ); + + it( + "the move fails and no transfer occurs when a wild pokemon is the user", + async () => { + game.override.startingHeldItems([{name: "LUCKY_EGG"}]); + game.override.enemyHeldItems([{name: "LEFTOVERS"}]); + game.override.moveset(SPLASH_ONLY); + game.override.enemySpecies(Species.MIME_JR); + game.override.enemyMoveset(TRICK_ONLY); + await game.startBattle([Species.MAGIKARP]); + + const playerPokemon = game.scene.getPlayerPokemon(); + const enemyPokemon = game.scene.getEnemyPokemon(); + const playerPokemonFirstHeldItem = deepCopy(playerPokemon.getHeldItems()[0]) as PokemonHeldItemModifier; + const enemyPokemonFirstHeldItem = deepCopy(enemyPokemon.getHeldItems()[0]) as PokemonHeldItemModifier; + + printStackCount(playerPokemon.name, playerPokemonFirstHeldItem.type.id, playerPokemonFirstHeldItem.stackCount); + printStackCount(enemyPokemon.name, enemyPokemonFirstHeldItem.type.id, enemyPokemonFirstHeldItem.stackCount); + + game.doAttack(0); + await game.phaseInterceptor.to(TurnEndPhase); + + const playerPokemonCurrentHeldItem = playerPokemon.getHeldItems()[0]; + const enemyPokemonCurrentHeldItem = enemyPokemon.getHeldItems()[0]; + + printStackCount(playerPokemon.name, playerPokemonFirstHeldItem.type.id, playerPokemonFirstHeldItem.stackCount); + printStackCount(enemyPokemon.name, enemyPokemonFirstHeldItem.type.id, enemyPokemonFirstHeldItem.stackCount); + + const playerDidNotLoseItem = playerPokemonFirstHeldItem.type.id === playerPokemonCurrentHeldItem.type.id && playerPokemonFirstHeldItem.stackCount === playerPokemonCurrentHeldItem.stackCount; + const enemyDidNotLoseItem = enemyPokemonFirstHeldItem.type.id === enemyPokemonCurrentHeldItem.type.id && enemyPokemonFirstHeldItem.stackCount === enemyPokemonCurrentHeldItem.stackCount; + + expect(playerDidNotLoseItem && enemyDidNotLoseItem).toBeTruthy(); + }, TIMEOUT + ); + + it( + "the move fails and no transfer occurs when the target pokemon has sticky hold", + async () => { + game.override.startingHeldItems([{name: "LUCKY_EGG"}]); + game.override.enemyHeldItems([{name: "LEFTOVERS"}]); + game.override.moveset(TRICK_ONLY); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.enemyAbility(Abilities.STICKY_HOLD); + await game.startBattle([Species.MIME_JR]); + + const playerPokemon = game.scene.getPlayerPokemon(); + const enemyPokemon = game.scene.getEnemyPokemon(); + const playerPokemonFirstHeldItem = deepCopy(playerPokemon.getHeldItems()[0]) as PokemonHeldItemModifier; + const enemyPokemonFirstHeldItem = deepCopy(enemyPokemon.getHeldItems()[0]) as PokemonHeldItemModifier; + + printStackCount(playerPokemon.name, playerPokemonFirstHeldItem.type.id, playerPokemonFirstHeldItem.stackCount); + printStackCount(enemyPokemon.name, enemyPokemonFirstHeldItem.type.id, enemyPokemonFirstHeldItem.stackCount); + + game.doAttack(0); + await game.phaseInterceptor.to(TurnEndPhase); + + const playerPokemonCurrentHeldItem = playerPokemon.getHeldItems()[0]; + const enemyPokemonCurrentHeldItem = enemyPokemon.getHeldItems()[0]; + + printStackCount(playerPokemon.name, playerPokemonFirstHeldItem.type.id, playerPokemonFirstHeldItem.stackCount); + printStackCount(enemyPokemon.name, enemyPokemonFirstHeldItem.type.id, enemyPokemonFirstHeldItem.stackCount); + + const playerDidNotLoseItem = playerPokemonFirstHeldItem.type.id === playerPokemonCurrentHeldItem.type.id && playerPokemonFirstHeldItem.stackCount === playerPokemonCurrentHeldItem.stackCount; + const enemyDidNotLoseItem = enemyPokemonFirstHeldItem.type.id === enemyPokemonCurrentHeldItem.type.id && enemyPokemonFirstHeldItem.stackCount === enemyPokemonCurrentHeldItem.stackCount; + + expect(playerDidNotLoseItem && enemyDidNotLoseItem).toBeTruthy(); + }, TIMEOUT + ); + + it( + "the move fails and no transfer occurs when neither pokemon have any items", + async() => { + game.override.moveset(TRICK_ONLY); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset(SPLASH_ONLY); + await game.startBattle([Species.MIME_JR]); + + const playerPokemon = game.scene.getPlayerPokemon(); + const enemyPokemon = game.scene.getEnemyPokemon(); + + expect(playerPokemon.getHeldItems().length === 0); + expect(enemyPokemon.getHeldItems().length === 0); + + game.doAttack(0); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(playerPokemon.getHeldItems().length === 0); + expect(enemyPokemon.getHeldItems().length === 0); + + }, TIMEOUT + ); +});