From ee4d130ebb916f3f18f240d6ed64b8a6b09c0692 Mon Sep 17 00:00:00 2001 From: Dmitriy K Date: Mon, 10 Jun 2024 17:35:24 -0400 Subject: [PATCH] [Test(refactor)]: Refactor tests game manager (#2062) * refactor tests game manager * add setPosition to Mock Text class --- src/test/battle/battle.test.ts | 4 +- src/test/battle/error-handling.test.ts | 2 +- src/test/utils/gameManager.ts | 168 +++++++++--------- .../utils/mocks/mocksContainer/mockText.ts | 10 ++ 4 files changed, 96 insertions(+), 88 deletions(-) diff --git a/src/test/battle/battle.test.ts b/src/test/battle/battle.test.ts index 52d014a74a5..9077cf00076 100644 --- a/src/test/battle/battle.test.ts +++ b/src/test/battle/battle.test.ts @@ -300,7 +300,7 @@ describe("Test Battle Phase", () => { vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); await game.startBattle(); const turn = game.scene.currentBattle.turn; - await game.doAttack(0); + game.doAttack(0); await game.toNextTurn(); expect(game.scene.currentBattle.turn).toBeGreaterThan(turn); }, 20000); @@ -318,7 +318,7 @@ describe("Test Battle Phase", () => { vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); await game.startBattle(); const waveIndex = game.scene.currentBattle.waveIndex; - await game.doAttack(0); + game.doAttack(0); await game.doKillOpponents(); await game.toNextWave(); expect(game.scene.currentBattle.waveIndex).toBeGreaterThan(waveIndex); diff --git a/src/test/battle/error-handling.test.ts b/src/test/battle/error-handling.test.ts index 0f661149dd3..8b94c108bc1 100644 --- a/src/test/battle/error-handling.test.ts +++ b/src/test/battle/error-handling.test.ts @@ -37,7 +37,7 @@ describe("Test Battle Phase", () => { it.skip("to next turn", async() => { await game.startBattle(); const turn = game.scene.currentBattle.turn; - await game.doAttack(0); + game.doAttack(0); await game.toNextTurn(); expect(game.scene.currentBattle.turn).toBeGreaterThan(turn); }, 20000); diff --git a/src/test/utils/gameManager.ts b/src/test/utils/gameManager.ts index c00b766bc85..faf44e4bd2b 100644 --- a/src/test/utils/gameManager.ts +++ b/src/test/utils/gameManager.ts @@ -3,7 +3,6 @@ import {Mode} from "#app/ui/ui"; import {generateStarter, waitUntil} from "#app/test/utils/gameManagerUtils"; import { CommandPhase, - DamagePhase, EncounterPhase, FaintPhase, LoginPhase, NewBattlePhase, @@ -98,23 +97,23 @@ export default class GameManager { * Runs the game to the title phase. * @returns A promise that resolves when the title phase is reached. */ - runToTitle(): Promise { - return new Promise(async(resolve, reject) => { - await this.phaseInterceptor.run(LoginPhase).catch((e) => reject(e)); - this.onNextPrompt("SelectGenderPhase", Mode.OPTION_SELECT, () => { - this.scene.gameData.gender = PlayerGender.MALE; - this.endPhase(); - }, () => this.isCurrentPhase(TitlePhase)); - await this.phaseInterceptor.run(SelectGenderPhase, () => this.isCurrentPhase(TitlePhase)).catch((e) => reject(e)); - await this.phaseInterceptor.run(TitlePhase).catch((e) => reject(e)); - this.scene.gameSpeed = 5; - this.scene.moveAnimations = false; - this.scene.showLevelUpStats = false; - this.scene.expGainsSpeed = 3; - this.scene.expParty = ExpNotification.SKIP; - this.scene.hpBarSpeed = 3; - resolve(); - }); + async runToTitle(): Promise { + await this.phaseInterceptor.run(LoginPhase); + + this.onNextPrompt("SelectGenderPhase", Mode.OPTION_SELECT, () => { + this.scene.gameData.gender = PlayerGender.MALE; + this.endPhase(); + }, () => this.isCurrentPhase(TitlePhase)); + + await this.phaseInterceptor.run(SelectGenderPhase, () => this.isCurrentPhase(TitlePhase)); + await this.phaseInterceptor.run(TitlePhase); + + this.scene.gameSpeed = 5; + this.scene.moveAnimations = false; + this.scene.showLevelUpStats = false; + this.scene.expGainsSpeed = 3; + this.scene.expParty = ExpNotification.SKIP; + this.scene.hpBarSpeed = 3; } /** @@ -122,92 +121,91 @@ export default class GameManager { * @param species - Optional array of species to summon. * @returns A promise that resolves when the summon phase is reached. */ - runToSummon(species?: Species[]): Promise { - return new Promise(async(resolve, reject) => { - await this.runToTitle().catch((e) => reject(e)); - this.onNextPrompt("TitlePhase", Mode.TITLE, () => { - this.scene.gameMode = getGameMode(GameModes.CLASSIC); - const starters = generateStarter(this.scene, species); - const selectStarterPhase = new SelectStarterPhase(this.scene); - this.scene.pushPhase(new EncounterPhase(this.scene, false)); - selectStarterPhase.initBattle(starters); - }); - await this.phaseInterceptor.run(EncounterPhase).catch((e) => reject(e)); - resolve(); + async runToSummon(species?: Species[]) { + await this.runToTitle(); + + this.onNextPrompt("TitlePhase", Mode.TITLE, () => { + this.scene.gameMode = getGameMode(GameModes.CLASSIC); + const starters = generateStarter(this.scene, species); + const selectStarterPhase = new SelectStarterPhase(this.scene); + this.scene.pushPhase(new EncounterPhase(this.scene, false)); + selectStarterPhase.initBattle(starters); }); + + await this.phaseInterceptor.run(EncounterPhase); } /** - * Starts a battle. + * Transitions to the start of a battle. * @param species - Optional array of species to start the battle with. * @returns A promise that resolves when the battle is started. */ - startBattle(species?: Species[]): Promise { - return new Promise(async(resolve, reject) => { - await this.runToSummon(species).catch((e) => reject(e)); - this.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => { - this.setMode(Mode.MESSAGE); - this.endPhase(); - }, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(TurnInitPhase)); - this.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => { - this.setMode(Mode.MESSAGE); - this.endPhase(); - }, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(TurnInitPhase)); - await this.phaseInterceptor.to(CommandPhase).catch((e) => reject(e)); - console.log("==================[New Turn]=================="); - return resolve(); - }); + async startBattle(species?: Species[]) { + await this.runToSummon(species); + + this.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => { + this.setMode(Mode.MESSAGE); + this.endPhase(); + }, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(TurnInitPhase)); + + this.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => { + this.setMode(Mode.MESSAGE); + this.endPhase(); + }, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(TurnInitPhase)); + + await this.phaseInterceptor.to(CommandPhase); + console.log("==================[New Turn]=================="); } - doAttack(moveIndex: integer): Promise { + /** + * Emulate a player attack + * @param movePosition the index of the move in the pokemon's moveset array + */ + doAttack(movePosition: integer) { this.onNextPrompt("CommandPhase", Mode.COMMAND, () => { this.scene.ui.setMode(Mode.FIGHT, (this.scene.getCurrentPhase() as CommandPhase).getFieldIndex()); }); this.onNextPrompt("CommandPhase", Mode.FIGHT, () => { - (this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, moveIndex, false); - }); - return this.phaseInterceptor.to(DamagePhase); - } - - doKillOpponents() { - return new Promise(async(resolve, reject) => { - await this.killPokemon(this.scene.currentBattle.enemyParty[0]).catch((e) => reject(e)); - if (this.scene.currentBattle.double) { - await this.killPokemon(this.scene.currentBattle.enemyParty[1]).catch((e) => reject(e)); - } - return resolve(); + (this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false); }); } - toNextTurn(): Promise { - return new Promise(async(resolve, reject) => { - await this.phaseInterceptor.to(CommandPhase).catch((e) => reject(e)); - return resolve(); - }); + /** Faint all opponents currently on the field */ + async doKillOpponents() { + await this.killPokemon(this.scene.currentBattle.enemyParty[0]); + if (this.scene.currentBattle.double) { + await this.killPokemon(this.scene.currentBattle.enemyParty[1]); + } } - toNextWave(): Promise { - return new Promise(async(resolve, reject) => { - this.onNextPrompt("SelectModifierPhase", Mode.MODIFIER_SELECT, () => { - const handler = this.scene.ui.getHandler() as ModifierSelectUiHandler; - handler.processInput(Button.CANCEL); - }, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(NewBattlePhase), true); - this.onNextPrompt("SelectModifierPhase", Mode.CONFIRM, () => { - const handler = this.scene.ui.getHandler() as ModifierSelectUiHandler; - handler.processInput(Button.ACTION); - }, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(NewBattlePhase)); - this.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => { - this.setMode(Mode.MESSAGE); - this.endPhase(); - }, () => this.isCurrentPhase(TurnInitPhase)); - this.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => { - this.setMode(Mode.MESSAGE); - this.endPhase(); - }, () => this.isCurrentPhase(TurnInitPhase)); - await this.phaseInterceptor.to(CommandPhase).catch((e) => reject(e)); + /** Emulate selecting a modifier (item) */ + doSelectModifier() { + this.onNextPrompt("SelectModifierPhase", Mode.MODIFIER_SELECT, () => { + const handler = this.scene.ui.getHandler() as ModifierSelectUiHandler; + handler.processInput(Button.CANCEL); + }, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(NewBattlePhase), true); - return resolve(); - }); + this.onNextPrompt("SelectModifierPhase", Mode.CONFIRM, () => { + const handler = this.scene.ui.getHandler() as ModifierSelectUiHandler; + handler.processInput(Button.ACTION); + }, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(NewBattlePhase)); + } + + /** Transition to the next upcoming {@linkcode CommandPhase} */ + async toNextTurn() { + await this.phaseInterceptor.to(CommandPhase); + } + + /** Emulate selecting a modifier (item) and transition to the next upcoming {@linkcode CommandPhase} */ + async toNextWave() { + this.doSelectModifier(); + + this.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => { + this.setMode(Mode.MESSAGE); + this.endPhase(); + }, () => this.isCurrentPhase(TurnInitPhase)); + + await this.toNextTurn(); } /** diff --git a/src/test/utils/mocks/mocksContainer/mockText.ts b/src/test/utils/mocks/mocksContainer/mockText.ts index bfff146465e..1dd440fde7c 100644 --- a/src/test/utils/mocks/mocksContainer/mockText.ts +++ b/src/test/utils/mocks/mocksContainer/mockText.ts @@ -8,6 +8,7 @@ export default class MockText { private textureManager; public list = []; public style; + constructor(textureManager, x, y, content, styleOptions) { this.scene = textureManager.scene; this.textureManager = textureManager; @@ -138,6 +139,15 @@ export default class MockText { // return this.phaserText.setX(x); } + /** + * Sets the position of this Game Object. + * @param x The x position of this Game Object. Default 0. + * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. + * @param z The z position of this Game Object. Default 0. + * @param w The w position of this Game Object. Default 0. + */ + setPosition(x?: number, y?: number, z?: number, w?: number) { } + setText(text) { // Sets the text this Game Object will display. // return this.phaserText.setText(text);