mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-02-18 02:07:44 +00:00
[Improvement] Refactored Test Phase Management with Error Handling (#1962)
* better phase management in tests * cleanup runFrom/to * first step of async error handling * second step of async error handling, halt await, still an issue with select-starter test * added back whenAboutToRun * added back full run suite for starter-select.test.ts
This commit is contained in:
parent
0af0ad5b49
commit
c301a54039
@ -44,8 +44,8 @@ describe("Abilities - Intrepid Sword", () => {
|
|||||||
expect(game.scene.getParty()[0].summonData).not.toBeUndefined();
|
expect(game.scene.getParty()[0].summonData).not.toBeUndefined();
|
||||||
let battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
|
let battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
|
||||||
expect(battleStatsPokemon[BattleStat.ATK]).toBe(0);
|
expect(battleStatsPokemon[BattleStat.ATK]).toBe(0);
|
||||||
await game.phaseInterceptor.mustRun(ShowAbilityPhase).catch((error) => expect(error).toBe(ShowAbilityPhase));
|
await game.phaseInterceptor.run(ShowAbilityPhase);
|
||||||
await game.phaseInterceptor.mustRun(StatChangePhase).catch((error) => expect(error).toBe(StatChangePhase));
|
await game.phaseInterceptor.run(StatChangePhase);
|
||||||
battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
|
battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
|
||||||
expect(battleStatsPokemon[BattleStat.ATK]).toBe(1);
|
expect(battleStatsPokemon[BattleStat.ATK]).toBe(1);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
@ -57,8 +57,8 @@ describe("Abilities - Intrepid Sword", () => {
|
|||||||
let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
|
let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
|
||||||
expect(battleStatsOpponent[BattleStat.ATK]).toBe(0);
|
expect(battleStatsOpponent[BattleStat.ATK]).toBe(0);
|
||||||
await game.phaseInterceptor.runFrom(PostSummonPhase).to(ToggleDoublePositionPhase);
|
await game.phaseInterceptor.runFrom(PostSummonPhase).to(ToggleDoublePositionPhase);
|
||||||
await game.phaseInterceptor.mustRun(StatChangePhase).catch((error) => expect(error).toBe(StatChangePhase));
|
await game.phaseInterceptor.run(StatChangePhase);
|
||||||
await game.phaseInterceptor.whenAboutToRun(MessagePhase);
|
await game.phaseInterceptor.run(MessagePhase);
|
||||||
battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
|
battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
|
||||||
expect(battleStatsOpponent[BattleStat.ATK]).toBe(1);
|
expect(battleStatsOpponent[BattleStat.ATK]).toBe(1);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
@ -5,7 +5,7 @@ import * as overrides from "#app/overrides";
|
|||||||
import {Abilities} from "#app/data/enums/abilities";
|
import {Abilities} from "#app/data/enums/abilities";
|
||||||
import {Species} from "#app/data/enums/species";
|
import {Species} from "#app/data/enums/species";
|
||||||
import {
|
import {
|
||||||
CommandPhase, EnemyCommandPhase,
|
CommandPhase, EnemyCommandPhase, SelectTargetPhase,
|
||||||
TurnStartPhase
|
TurnStartPhase
|
||||||
} from "#app/phases";
|
} from "#app/phases";
|
||||||
import {Mode} from "#app/ui/ui";
|
import {Mode} from "#app/ui/ui";
|
||||||
@ -55,7 +55,6 @@ describe("Battle order", () => {
|
|||||||
(game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
(game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.run(EnemyCommandPhase);
|
await game.phaseInterceptor.run(EnemyCommandPhase);
|
||||||
await game.phaseInterceptor.whenAboutToRun(TurnStartPhase);
|
|
||||||
const phase = game.scene.getCurrentPhase() as TurnStartPhase;
|
const phase = game.scene.getCurrentPhase() as TurnStartPhase;
|
||||||
const order = phase.getOrder();
|
const order = phase.getOrder();
|
||||||
expect(order[0]).toBe(2);
|
expect(order[0]).toBe(2);
|
||||||
@ -77,7 +76,6 @@ describe("Battle order", () => {
|
|||||||
(game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
(game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.run(EnemyCommandPhase);
|
await game.phaseInterceptor.run(EnemyCommandPhase);
|
||||||
await game.phaseInterceptor.whenAboutToRun(TurnStartPhase);
|
|
||||||
const phase = game.scene.getCurrentPhase() as TurnStartPhase;
|
const phase = game.scene.getCurrentPhase() as TurnStartPhase;
|
||||||
const order = phase.getOrder();
|
const order = phase.getOrder();
|
||||||
expect(order[0]).toBe(0);
|
expect(order[0]).toBe(0);
|
||||||
@ -118,9 +116,7 @@ describe("Battle order", () => {
|
|||||||
const handler = game.scene.ui.getHandler() as TargetSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as TargetSelectUiHandler;
|
||||||
handler.processInput(Button.ACTION);
|
handler.processInput(Button.ACTION);
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.runFrom(CommandPhase).to(EnemyCommandPhase);
|
await game.phaseInterceptor.runFrom(SelectTargetPhase).to(TurnStartPhase, false);
|
||||||
await game.phaseInterceptor.run(EnemyCommandPhase);
|
|
||||||
await game.phaseInterceptor.whenAboutToRun(TurnStartPhase);
|
|
||||||
const phase = game.scene.getCurrentPhase() as TurnStartPhase;
|
const phase = game.scene.getCurrentPhase() as TurnStartPhase;
|
||||||
const order = phase.getOrder();
|
const order = phase.getOrder();
|
||||||
expect(order.indexOf(0)).toBeGreaterThan(order.indexOf(2));
|
expect(order.indexOf(0)).toBeGreaterThan(order.indexOf(2));
|
||||||
@ -163,9 +159,7 @@ describe("Battle order", () => {
|
|||||||
const handler = game.scene.ui.getHandler() as TargetSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as TargetSelectUiHandler;
|
||||||
handler.processInput(Button.ACTION);
|
handler.processInput(Button.ACTION);
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.runFrom(CommandPhase).to(EnemyCommandPhase);
|
await game.phaseInterceptor.runFrom(SelectTargetPhase).to(TurnStartPhase, false);
|
||||||
await game.phaseInterceptor.run(EnemyCommandPhase);
|
|
||||||
await game.phaseInterceptor.whenAboutToRun(TurnStartPhase);
|
|
||||||
const phase = game.scene.getCurrentPhase() as TurnStartPhase;
|
const phase = game.scene.getCurrentPhase() as TurnStartPhase;
|
||||||
const order = phase.getOrder();
|
const order = phase.getOrder();
|
||||||
expect(order.indexOf(3)).toBeLessThan(order.indexOf(0));
|
expect(order.indexOf(3)).toBeLessThan(order.indexOf(0));
|
||||||
@ -207,9 +201,7 @@ describe("Battle order", () => {
|
|||||||
const handler = game.scene.ui.getHandler() as TargetSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as TargetSelectUiHandler;
|
||||||
handler.processInput(Button.ACTION);
|
handler.processInput(Button.ACTION);
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.runFrom(CommandPhase).to(EnemyCommandPhase);
|
await game.phaseInterceptor.runFrom(SelectTargetPhase).to(TurnStartPhase, false);
|
||||||
await game.phaseInterceptor.run(EnemyCommandPhase);
|
|
||||||
await game.phaseInterceptor.whenAboutToRun(TurnStartPhase);
|
|
||||||
const phase = game.scene.getCurrentPhase() as TurnStartPhase;
|
const phase = game.scene.getCurrentPhase() as TurnStartPhase;
|
||||||
const order = phase.getOrder();
|
const order = phase.getOrder();
|
||||||
expect(order.indexOf(1)).toBeLessThan(order.indexOf(0));
|
expect(order.indexOf(1)).toBeLessThan(order.indexOf(0));
|
||||||
|
@ -1,34 +1,21 @@
|
|||||||
import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest";
|
import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest";
|
||||||
import {generateStarter, getMovePosition, waitUntil,} from "#app/test/utils/gameManagerUtils";
|
import {generateStarter, getMovePosition,} from "#app/test/utils/gameManagerUtils";
|
||||||
import {Mode} from "#app/ui/ui";
|
import {Mode} from "#app/ui/ui";
|
||||||
import {GameModes} from "#app/game-mode";
|
import {GameModes} from "#app/game-mode";
|
||||||
import {Species} from "#app/data/enums/species";
|
import {Species} from "#app/data/enums/species";
|
||||||
import * as overrides from "../../overrides";
|
import * as overrides from "../../overrides";
|
||||||
import {Command} from "#app/ui/command-ui-handler";
|
import {Command} from "#app/ui/command-ui-handler";
|
||||||
import {
|
import {
|
||||||
BattleEndPhase,
|
|
||||||
BerryPhase,
|
|
||||||
CommandPhase,
|
CommandPhase,
|
||||||
DamagePhase,
|
|
||||||
EggLapsePhase,
|
|
||||||
EncounterPhase,
|
EncounterPhase,
|
||||||
EnemyCommandPhase,
|
EnemyCommandPhase,
|
||||||
FaintPhase,
|
|
||||||
LoginPhase,
|
LoginPhase,
|
||||||
MessagePhase,
|
|
||||||
MoveEffectPhase,
|
|
||||||
MoveEndPhase,
|
|
||||||
MovePhase,
|
|
||||||
PostSummonPhase,
|
|
||||||
SelectGenderPhase,
|
SelectGenderPhase,
|
||||||
SelectModifierPhase,
|
SelectModifierPhase,
|
||||||
SelectStarterPhase,
|
SelectStarterPhase,
|
||||||
StatChangePhase,
|
SummonPhase,
|
||||||
TitlePhase,
|
TitlePhase,
|
||||||
TurnEndPhase,
|
|
||||||
TurnInitPhase,
|
TurnInitPhase,
|
||||||
TurnStartPhase,
|
|
||||||
VictoryPhase,
|
|
||||||
} from "#app/phases";
|
} from "#app/phases";
|
||||||
import {Moves} from "#app/data/enums/moves";
|
import {Moves} from "#app/data/enums/moves";
|
||||||
import GameManager from "#app/test/utils/gameManager";
|
import GameManager from "#app/test/utils/gameManager";
|
||||||
@ -36,6 +23,7 @@ import Phaser from "phaser";
|
|||||||
import {allSpecies} from "#app/data/pokemon-species";
|
import {allSpecies} from "#app/data/pokemon-species";
|
||||||
import {PlayerGender} from "#app/data/enums/player-gender";
|
import {PlayerGender} from "#app/data/enums/player-gender";
|
||||||
import { getGameMode } from "#app/game-mode.js";
|
import { getGameMode } from "#app/game-mode.js";
|
||||||
|
import {Abilities} from "#app/data/enums/abilities";
|
||||||
|
|
||||||
describe("Test Battle Phase", () => {
|
describe("Test Battle Phase", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
@ -55,22 +43,6 @@ describe("Test Battle Phase", () => {
|
|||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("test phase interceptor with remove", async() => {
|
|
||||||
await game.phaseInterceptor.run(LoginPhase);
|
|
||||||
|
|
||||||
await game.phaseInterceptor.run(LoginPhase, () => {
|
|
||||||
return game.phaseInterceptor.log.includes("LoginPhase");
|
|
||||||
});
|
|
||||||
|
|
||||||
game.scene.gameData.gender = PlayerGender.MALE;
|
|
||||||
await game.phaseInterceptor.remove(SelectGenderPhase, () => game.isCurrentPhase(TitlePhase));
|
|
||||||
|
|
||||||
await game.phaseInterceptor.run(TitlePhase);
|
|
||||||
await waitUntil(() => game.scene.ui?.getMode() === Mode.TITLE);
|
|
||||||
|
|
||||||
expect(game.scene.ui?.getMode()).toBe(Mode.TITLE);
|
|
||||||
}, 100000);
|
|
||||||
|
|
||||||
it("test phase interceptor with prompt", async() => {
|
it("test phase interceptor with prompt", async() => {
|
||||||
await game.phaseInterceptor.run(LoginPhase);
|
await game.phaseInterceptor.run(LoginPhase);
|
||||||
|
|
||||||
@ -87,7 +59,7 @@ describe("Test Battle Phase", () => {
|
|||||||
|
|
||||||
expect(game.scene.ui?.getMode()).toBe(Mode.TITLE);
|
expect(game.scene.ui?.getMode()).toBe(Mode.TITLE);
|
||||||
expect(game.scene.gameData.gender).toBe(PlayerGender.MALE);
|
expect(game.scene.gameData.gender).toBe(PlayerGender.MALE);
|
||||||
}, 100000);
|
}, 20000);
|
||||||
|
|
||||||
it("test phase interceptor with prompt with preparation for a future prompt", async() => {
|
it("test phase interceptor with prompt with preparation for a future prompt", async() => {
|
||||||
await game.phaseInterceptor.run(LoginPhase);
|
await game.phaseInterceptor.run(LoginPhase);
|
||||||
@ -109,13 +81,13 @@ describe("Test Battle Phase", () => {
|
|||||||
|
|
||||||
expect(game.scene.ui?.getMode()).toBe(Mode.TITLE);
|
expect(game.scene.ui?.getMode()).toBe(Mode.TITLE);
|
||||||
expect(game.scene.gameData.gender).toBe(PlayerGender.MALE);
|
expect(game.scene.gameData.gender).toBe(PlayerGender.MALE);
|
||||||
}, 100000);
|
}, 20000);
|
||||||
|
|
||||||
it("newGame one-liner", async() => {
|
it("newGame one-liner", async() => {
|
||||||
await game.startBattle();
|
await game.startBattle();
|
||||||
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
||||||
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
||||||
}, 100000);
|
}, 20000);
|
||||||
|
|
||||||
it("do attack wave 3 - single battle - regular - OHKO", async() => {
|
it("do attack wave 3 - single battle - regular - OHKO", async() => {
|
||||||
vi.spyOn(overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO);
|
vi.spyOn(overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO);
|
||||||
@ -123,6 +95,8 @@ describe("Test Battle Phase", () => {
|
|||||||
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000);
|
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000);
|
||||||
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3);
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3);
|
||||||
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]);
|
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]);
|
||||||
|
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]);
|
||||||
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
await game.startBattle();
|
await game.startBattle();
|
||||||
game.onNextPrompt("CommandPhase", Mode.COMMAND, () => {
|
game.onNextPrompt("CommandPhase", Mode.COMMAND, () => {
|
||||||
@ -132,28 +106,10 @@ describe("Test Battle Phase", () => {
|
|||||||
const movePosition = getMovePosition(game.scene, 0, Moves.TACKLE);
|
const movePosition = getMovePosition(game.scene, 0, Moves.TACKLE);
|
||||||
(game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
(game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.run(EnemyCommandPhase);
|
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(SelectModifierPhase);
|
||||||
await game.phaseInterceptor.run(TurnStartPhase);
|
|
||||||
|
|
||||||
await game.phaseInterceptor.run(MovePhase);
|
|
||||||
await game.phaseInterceptor.run(MessagePhase);
|
|
||||||
await game.phaseInterceptor.run(MoveEffectPhase);
|
|
||||||
await game.phaseInterceptor.run(DamagePhase);
|
|
||||||
await game.phaseInterceptor.run(MessagePhase, () => game.isCurrentPhase(FaintPhase));
|
|
||||||
await game.phaseInterceptor.run(FaintPhase);
|
|
||||||
await game.phaseInterceptor.run(MessagePhase);
|
|
||||||
|
|
||||||
await game.phaseInterceptor.run(VictoryPhase);
|
|
||||||
await game.phaseInterceptor.run(MoveEndPhase);
|
|
||||||
await game.phaseInterceptor.run(MovePhase);
|
|
||||||
await game.phaseInterceptor.run(BerryPhase);
|
|
||||||
await game.phaseInterceptor.run(TurnEndPhase);
|
|
||||||
await game.phaseInterceptor.run(BattleEndPhase);
|
|
||||||
await game.phaseInterceptor.run(EggLapsePhase);
|
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
|
||||||
expect(game.scene.ui?.getMode()).toBe(Mode.MODIFIER_SELECT);
|
expect(game.scene.ui?.getMode()).toBe(Mode.MODIFIER_SELECT);
|
||||||
expect(game.scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(game.scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
||||||
}, 100000);
|
}, 20000);
|
||||||
|
|
||||||
it("do attack wave 3 - single battle - regular - NO OHKO with opponent using non damage attack", async() => {
|
it("do attack wave 3 - single battle - regular - NO OHKO with opponent using non damage attack", async() => {
|
||||||
vi.spyOn(overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO);
|
vi.spyOn(overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO);
|
||||||
@ -161,7 +117,8 @@ describe("Test Battle Phase", () => {
|
|||||||
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(5);
|
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(5);
|
||||||
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3);
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3);
|
||||||
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]);
|
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]);
|
||||||
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TAIL_WHIP]);
|
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TAIL_WHIP, Moves.TAIL_WHIP, Moves.TAIL_WHIP, Moves.TAIL_WHIP]);
|
||||||
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
await game.startBattle();
|
await game.startBattle();
|
||||||
game.onNextPrompt("CommandPhase", Mode.COMMAND, () => {
|
game.onNextPrompt("CommandPhase", Mode.COMMAND, () => {
|
||||||
@ -171,35 +128,8 @@ describe("Test Battle Phase", () => {
|
|||||||
const movePosition = getMovePosition(game.scene, 0, Moves.TACKLE);
|
const movePosition = getMovePosition(game.scene, 0, Moves.TACKLE);
|
||||||
(game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
(game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.run(EnemyCommandPhase);
|
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(TurnInitPhase);
|
||||||
await game.phaseInterceptor.run(TurnStartPhase);
|
}, 20000);
|
||||||
|
|
||||||
await game.phaseInterceptor.run(MovePhase);
|
|
||||||
await game.phaseInterceptor.run(MessagePhase);
|
|
||||||
await game.phaseInterceptor.run(MoveEffectPhase);
|
|
||||||
await game.phaseInterceptor.run(DamagePhase);
|
|
||||||
await game.phaseInterceptor.run(MessagePhase, () => game.isCurrentPhase(MoveEndPhase));
|
|
||||||
await game.phaseInterceptor.run(MoveEndPhase);
|
|
||||||
|
|
||||||
await game.phaseInterceptor.run(MovePhase);
|
|
||||||
await game.phaseInterceptor.run(MessagePhase, () => game.isCurrentPhase(MoveEffectPhase));
|
|
||||||
await game.phaseInterceptor.run(MoveEffectPhase);
|
|
||||||
game.scene.moveAnimations = null; // Mandatory to avoid the crash
|
|
||||||
await game.phaseInterceptor.run(StatChangePhase, () => game.isCurrentPhase(MessagePhase) || game.isCurrentPhase(MoveEndPhase) || game.isCurrentPhase(DamagePhase));
|
|
||||||
await game.phaseInterceptor.run(DamagePhase, () => game.isCurrentPhase(MessagePhase) || game.isCurrentPhase(MoveEndPhase));
|
|
||||||
await game.phaseInterceptor.run(MessagePhase, () => game.isCurrentPhase(MoveEndPhase));
|
|
||||||
await game.phaseInterceptor.run(MoveEndPhase);
|
|
||||||
|
|
||||||
await game.phaseInterceptor.run(BerryPhase);
|
|
||||||
await game.phaseInterceptor.run(MessagePhase, () => game.isCurrentPhase(TurnEndPhase));
|
|
||||||
await game.phaseInterceptor.run(TurnEndPhase);
|
|
||||||
|
|
||||||
await game.phaseInterceptor.run(TurnInitPhase);
|
|
||||||
await game.phaseInterceptor.run(CommandPhase);
|
|
||||||
await waitUntil(() => game.scene.ui?.getMode() === Mode.COMMAND);
|
|
||||||
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
|
||||||
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
|
||||||
}, 100000);
|
|
||||||
|
|
||||||
it("load 100% data file", async() => {
|
it("load 100% data file", async() => {
|
||||||
await game.importData("src/test/utils/saves/everything.prsv");
|
await game.importData("src/test/utils/saves/everything.prsv");
|
||||||
@ -208,7 +138,7 @@ describe("Test Battle Phase", () => {
|
|||||||
return species.caughtAttr !== 0n;
|
return species.caughtAttr !== 0n;
|
||||||
}).length;
|
}).length;
|
||||||
expect(caughtCount).toBe(Object.keys(allSpecies).length);
|
expect(caughtCount).toBe(Object.keys(allSpecies).length);
|
||||||
}, 50000);
|
}, 20000);
|
||||||
|
|
||||||
it("start battle with selected team", async() => {
|
it("start battle with selected team", async() => {
|
||||||
await game.startBattle([
|
await game.startBattle([
|
||||||
@ -219,26 +149,7 @@ describe("Test Battle Phase", () => {
|
|||||||
expect(game.scene.getParty()[0].species.speciesId).toBe(Species.CHARIZARD);
|
expect(game.scene.getParty()[0].species.speciesId).toBe(Species.CHARIZARD);
|
||||||
expect(game.scene.getParty()[1].species.speciesId).toBe(Species.CHANSEY);
|
expect(game.scene.getParty()[1].species.speciesId).toBe(Species.CHANSEY);
|
||||||
expect(game.scene.getParty()[2].species.speciesId).toBe(Species.MEW);
|
expect(game.scene.getParty()[2].species.speciesId).toBe(Species.MEW);
|
||||||
}, 50000);
|
}, 20000);
|
||||||
|
|
||||||
it("assert next phase", async() => {
|
|
||||||
await game.phaseInterceptor.run(LoginPhase);
|
|
||||||
game.onNextPrompt("SelectGenderPhase", Mode.OPTION_SELECT, () => {
|
|
||||||
game.scene.gameData.gender = PlayerGender.MALE;
|
|
||||||
game.endPhase();
|
|
||||||
}, () => game.isCurrentPhase(TitlePhase));
|
|
||||||
await game.phaseInterceptor.mustRun(SelectGenderPhase).catch((error) => expect(error).toBe(SelectGenderPhase));
|
|
||||||
await game.phaseInterceptor.mustRun(TitlePhase).catch((error) => expect(error).toBe(TitlePhase));
|
|
||||||
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
|
||||||
game.scene.gameMode = getGameMode(GameModes.CLASSIC);
|
|
||||||
const starters = generateStarter(game.scene);
|
|
||||||
const selectStarterPhase = new SelectStarterPhase(game.scene);
|
|
||||||
game.scene.pushPhase(new EncounterPhase(game.scene, false));
|
|
||||||
selectStarterPhase.initBattle(starters);
|
|
||||||
});
|
|
||||||
await game.phaseInterceptor.mustRun(EncounterPhase).catch((error) => expect(error).toBe(EncounterPhase));
|
|
||||||
await game.phaseInterceptor.mustRun(PostSummonPhase).catch((error) => expect(error).toBe(PostSummonPhase));
|
|
||||||
}, 50000);
|
|
||||||
|
|
||||||
it("test remove random battle seed int", async() => {
|
it("test remove random battle seed int", async() => {
|
||||||
for (let i=0; i<10; i++) {
|
for (let i=0; i<10; i++) {
|
||||||
@ -246,5 +157,107 @@ describe("Test Battle Phase", () => {
|
|||||||
expect(rand).toBe(14);
|
expect(rand).toBe(14);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("wrong phase", async() => {
|
||||||
|
await game.phaseInterceptor.run(LoginPhase);
|
||||||
|
await game.phaseInterceptor.run(LoginPhase).catch((e) => {
|
||||||
|
expect(e).toBe("Wrong phase: this is SelectGenderPhase and not LoginPhase");
|
||||||
|
});
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("wrong phase but skip", async() => {
|
||||||
|
await game.phaseInterceptor.run(LoginPhase);
|
||||||
|
await game.phaseInterceptor.run(LoginPhase, () => game.isCurrentPhase(SelectGenderPhase));
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("good run", async() => {
|
||||||
|
await game.phaseInterceptor.run(LoginPhase);
|
||||||
|
game.onNextPrompt("SelectGenderPhase", Mode.OPTION_SELECT, () => {
|
||||||
|
game.scene.gameData.gender = PlayerGender.MALE;
|
||||||
|
game.endPhase();
|
||||||
|
}, () => game.isCurrentPhase(TitlePhase));
|
||||||
|
await game.phaseInterceptor.run(SelectGenderPhase, () => game.isCurrentPhase(TitlePhase));
|
||||||
|
await game.phaseInterceptor.run(TitlePhase);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("good run from select gender to title", async() => {
|
||||||
|
await game.phaseInterceptor.run(LoginPhase);
|
||||||
|
game.onNextPrompt("SelectGenderPhase", Mode.OPTION_SELECT, () => {
|
||||||
|
game.scene.gameData.gender = PlayerGender.MALE;
|
||||||
|
game.endPhase();
|
||||||
|
}, () => game.isCurrentPhase(TitlePhase));
|
||||||
|
await game.phaseInterceptor.runFrom(SelectGenderPhase).to(TitlePhase);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("good run to SummonPhase phase", async() => {
|
||||||
|
await game.phaseInterceptor.run(LoginPhase);
|
||||||
|
game.onNextPrompt("SelectGenderPhase", Mode.OPTION_SELECT, () => {
|
||||||
|
game.scene.gameData.gender = PlayerGender.MALE;
|
||||||
|
game.endPhase();
|
||||||
|
}, () => game.isCurrentPhase(TitlePhase));
|
||||||
|
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
||||||
|
game.scene.gameMode = getGameMode(GameModes.CLASSIC);
|
||||||
|
const starters = generateStarter(game.scene);
|
||||||
|
const selectStarterPhase = new SelectStarterPhase(game.scene);
|
||||||
|
game.scene.pushPhase(new EncounterPhase(game.scene, false));
|
||||||
|
selectStarterPhase.initBattle(starters);
|
||||||
|
});
|
||||||
|
await game.phaseInterceptor.runFrom(SelectGenderPhase).to(SummonPhase);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("2vs1", async() => {
|
||||||
|
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MIGHTYENA);
|
||||||
|
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
await game.startBattle([
|
||||||
|
Species.BLASTOISE,
|
||||||
|
Species.CHARIZARD,
|
||||||
|
]);
|
||||||
|
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
||||||
|
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("1vs1", async() => {
|
||||||
|
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MIGHTYENA);
|
||||||
|
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
await game.startBattle([
|
||||||
|
Species.BLASTOISE,
|
||||||
|
]);
|
||||||
|
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
||||||
|
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("2vs2", async() => {
|
||||||
|
vi.spyOn(overrides, "DOUBLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MIGHTYENA);
|
||||||
|
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3);
|
||||||
|
await game.startBattle([
|
||||||
|
Species.BLASTOISE,
|
||||||
|
Species.CHARIZARD,
|
||||||
|
]);
|
||||||
|
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
||||||
|
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
it("4vs2", async() => {
|
||||||
|
vi.spyOn(overrides, "DOUBLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MIGHTYENA);
|
||||||
|
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3);
|
||||||
|
await game.startBattle([
|
||||||
|
Species.BLASTOISE,
|
||||||
|
Species.CHARIZARD,
|
||||||
|
Species.DARKRAI,
|
||||||
|
Species.GABITE,
|
||||||
|
]);
|
||||||
|
expect(game.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
||||||
|
expect(game.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
||||||
|
}, 20000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
39
src/test/battle/error-handling.test.ts
Normal file
39
src/test/battle/error-handling.test.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import {afterEach, beforeAll, beforeEach, describe, it, vi} from "vitest";
|
||||||
|
import GameManager from "#app/test/utils/gameManager";
|
||||||
|
import Phaser from "phaser";
|
||||||
|
import * as overrides from "#app/overrides";
|
||||||
|
import {Species} from "#app/data/enums/species";
|
||||||
|
import {Moves} from "#app/data/enums/moves";
|
||||||
|
import {Abilities} from "#app/data/enums/abilities";
|
||||||
|
|
||||||
|
describe("Test Battle Phase", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should start phase", async() => {
|
||||||
|
vi.spyOn(overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO);
|
||||||
|
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA);
|
||||||
|
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000);
|
||||||
|
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3);
|
||||||
|
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]);
|
||||||
|
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION);
|
||||||
|
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]);
|
||||||
|
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
|
||||||
|
await game.startBattle();
|
||||||
|
}, 100000);
|
||||||
|
});
|
||||||
|
|
@ -28,7 +28,8 @@ describe("Phases", () => {
|
|||||||
describe("LoginPhase", () => {
|
describe("LoginPhase", () => {
|
||||||
it("should start the login phase", async () => {
|
it("should start the login phase", async () => {
|
||||||
const loginPhase = new LoginPhase(scene);
|
const loginPhase = new LoginPhase(scene);
|
||||||
loginPhase.start();
|
scene.pushPhase(loginPhase);
|
||||||
|
await game.phaseInterceptor.run(LoginPhase);
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MESSAGE);
|
expect(scene.ui.getMode()).to.equal(Mode.MESSAGE);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -36,16 +37,18 @@ describe("Phases", () => {
|
|||||||
describe("TitlePhase", () => {
|
describe("TitlePhase", () => {
|
||||||
it("should start the title phase", async () => {
|
it("should start the title phase", async () => {
|
||||||
const titlePhase = new TitlePhase(scene);
|
const titlePhase = new TitlePhase(scene);
|
||||||
titlePhase.start();
|
scene.pushPhase(titlePhase);
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MESSAGE);
|
await game.phaseInterceptor.run(TitlePhase);
|
||||||
|
expect(scene.ui.getMode()).to.equal(Mode.TITLE);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("UnavailablePhase", () => {
|
describe("UnavailablePhase", () => {
|
||||||
it("should start the unavailable phase", async () => {
|
it("should start the unavailable phase", async () => {
|
||||||
const unavailablePhase = new UnavailablePhase(scene);
|
const unavailablePhase = new UnavailablePhase(scene);
|
||||||
unavailablePhase.start();
|
scene.pushPhase(unavailablePhase);
|
||||||
|
await game.phaseInterceptor.run(UnavailablePhase);
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.UNAVAILABLE);
|
expect(scene.ui.getMode()).to.equal(Mode.UNAVAILABLE);
|
||||||
});
|
}, 20000);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -15,9 +15,9 @@ import OptionSelectUiHandler from "#app/ui/settings/option-select-ui-handler";
|
|||||||
import SaveSlotSelectUiHandler from "#app/ui/save-slot-select-ui-handler";
|
import SaveSlotSelectUiHandler from "#app/ui/save-slot-select-ui-handler";
|
||||||
import {OptionSelectItem} from "#app/ui/abstact-option-select-ui-handler";
|
import {OptionSelectItem} from "#app/ui/abstact-option-select-ui-handler";
|
||||||
import {Gender} from "#app/data/gender";
|
import {Gender} from "#app/data/gender";
|
||||||
|
import {allSpecies} from "#app/data/pokemon-species";
|
||||||
import {Nature} from "#app/data/nature";
|
import {Nature} from "#app/data/nature";
|
||||||
import {Abilities} from "#app/data/enums/abilities";
|
import {Abilities} from "#app/data/enums/abilities";
|
||||||
import {allSpecies} from "#app/data/pokemon-species";
|
|
||||||
|
|
||||||
|
|
||||||
describe("UI - Starter select", () => {
|
describe("UI - Starter select", () => {
|
||||||
@ -51,12 +51,13 @@ describe("UI - Starter select", () => {
|
|||||||
currentPhase.gameMode = GameModes.CLASSIC;
|
currentPhase.gameMode = GameModes.CLASSIC;
|
||||||
currentPhase.end();
|
currentPhase.end();
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.mustRun(SelectStarterPhase).catch((error) => expect(error).toBe(SelectStarterPhase));
|
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.RIGHT);
|
handler.processInput(Button.RIGHT);
|
||||||
handler.processInput(Button.ACTION);
|
handler.processInput(Button.ACTION);
|
||||||
|
game.phaseInterceptor.unlock();
|
||||||
});
|
});
|
||||||
|
await game.phaseInterceptor.run(SelectStarterPhase);
|
||||||
let options: OptionSelectItem[];
|
let options: OptionSelectItem[];
|
||||||
let optionSelectUiHandler: OptionSelectUiHandler;
|
let optionSelectUiHandler: OptionSelectUiHandler;
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
@ -73,6 +74,7 @@ describe("UI - Starter select", () => {
|
|||||||
expect(options.some(option => option.label === "Cancel")).toBe(true);
|
expect(options.some(option => option.label === "Cancel")).toBe(true);
|
||||||
optionSelectUiHandler.processInput(Button.ACTION);
|
optionSelectUiHandler.processInput(Button.ACTION);
|
||||||
|
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.SUBMIT);
|
handler.processInput(Button.SUBMIT);
|
||||||
@ -84,10 +86,8 @@ describe("UI - Starter select", () => {
|
|||||||
game.onNextPrompt("SelectStarterPhase", Mode.SAVE_SLOT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.SAVE_SLOT, () => {
|
||||||
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
||||||
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
||||||
|
resolve();
|
||||||
});
|
});
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.CONFIRM, () => {
|
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
|
||||||
handler.processInput(Button.ACTION);
|
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||||
|
|
||||||
@ -99,19 +99,25 @@ describe("UI - Starter select", () => {
|
|||||||
|
|
||||||
it("Bulbasaur - shiny - variant 2 female hardy overgrow", async() => {
|
it("Bulbasaur - shiny - variant 2 female hardy overgrow", async() => {
|
||||||
await game.importData("src/test/utils/saves/everything.prsv");
|
await game.importData("src/test/utils/saves/everything.prsv");
|
||||||
|
const caughtCount = Object.keys(game.scene.gameData.dexData).filter((key) => {
|
||||||
|
const species = game.scene.gameData.dexData[key];
|
||||||
|
return species.caughtAttr !== 0n;
|
||||||
|
}).length;
|
||||||
|
expect(caughtCount).toBe(Object.keys(allSpecies).length);
|
||||||
await game.runToTitle();
|
await game.runToTitle();
|
||||||
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
||||||
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
||||||
currentPhase.gameMode = GameModes.CLASSIC;
|
currentPhase.gameMode = GameModes.CLASSIC;
|
||||||
currentPhase.end();
|
currentPhase.end();
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.mustRun(SelectStarterPhase).catch((error) => expect(error).toBe(SelectStarterPhase));
|
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.RIGHT);
|
handler.processInput(Button.RIGHT);
|
||||||
handler.processInput(Button.CYCLE_GENDER);
|
handler.processInput(Button.CYCLE_GENDER);
|
||||||
handler.processInput(Button.ACTION);
|
handler.processInput(Button.ACTION);
|
||||||
|
game.phaseInterceptor.unlock();
|
||||||
});
|
});
|
||||||
|
await game.phaseInterceptor.run(SelectStarterPhase);
|
||||||
let options: OptionSelectItem[];
|
let options: OptionSelectItem[];
|
||||||
let optionSelectUiHandler: OptionSelectUiHandler;
|
let optionSelectUiHandler: OptionSelectUiHandler;
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
@ -128,6 +134,7 @@ describe("UI - Starter select", () => {
|
|||||||
expect(options.some(option => option.label === "Cancel")).toBe(true);
|
expect(options.some(option => option.label === "Cancel")).toBe(true);
|
||||||
optionSelectUiHandler.processInput(Button.ACTION);
|
optionSelectUiHandler.processInput(Button.ACTION);
|
||||||
|
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.SUBMIT);
|
handler.processInput(Button.SUBMIT);
|
||||||
@ -139,10 +146,8 @@ describe("UI - Starter select", () => {
|
|||||||
game.onNextPrompt("SelectStarterPhase", Mode.SAVE_SLOT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.SAVE_SLOT, () => {
|
||||||
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
||||||
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
||||||
|
resolve();
|
||||||
});
|
});
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.CONFIRM, () => {
|
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
|
||||||
handler.processInput(Button.ACTION);
|
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||||
|
|
||||||
@ -153,15 +158,19 @@ describe("UI - Starter select", () => {
|
|||||||
expect(game.scene.getParty()[0].getAbility().id).toBe(Abilities.OVERGROW);
|
expect(game.scene.getParty()[0].getAbility().id).toBe(Abilities.OVERGROW);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
|
||||||
it("Bulbasaur - shiny - variant 2 female lonely cholorophyl", async() => {
|
it("Bulbasaur - shiny - variant 2 female lonely chlorophyl", async() => {
|
||||||
await game.importData("src/test/utils/saves/everything.prsv");
|
await game.importData("src/test/utils/saves/everything.prsv");
|
||||||
|
const caughtCount = Object.keys(game.scene.gameData.dexData).filter((key) => {
|
||||||
|
const species = game.scene.gameData.dexData[key];
|
||||||
|
return species.caughtAttr !== 0n;
|
||||||
|
}).length;
|
||||||
|
expect(caughtCount).toBe(Object.keys(allSpecies).length);
|
||||||
await game.runToTitle();
|
await game.runToTitle();
|
||||||
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
||||||
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
||||||
currentPhase.gameMode = GameModes.CLASSIC;
|
currentPhase.gameMode = GameModes.CLASSIC;
|
||||||
currentPhase.end();
|
currentPhase.end();
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.mustRun(SelectStarterPhase).catch((error) => expect(error).toBe(SelectStarterPhase));
|
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.RIGHT);
|
handler.processInput(Button.RIGHT);
|
||||||
@ -169,7 +178,9 @@ describe("UI - Starter select", () => {
|
|||||||
handler.processInput(Button.CYCLE_NATURE);
|
handler.processInput(Button.CYCLE_NATURE);
|
||||||
handler.processInput(Button.CYCLE_ABILITY);
|
handler.processInput(Button.CYCLE_ABILITY);
|
||||||
handler.processInput(Button.ACTION);
|
handler.processInput(Button.ACTION);
|
||||||
|
game.phaseInterceptor.unlock();
|
||||||
});
|
});
|
||||||
|
await game.phaseInterceptor.run(SelectStarterPhase);
|
||||||
let options: OptionSelectItem[];
|
let options: OptionSelectItem[];
|
||||||
let optionSelectUiHandler: OptionSelectUiHandler;
|
let optionSelectUiHandler: OptionSelectUiHandler;
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
@ -186,6 +197,7 @@ describe("UI - Starter select", () => {
|
|||||||
expect(options.some(option => option.label === "Cancel")).toBe(true);
|
expect(options.some(option => option.label === "Cancel")).toBe(true);
|
||||||
optionSelectUiHandler.processInput(Button.ACTION);
|
optionSelectUiHandler.processInput(Button.ACTION);
|
||||||
|
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.SUBMIT);
|
handler.processInput(Button.SUBMIT);
|
||||||
@ -197,10 +209,8 @@ describe("UI - Starter select", () => {
|
|||||||
game.onNextPrompt("SelectStarterPhase", Mode.SAVE_SLOT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.SAVE_SLOT, () => {
|
||||||
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
||||||
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
||||||
|
resolve();
|
||||||
});
|
});
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.CONFIRM, () => {
|
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
|
||||||
handler.processInput(Button.ACTION);
|
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||||
|
|
||||||
@ -211,21 +221,27 @@ describe("UI - Starter select", () => {
|
|||||||
expect(game.scene.getParty()[0].getAbility().id).toBe(Abilities.CHLOROPHYLL);
|
expect(game.scene.getParty()[0].getAbility().id).toBe(Abilities.CHLOROPHYLL);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
|
||||||
it("Bulbasaur - shiny - variant 2 female", async() => {
|
it("Bulbasaur - shiny - variant 2 female lonely chlorophyl", async() => {
|
||||||
await game.importData("src/test/utils/saves/everything.prsv");
|
await game.importData("src/test/utils/saves/everything.prsv");
|
||||||
|
const caughtCount = Object.keys(game.scene.gameData.dexData).filter((key) => {
|
||||||
|
const species = game.scene.gameData.dexData[key];
|
||||||
|
return species.caughtAttr !== 0n;
|
||||||
|
}).length;
|
||||||
|
expect(caughtCount).toBe(Object.keys(allSpecies).length);
|
||||||
await game.runToTitle();
|
await game.runToTitle();
|
||||||
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
||||||
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
||||||
currentPhase.gameMode = GameModes.CLASSIC;
|
currentPhase.gameMode = GameModes.CLASSIC;
|
||||||
currentPhase.end();
|
currentPhase.end();
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.mustRun(SelectStarterPhase).catch((error) => expect(error).toBe(SelectStarterPhase));
|
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.RIGHT);
|
handler.processInput(Button.RIGHT);
|
||||||
handler.processInput(Button.CYCLE_GENDER);
|
handler.processInput(Button.CYCLE_GENDER);
|
||||||
handler.processInput(Button.ACTION);
|
handler.processInput(Button.ACTION);
|
||||||
|
game.phaseInterceptor.unlock();
|
||||||
});
|
});
|
||||||
|
await game.phaseInterceptor.run(SelectStarterPhase);
|
||||||
let options: OptionSelectItem[];
|
let options: OptionSelectItem[];
|
||||||
let optionSelectUiHandler: OptionSelectUiHandler;
|
let optionSelectUiHandler: OptionSelectUiHandler;
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
@ -242,6 +258,7 @@ describe("UI - Starter select", () => {
|
|||||||
expect(options.some(option => option.label === "Cancel")).toBe(true);
|
expect(options.some(option => option.label === "Cancel")).toBe(true);
|
||||||
optionSelectUiHandler.processInput(Button.ACTION);
|
optionSelectUiHandler.processInput(Button.ACTION);
|
||||||
|
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.SUBMIT);
|
handler.processInput(Button.SUBMIT);
|
||||||
@ -253,10 +270,8 @@ describe("UI - Starter select", () => {
|
|||||||
game.onNextPrompt("SelectStarterPhase", Mode.SAVE_SLOT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.SAVE_SLOT, () => {
|
||||||
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
||||||
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
||||||
|
resolve();
|
||||||
});
|
});
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.CONFIRM, () => {
|
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
|
||||||
handler.processInput(Button.ACTION);
|
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||||
|
|
||||||
@ -268,19 +283,25 @@ describe("UI - Starter select", () => {
|
|||||||
|
|
||||||
it("Bulbasaur - not shiny", async() => {
|
it("Bulbasaur - not shiny", async() => {
|
||||||
await game.importData("src/test/utils/saves/everything.prsv");
|
await game.importData("src/test/utils/saves/everything.prsv");
|
||||||
|
const caughtCount = Object.keys(game.scene.gameData.dexData).filter((key) => {
|
||||||
|
const species = game.scene.gameData.dexData[key];
|
||||||
|
return species.caughtAttr !== 0n;
|
||||||
|
}).length;
|
||||||
|
expect(caughtCount).toBe(Object.keys(allSpecies).length);
|
||||||
await game.runToTitle();
|
await game.runToTitle();
|
||||||
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
||||||
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
||||||
currentPhase.gameMode = GameModes.CLASSIC;
|
currentPhase.gameMode = GameModes.CLASSIC;
|
||||||
currentPhase.end();
|
currentPhase.end();
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.mustRun(SelectStarterPhase).catch((error) => expect(error).toBe(SelectStarterPhase));
|
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.RIGHT);
|
handler.processInput(Button.RIGHT);
|
||||||
handler.processInput(Button.CYCLE_SHINY);
|
handler.processInput(Button.CYCLE_SHINY);
|
||||||
handler.processInput(Button.ACTION);
|
handler.processInput(Button.ACTION);
|
||||||
|
game.phaseInterceptor.unlock();
|
||||||
});
|
});
|
||||||
|
await game.phaseInterceptor.run(SelectStarterPhase);
|
||||||
let options: OptionSelectItem[];
|
let options: OptionSelectItem[];
|
||||||
let optionSelectUiHandler: OptionSelectUiHandler;
|
let optionSelectUiHandler: OptionSelectUiHandler;
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
@ -297,6 +318,7 @@ describe("UI - Starter select", () => {
|
|||||||
expect(options.some(option => option.label === "Cancel")).toBe(true);
|
expect(options.some(option => option.label === "Cancel")).toBe(true);
|
||||||
optionSelectUiHandler.processInput(Button.ACTION);
|
optionSelectUiHandler.processInput(Button.ACTION);
|
||||||
|
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.SUBMIT);
|
handler.processInput(Button.SUBMIT);
|
||||||
@ -308,10 +330,8 @@ describe("UI - Starter select", () => {
|
|||||||
game.onNextPrompt("SelectStarterPhase", Mode.SAVE_SLOT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.SAVE_SLOT, () => {
|
||||||
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
||||||
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
||||||
|
resolve();
|
||||||
});
|
});
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.CONFIRM, () => {
|
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
|
||||||
handler.processInput(Button.ACTION);
|
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||||
|
|
||||||
@ -320,76 +340,28 @@ describe("UI - Starter select", () => {
|
|||||||
expect(game.scene.getParty()[0].variant).toBe(0);
|
expect(game.scene.getParty()[0].variant).toBe(0);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
|
||||||
it("Bulbasaur - shiny - variant 0", async() => {
|
|
||||||
await game.importData("src/test/utils/saves/everything.prsv");
|
|
||||||
await game.runToTitle();
|
|
||||||
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
|
||||||
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
|
||||||
currentPhase.gameMode = GameModes.CLASSIC;
|
|
||||||
currentPhase.end();
|
|
||||||
});
|
|
||||||
await game.phaseInterceptor.mustRun(SelectStarterPhase).catch((error) => expect(error).toBe(SelectStarterPhase));
|
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
|
||||||
handler.processInput(Button.RIGHT);
|
|
||||||
handler.processInput(Button.V);
|
|
||||||
handler.processInput(Button.ACTION);
|
|
||||||
});
|
|
||||||
let options: OptionSelectItem[];
|
|
||||||
let optionSelectUiHandler: OptionSelectUiHandler;
|
|
||||||
await new Promise<void>((resolve) => {
|
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.OPTION_SELECT, () => {
|
|
||||||
optionSelectUiHandler = game.scene.ui.getHandler() as OptionSelectUiHandler;
|
|
||||||
options = optionSelectUiHandler.getOptionsWithScroll();
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
expect(options.some(option => option.label === "Add to Party")).toBe(true);
|
|
||||||
expect(options.some(option => option.label === "Toggle IVs")).toBe(true);
|
|
||||||
expect(options.some(option => option.label === "Manage Moves")).toBe(true);
|
|
||||||
expect(options.some(option => option.label === "Use Candies")).toBe(true);
|
|
||||||
expect(options.some(option => option.label === "Cancel")).toBe(true);
|
|
||||||
optionSelectUiHandler.processInput(Button.ACTION);
|
|
||||||
|
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
|
||||||
handler.processInput(Button.SUBMIT);
|
|
||||||
});
|
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.CONFIRM, () => {
|
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
|
||||||
handler.processInput(Button.ACTION);
|
|
||||||
});
|
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.SAVE_SLOT, () => {
|
|
||||||
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
|
||||||
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
|
||||||
});
|
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.CONFIRM, () => {
|
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
|
||||||
handler.processInput(Button.ACTION);
|
|
||||||
});
|
|
||||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
|
||||||
|
|
||||||
expect(game.scene.getParty()[0].species.speciesId).toBe(Species.BULBASAUR);
|
|
||||||
expect(game.scene.getParty()[0].shiny).toBe(true);
|
|
||||||
expect(game.scene.getParty()[0].variant).toBe(0);
|
|
||||||
}, 20000);
|
|
||||||
|
|
||||||
it("Bulbasaur - shiny - variant 1", async() => {
|
it("Bulbasaur - shiny - variant 1", async() => {
|
||||||
await game.importData("src/test/utils/saves/everything.prsv");
|
await game.importData("src/test/utils/saves/everything.prsv");
|
||||||
|
const caughtCount = Object.keys(game.scene.gameData.dexData).filter((key) => {
|
||||||
|
const species = game.scene.gameData.dexData[key];
|
||||||
|
return species.caughtAttr !== 0n;
|
||||||
|
}).length;
|
||||||
|
expect(caughtCount).toBe(Object.keys(allSpecies).length);
|
||||||
await game.runToTitle();
|
await game.runToTitle();
|
||||||
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
||||||
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
||||||
currentPhase.gameMode = GameModes.CLASSIC;
|
currentPhase.gameMode = GameModes.CLASSIC;
|
||||||
currentPhase.end();
|
currentPhase.end();
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.mustRun(SelectStarterPhase).catch((error) => expect(error).toBe(SelectStarterPhase));
|
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.RIGHT);
|
handler.processInput(Button.RIGHT);
|
||||||
handler.processInput(Button.V);
|
handler.processInput(Button.V);
|
||||||
handler.processInput(Button.V);
|
handler.processInput(Button.V);
|
||||||
handler.processInput(Button.ACTION);
|
handler.processInput(Button.ACTION);
|
||||||
|
game.phaseInterceptor.unlock();
|
||||||
});
|
});
|
||||||
|
await game.phaseInterceptor.run(SelectStarterPhase);
|
||||||
let options: OptionSelectItem[];
|
let options: OptionSelectItem[];
|
||||||
let optionSelectUiHandler: OptionSelectUiHandler;
|
let optionSelectUiHandler: OptionSelectUiHandler;
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
@ -406,6 +378,7 @@ describe("UI - Starter select", () => {
|
|||||||
expect(options.some(option => option.label === "Cancel")).toBe(true);
|
expect(options.some(option => option.label === "Cancel")).toBe(true);
|
||||||
optionSelectUiHandler.processInput(Button.ACTION);
|
optionSelectUiHandler.processInput(Button.ACTION);
|
||||||
|
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.SUBMIT);
|
handler.processInput(Button.SUBMIT);
|
||||||
@ -417,10 +390,8 @@ describe("UI - Starter select", () => {
|
|||||||
game.onNextPrompt("SelectStarterPhase", Mode.SAVE_SLOT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.SAVE_SLOT, () => {
|
||||||
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
||||||
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
||||||
|
resolve();
|
||||||
});
|
});
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.CONFIRM, () => {
|
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
|
||||||
handler.processInput(Button.ACTION);
|
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||||
|
|
||||||
@ -429,15 +400,19 @@ describe("UI - Starter select", () => {
|
|||||||
expect(game.scene.getParty()[0].variant).toBe(1);
|
expect(game.scene.getParty()[0].variant).toBe(1);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
|
||||||
it("Bulbasaur - shiny - variant 1", async() => {
|
it("Bulbasaur - shiny - variant 2", async() => {
|
||||||
await game.importData("src/test/utils/saves/everything.prsv");
|
await game.importData("src/test/utils/saves/everything.prsv");
|
||||||
|
const caughtCount = Object.keys(game.scene.gameData.dexData).filter((key) => {
|
||||||
|
const species = game.scene.gameData.dexData[key];
|
||||||
|
return species.caughtAttr !== 0n;
|
||||||
|
}).length;
|
||||||
|
expect(caughtCount).toBe(Object.keys(allSpecies).length);
|
||||||
await game.runToTitle();
|
await game.runToTitle();
|
||||||
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
||||||
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
||||||
currentPhase.gameMode = GameModes.CLASSIC;
|
currentPhase.gameMode = GameModes.CLASSIC;
|
||||||
currentPhase.end();
|
currentPhase.end();
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.mustRun(SelectStarterPhase).catch((error) => expect(error).toBe(SelectStarterPhase));
|
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.RIGHT);
|
handler.processInput(Button.RIGHT);
|
||||||
@ -445,7 +420,9 @@ describe("UI - Starter select", () => {
|
|||||||
handler.processInput(Button.V);
|
handler.processInput(Button.V);
|
||||||
handler.processInput(Button.V);
|
handler.processInput(Button.V);
|
||||||
handler.processInput(Button.ACTION);
|
handler.processInput(Button.ACTION);
|
||||||
|
game.phaseInterceptor.unlock();
|
||||||
});
|
});
|
||||||
|
await game.phaseInterceptor.run(SelectStarterPhase);
|
||||||
let options: OptionSelectItem[];
|
let options: OptionSelectItem[];
|
||||||
let optionSelectUiHandler: OptionSelectUiHandler;
|
let optionSelectUiHandler: OptionSelectUiHandler;
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
@ -462,6 +439,7 @@ describe("UI - Starter select", () => {
|
|||||||
expect(options.some(option => option.label === "Cancel")).toBe(true);
|
expect(options.some(option => option.label === "Cancel")).toBe(true);
|
||||||
optionSelectUiHandler.processInput(Button.ACTION);
|
optionSelectUiHandler.processInput(Button.ACTION);
|
||||||
|
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.SUBMIT);
|
handler.processInput(Button.SUBMIT);
|
||||||
@ -473,10 +451,8 @@ describe("UI - Starter select", () => {
|
|||||||
game.onNextPrompt("SelectStarterPhase", Mode.SAVE_SLOT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.SAVE_SLOT, () => {
|
||||||
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
||||||
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
||||||
|
resolve();
|
||||||
});
|
});
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.CONFIRM, () => {
|
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
|
||||||
handler.processInput(Button.ACTION);
|
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||||
|
|
||||||
@ -485,15 +461,19 @@ describe("UI - Starter select", () => {
|
|||||||
expect(game.scene.getParty()[0].variant).toBe(2);
|
expect(game.scene.getParty()[0].variant).toBe(2);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
|
||||||
it("Check if first pokemon in party is caterpie from gen 1 and 1rd row, 3rd column ", async() => {
|
it("Check if first pokemon in party is caterpie from gen 1 and 1rd row, 3rd column", async() => {
|
||||||
await game.importData("src/test/utils/saves/everything.prsv");
|
await game.importData("src/test/utils/saves/everything.prsv");
|
||||||
|
const caughtCount = Object.keys(game.scene.gameData.dexData).filter((key) => {
|
||||||
|
const species = game.scene.gameData.dexData[key];
|
||||||
|
return species.caughtAttr !== 0n;
|
||||||
|
}).length;
|
||||||
|
expect(caughtCount).toBe(Object.keys(allSpecies).length);
|
||||||
await game.runToTitle();
|
await game.runToTitle();
|
||||||
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
||||||
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
||||||
currentPhase.gameMode = GameModes.CLASSIC;
|
currentPhase.gameMode = GameModes.CLASSIC;
|
||||||
currentPhase.end();
|
currentPhase.end();
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.mustRun(SelectStarterPhase).catch((error) => expect(error).toBe(SelectStarterPhase));
|
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.RIGHT);
|
handler.processInput(Button.RIGHT);
|
||||||
@ -501,7 +481,9 @@ describe("UI - Starter select", () => {
|
|||||||
handler.processInput(Button.RIGHT);
|
handler.processInput(Button.RIGHT);
|
||||||
handler.processInput(Button.RIGHT);
|
handler.processInput(Button.RIGHT);
|
||||||
handler.processInput(Button.ACTION);
|
handler.processInput(Button.ACTION);
|
||||||
|
game.phaseInterceptor.unlock();
|
||||||
});
|
});
|
||||||
|
await game.phaseInterceptor.run(SelectStarterPhase);
|
||||||
let options: OptionSelectItem[];
|
let options: OptionSelectItem[];
|
||||||
let optionSelectUiHandler: OptionSelectUiHandler;
|
let optionSelectUiHandler: OptionSelectUiHandler;
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
@ -526,6 +508,7 @@ describe("UI - Starter select", () => {
|
|||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(starterSelectUiHandler.starterGens[0]).toBe(0);
|
expect(starterSelectUiHandler.starterGens[0]).toBe(0);
|
||||||
expect(starterSelectUiHandler.starterCursors[0]).toBe(3);
|
expect(starterSelectUiHandler.starterCursors[0]).toBe(3);
|
||||||
expect(starterSelectUiHandler.cursorObj.x).toBe(132 + 4 * 18);
|
expect(starterSelectUiHandler.cursorObj.x).toBe(132 + 4 * 18);
|
||||||
@ -539,23 +522,23 @@ describe("UI - Starter select", () => {
|
|||||||
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
||||||
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
||||||
});
|
});
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.CONFIRM, () => {
|
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
|
||||||
handler.processInput(Button.ACTION);
|
|
||||||
});
|
|
||||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||||
expect(game.scene.getParty()[0].species.speciesId).toBe(Species.CATERPIE);
|
expect(game.scene.getParty()[0].species.speciesId).toBe(Species.CATERPIE);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
|
||||||
it("Check if first pokemon in party is nidoran_m from gen 1 and 2nd row, 4th column (cursor (9+4)-1) ", async() => {
|
it("Check if first pokemon in party is nidoran_m from gen 1 and 2nd row, 4th column (cursor (9+4)-1)", async() => {
|
||||||
await game.importData("src/test/utils/saves/everything.prsv");
|
await game.importData("src/test/utils/saves/everything.prsv");
|
||||||
|
const caughtCount = Object.keys(game.scene.gameData.dexData).filter((key) => {
|
||||||
|
const species = game.scene.gameData.dexData[key];
|
||||||
|
return species.caughtAttr !== 0n;
|
||||||
|
}).length;
|
||||||
|
expect(caughtCount).toBe(Object.keys(allSpecies).length);
|
||||||
await game.runToTitle();
|
await game.runToTitle();
|
||||||
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
||||||
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
const currentPhase = game.scene.getCurrentPhase() as TitlePhase;
|
||||||
currentPhase.gameMode = GameModes.CLASSIC;
|
currentPhase.gameMode = GameModes.CLASSIC;
|
||||||
currentPhase.end();
|
currentPhase.end();
|
||||||
});
|
});
|
||||||
await game.phaseInterceptor.mustRun(SelectStarterPhase).catch((error) => expect(error).toBe(SelectStarterPhase));
|
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
game.onNextPrompt("SelectStarterPhase", Mode.STARTER_SELECT, () => {
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.RIGHT);
|
handler.processInput(Button.RIGHT);
|
||||||
@ -564,7 +547,9 @@ describe("UI - Starter select", () => {
|
|||||||
handler.processInput(Button.RIGHT);
|
handler.processInput(Button.RIGHT);
|
||||||
handler.processInput(Button.DOWN);
|
handler.processInput(Button.DOWN);
|
||||||
handler.processInput(Button.ACTION);
|
handler.processInput(Button.ACTION);
|
||||||
|
game.phaseInterceptor.unlock();
|
||||||
});
|
});
|
||||||
|
await game.phaseInterceptor.run(SelectStarterPhase);
|
||||||
let options: OptionSelectItem[];
|
let options: OptionSelectItem[];
|
||||||
let optionSelectUiHandler: OptionSelectUiHandler;
|
let optionSelectUiHandler: OptionSelectUiHandler;
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
@ -589,6 +574,7 @@ describe("UI - Starter select", () => {
|
|||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(starterSelectUiHandler.starterGens[0]).toBe(0);
|
expect(starterSelectUiHandler.starterGens[0]).toBe(0);
|
||||||
expect(starterSelectUiHandler.starterCursors[0]).toBe(12);
|
expect(starterSelectUiHandler.starterCursors[0]).toBe(12);
|
||||||
expect(starterSelectUiHandler.cursorObj.x).toBe(132 + 4 * 18);
|
expect(starterSelectUiHandler.cursorObj.x).toBe(132 + 4 * 18);
|
||||||
@ -602,10 +588,6 @@ describe("UI - Starter select", () => {
|
|||||||
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
|
||||||
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
||||||
});
|
});
|
||||||
game.onNextPrompt("SelectStarterPhase", Mode.CONFIRM, () => {
|
|
||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
|
||||||
handler.processInput(Button.ACTION);
|
|
||||||
});
|
|
||||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||||
expect(game.scene.getParty()[0].species.speciesId).toBe(Species.NIDORAN_M);
|
expect(game.scene.getParty()[0].species.speciesId).toBe(Species.NIDORAN_M);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
50
src/test/utils/errorInterceptor.ts
Normal file
50
src/test/utils/errorInterceptor.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
export default class ErrorInterceptor {
|
||||||
|
private static instance: ErrorInterceptor;
|
||||||
|
public running;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.running = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getInstance(): ErrorInterceptor {
|
||||||
|
if (!ErrorInterceptor.instance) {
|
||||||
|
ErrorInterceptor.instance = new ErrorInterceptor();
|
||||||
|
}
|
||||||
|
return ErrorInterceptor.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.running = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
add(obj) {
|
||||||
|
this.running.push(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(obj) {
|
||||||
|
const index = this.running.indexOf(obj);
|
||||||
|
if (index !== -1) {
|
||||||
|
this.running.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
process.on("uncaughtException", (error) => {
|
||||||
|
console.log(error);
|
||||||
|
const toStop = ErrorInterceptor.getInstance().running;
|
||||||
|
for (const elm of toStop) {
|
||||||
|
elm.rejectAll(error);
|
||||||
|
}
|
||||||
|
global.testFailed = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Global error handler for unhandled promise rejections
|
||||||
|
process.on("unhandledRejection", (reason, promise) => {
|
||||||
|
console.log(reason);
|
||||||
|
const toStop = ErrorInterceptor.getInstance().running;
|
||||||
|
for (const elm of toStop) {
|
||||||
|
elm.rejectAll(reason);
|
||||||
|
}
|
||||||
|
global.testFailed = true;
|
||||||
|
});
|
@ -2,21 +2,17 @@ import GameWrapper from "#app/test/utils/gameWrapper";
|
|||||||
import {Mode} from "#app/ui/ui";
|
import {Mode} from "#app/ui/ui";
|
||||||
import {generateStarter, waitUntil} from "#app/test/utils/gameManagerUtils";
|
import {generateStarter, waitUntil} from "#app/test/utils/gameManagerUtils";
|
||||||
import {
|
import {
|
||||||
CheckSwitchPhase,
|
|
||||||
CommandPhase,
|
CommandPhase,
|
||||||
EncounterPhase,
|
EncounterPhase,
|
||||||
LoginPhase,
|
LoginPhase,
|
||||||
PostSummonPhase,
|
PostSummonPhase,
|
||||||
SelectGenderPhase,
|
SelectGenderPhase,
|
||||||
SelectStarterPhase,
|
SelectStarterPhase,
|
||||||
SummonPhase,
|
|
||||||
TitlePhase,
|
TitlePhase,
|
||||||
ToggleDoublePositionPhase,
|
|
||||||
} from "#app/phases";
|
} from "#app/phases";
|
||||||
import BattleScene from "#app/battle-scene.js";
|
import BattleScene from "#app/battle-scene.js";
|
||||||
import PhaseInterceptor from "#app/test/utils/phaseInterceptor";
|
import PhaseInterceptor from "#app/test/utils/phaseInterceptor";
|
||||||
import TextInterceptor from "#app/test/utils/TextInterceptor";
|
import TextInterceptor from "#app/test/utils/TextInterceptor";
|
||||||
import {expect} from "vitest";
|
|
||||||
import {GameModes, getGameMode} from "#app/game-mode";
|
import {GameModes, getGameMode} from "#app/game-mode";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { AES, enc } from "crypto-js";
|
import { AES, enc } from "crypto-js";
|
||||||
@ -26,6 +22,7 @@ import {PlayerGender} from "#app/data/enums/player-gender";
|
|||||||
import {GameDataType} from "#app/data/enums/game-data-type";
|
import {GameDataType} from "#app/data/enums/game-data-type";
|
||||||
import InputsHandler from "#app/test/utils/inputsHandler";
|
import InputsHandler from "#app/test/utils/inputsHandler";
|
||||||
import {ExpNotification} from "#app/enums/exp-notification";
|
import {ExpNotification} from "#app/enums/exp-notification";
|
||||||
|
import ErrorInterceptor from "#app/test/utils/errorInterceptor";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to manage the game state and transitions between phases.
|
* Class to manage the game state and transitions between phases.
|
||||||
@ -43,6 +40,8 @@ export default class GameManager {
|
|||||||
* @param bypassLogin - Whether to bypass the login phase.
|
* @param bypassLogin - Whether to bypass the login phase.
|
||||||
*/
|
*/
|
||||||
constructor(phaserGame: Phaser.Game, bypassLogin: boolean = true) {
|
constructor(phaserGame: Phaser.Game, bypassLogin: boolean = true) {
|
||||||
|
localStorage.clear();
|
||||||
|
ErrorInterceptor.getInstance().clear();
|
||||||
BattleScene.prototype.randBattleSeedInt = (arg) => arg-1;
|
BattleScene.prototype.randBattleSeedInt = (arg) => arg-1;
|
||||||
this.gameWrapper = new GameWrapper(phaserGame, bypassLogin);
|
this.gameWrapper = new GameWrapper(phaserGame, bypassLogin);
|
||||||
this.scene = new BattleScene();
|
this.scene = new BattleScene();
|
||||||
@ -94,14 +93,14 @@ export default class GameManager {
|
|||||||
* @returns A promise that resolves when the title phase is reached.
|
* @returns A promise that resolves when the title phase is reached.
|
||||||
*/
|
*/
|
||||||
runToTitle(): Promise<void> {
|
runToTitle(): Promise<void> {
|
||||||
return new Promise(async(resolve) => {
|
return new Promise(async(resolve, reject) => {
|
||||||
await this.phaseInterceptor.run(LoginPhase);
|
await this.phaseInterceptor.run(LoginPhase).catch((e) => reject(e));
|
||||||
this.onNextPrompt("SelectGenderPhase", Mode.OPTION_SELECT, () => {
|
this.onNextPrompt("SelectGenderPhase", Mode.OPTION_SELECT, () => {
|
||||||
this.scene.gameData.gender = PlayerGender.MALE;
|
this.scene.gameData.gender = PlayerGender.MALE;
|
||||||
this.endPhase();
|
this.endPhase();
|
||||||
}, () => this.isCurrentPhase(TitlePhase));
|
}, () => this.isCurrentPhase(TitlePhase));
|
||||||
await this.phaseInterceptor.run(SelectGenderPhase, () => this.isCurrentPhase(TitlePhase));
|
await this.phaseInterceptor.run(SelectGenderPhase, () => this.isCurrentPhase(TitlePhase)).catch((e) => reject(e));
|
||||||
await this.phaseInterceptor.run(TitlePhase);
|
await this.phaseInterceptor.run(TitlePhase).catch((e) => reject(e));
|
||||||
this.scene.gameSpeed = 5;
|
this.scene.gameSpeed = 5;
|
||||||
this.scene.moveAnimations = false;
|
this.scene.moveAnimations = false;
|
||||||
this.scene.showLevelUpStats = false;
|
this.scene.showLevelUpStats = false;
|
||||||
@ -118,8 +117,8 @@ export default class GameManager {
|
|||||||
* @returns A promise that resolves when the summon phase is reached.
|
* @returns A promise that resolves when the summon phase is reached.
|
||||||
*/
|
*/
|
||||||
runToSummon(species?: Species[]): Promise<void> {
|
runToSummon(species?: Species[]): Promise<void> {
|
||||||
return new Promise(async(resolve) => {
|
return new Promise(async(resolve, reject) => {
|
||||||
await this.runToTitle();
|
await this.runToTitle().catch((e) => reject(e));
|
||||||
this.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
this.onNextPrompt("TitlePhase", Mode.TITLE, () => {
|
||||||
this.scene.gameMode = getGameMode(GameModes.CLASSIC);
|
this.scene.gameMode = getGameMode(GameModes.CLASSIC);
|
||||||
const starters = generateStarter(this.scene, species);
|
const starters = generateStarter(this.scene, species);
|
||||||
@ -127,7 +126,7 @@ export default class GameManager {
|
|||||||
this.scene.pushPhase(new EncounterPhase(this.scene, false));
|
this.scene.pushPhase(new EncounterPhase(this.scene, false));
|
||||||
selectStarterPhase.initBattle(starters);
|
selectStarterPhase.initBattle(starters);
|
||||||
});
|
});
|
||||||
await this.phaseInterceptor.run(EncounterPhase);
|
await this.phaseInterceptor.run(EncounterPhase).catch((e) => reject(e));
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -138,25 +137,18 @@ export default class GameManager {
|
|||||||
* @returns A promise that resolves when the battle is started.
|
* @returns A promise that resolves when the battle is started.
|
||||||
*/
|
*/
|
||||||
startBattle(species?: Species[]): Promise<void> {
|
startBattle(species?: Species[]): Promise<void> {
|
||||||
return new Promise(async(resolve) => {
|
return new Promise(async(resolve, reject) => {
|
||||||
await this.runToSummon(species);
|
await this.runToSummon(species).catch((e) => reject(e));
|
||||||
await this.phaseInterceptor.runFrom(PostSummonPhase).to(ToggleDoublePositionPhase);
|
|
||||||
await this.phaseInterceptor.run(SummonPhase, () => this.isCurrentPhase(CheckSwitchPhase) || this.isCurrentPhase(PostSummonPhase));
|
|
||||||
this.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => {
|
this.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => {
|
||||||
this.setMode(Mode.MESSAGE);
|
this.setMode(Mode.MESSAGE);
|
||||||
this.endPhase();
|
this.endPhase();
|
||||||
}, () => this.isCurrentPhase(PostSummonPhase));
|
}, () => this.isCurrentPhase(CommandPhase));
|
||||||
this.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => {
|
this.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => {
|
||||||
this.setMode(Mode.MESSAGE);
|
this.setMode(Mode.MESSAGE);
|
||||||
this.endPhase();
|
this.endPhase();
|
||||||
}, () => this.isCurrentPhase(PostSummonPhase));
|
}, () => this.isCurrentPhase(CommandPhase));
|
||||||
await this.phaseInterceptor.run(CheckSwitchPhase, () => this.isCurrentPhase(PostSummonPhase));
|
await this.phaseInterceptor.runFrom(PostSummonPhase).to(CommandPhase).catch((e) => reject(e));
|
||||||
await this.phaseInterceptor.run(CheckSwitchPhase, () => this.isCurrentPhase(PostSummonPhase));
|
|
||||||
await this.phaseInterceptor.runFrom(PostSummonPhase).to(CommandPhase);
|
|
||||||
await waitUntil(() => this.scene.ui?.getMode() === Mode.COMMAND);
|
|
||||||
console.log("==================[New Turn]==================");
|
console.log("==================[New Turn]==================");
|
||||||
expect(this.scene.ui?.getMode()).toBe(Mode.COMMAND);
|
|
||||||
expect(this.scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,6 @@ export default class GameWrapper {
|
|||||||
frames: {},
|
frames: {},
|
||||||
});
|
});
|
||||||
Pokemon.prototype.enableMask = () => null;
|
Pokemon.prototype.enableMask = () => null;
|
||||||
localStorage.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setScene(scene: BattleScene) {
|
setScene(scene: BattleScene) {
|
||||||
|
@ -6,10 +6,12 @@ import {
|
|||||||
LoginPhase, MessagePhase, MoveEffectPhase, MoveEndPhase, MovePhase, NewBattlePhase, NextEncounterPhase,
|
LoginPhase, MessagePhase, MoveEffectPhase, MoveEndPhase, MovePhase, NewBattlePhase, NextEncounterPhase,
|
||||||
PostSummonPhase,
|
PostSummonPhase,
|
||||||
SelectGenderPhase, SelectModifierPhase,
|
SelectGenderPhase, SelectModifierPhase,
|
||||||
SelectStarterPhase, ShinySparklePhase, ShowAbilityPhase, StatChangePhase, SummonPhase,
|
SelectStarterPhase, SelectTargetPhase, ShinySparklePhase, ShowAbilityPhase, StatChangePhase, SummonPhase,
|
||||||
TitlePhase, ToggleDoublePositionPhase, TurnEndPhase, TurnInitPhase, TurnStartPhase, VictoryPhase
|
TitlePhase, ToggleDoublePositionPhase, TurnEndPhase, TurnInitPhase, TurnStartPhase, UnavailablePhase, VictoryPhase
|
||||||
} from "#app/phases";
|
} from "#app/phases";
|
||||||
import {Mode} from "#app/ui/ui";
|
import UI, {Mode} from "#app/ui/ui";
|
||||||
|
import {Phase} from "#app/phase";
|
||||||
|
import ErrorInterceptor from "#app/test/utils/errorInterceptor";
|
||||||
|
|
||||||
export default class PhaseInterceptor {
|
export default class PhaseInterceptor {
|
||||||
public scene;
|
public scene;
|
||||||
@ -21,6 +23,9 @@ export default class PhaseInterceptor {
|
|||||||
private intervalRun;
|
private intervalRun;
|
||||||
private prompts;
|
private prompts;
|
||||||
private phaseFrom;
|
private phaseFrom;
|
||||||
|
private inProgress;
|
||||||
|
private originalSetMode;
|
||||||
|
private originalSuperEnd;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of phases with their corresponding start methods.
|
* List of phases with their corresponding start methods.
|
||||||
@ -56,6 +61,12 @@ export default class PhaseInterceptor {
|
|||||||
[MoveEndPhase, this.startPhase],
|
[MoveEndPhase, this.startPhase],
|
||||||
[StatChangePhase, this.startPhase],
|
[StatChangePhase, this.startPhase],
|
||||||
[ShinySparklePhase, this.startPhase],
|
[ShinySparklePhase, this.startPhase],
|
||||||
|
[SelectTargetPhase, this.startPhase],
|
||||||
|
[UnavailablePhase, this.startPhase],
|
||||||
|
];
|
||||||
|
|
||||||
|
private endBySetMode = [
|
||||||
|
TitlePhase, SelectGenderPhase, CommandPhase, SelectModifierPhase
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,6 +82,15 @@ export default class PhaseInterceptor {
|
|||||||
this.startPromptHander();
|
this.startPromptHander();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rejectAll(error) {
|
||||||
|
if (this.inProgress) {
|
||||||
|
clearInterval(this.promptInterval);
|
||||||
|
clearInterval(this.interval);
|
||||||
|
clearInterval(this.intervalRun);
|
||||||
|
this.inProgress.onError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to set the starting phase.
|
* Method to set the starting phase.
|
||||||
* @param phaseFrom - The phase to start from.
|
* @param phaseFrom - The phase to start from.
|
||||||
@ -86,20 +106,31 @@ export default class PhaseInterceptor {
|
|||||||
* @param phaseTo - The phase to transition to.
|
* @param phaseTo - The phase to transition to.
|
||||||
* @returns A promise that resolves when the transition is complete.
|
* @returns A promise that resolves when the transition is complete.
|
||||||
*/
|
*/
|
||||||
async to(phaseTo): Promise<void> {
|
async to(phaseTo, runTarget: boolean = true): Promise<void> {
|
||||||
return new Promise(async (resolve) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
await this.run(this.phaseFrom);
|
ErrorInterceptor.getInstance().add(this);
|
||||||
|
await this.run(this.phaseFrom).catch((e) => reject(e));
|
||||||
this.phaseFrom = null;
|
this.phaseFrom = null;
|
||||||
const targetName = typeof phaseTo === "string" ? phaseTo : phaseTo.name;
|
const targetName = typeof phaseTo === "string" ? phaseTo : phaseTo.name;
|
||||||
this.intervalRun = setInterval(async () => {
|
this.intervalRun = setInterval(async() => {
|
||||||
const currentPhase = this.onHold?.length && this.onHold[0];
|
const currentPhase = this.onHold?.length && this.onHold[0];
|
||||||
if (currentPhase && currentPhase.name !== targetName) {
|
if (currentPhase && currentPhase.name === targetName) {
|
||||||
await this.run(currentPhase.name);
|
|
||||||
} else if (currentPhase.name === targetName) {
|
|
||||||
await this.run(currentPhase.name);
|
|
||||||
clearInterval(this.intervalRun);
|
clearInterval(this.intervalRun);
|
||||||
|
if (!runTarget) {
|
||||||
return resolve();
|
return resolve();
|
||||||
}
|
}
|
||||||
|
await this.run(currentPhase).catch((e) => {
|
||||||
|
clearInterval(this.intervalRun);
|
||||||
|
return reject(e);
|
||||||
|
});
|
||||||
|
return resolve();
|
||||||
|
}
|
||||||
|
if (currentPhase && currentPhase.name !== targetName) {
|
||||||
|
await this.run(currentPhase).catch((e) => {
|
||||||
|
clearInterval(this.intervalRun);
|
||||||
|
return reject(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -111,92 +142,53 @@ export default class PhaseInterceptor {
|
|||||||
* @returns A promise that resolves when the phase is run.
|
* @returns A promise that resolves when the phase is run.
|
||||||
*/
|
*/
|
||||||
run(phaseTarget, skipFn?): Promise<void> {
|
run(phaseTarget, skipFn?): Promise<void> {
|
||||||
this.scene.moveAnimations = null; // Mandatory to avoid crash
|
|
||||||
return new Promise(async (resolve) => {
|
|
||||||
this.waitUntil(phaseTarget, skipFn).then(() => {
|
|
||||||
const currentPhase = this.onHold.shift();
|
|
||||||
currentPhase.call();
|
|
||||||
resolve();
|
|
||||||
}).catch(() => {
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to ensure a phase is run, to throw error on test if not.
|
|
||||||
* @param phaseTarget - The phase to run.
|
|
||||||
* @returns A promise that resolves when the phase is run.
|
|
||||||
*/
|
|
||||||
mustRun(phaseTarget): Promise<void> {
|
|
||||||
const targetName = typeof phaseTarget === "string" ? phaseTarget : phaseTarget.name;
|
const targetName = typeof phaseTarget === "string" ? phaseTarget : phaseTarget.name;
|
||||||
this.scene.moveAnimations = null; // Mandatory to avoid crash
|
this.scene.moveAnimations = null; // Mandatory to avoid crash
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
|
ErrorInterceptor.getInstance().add(this);
|
||||||
const interval = setInterval(async () => {
|
const interval = setInterval(async () => {
|
||||||
const currentPhase = this.onHold?.length && this.onHold[0];
|
const currentPhase = this.onHold.shift();
|
||||||
if (currentPhase && currentPhase.name !== targetName) {
|
if (currentPhase) {
|
||||||
reject(currentPhase);
|
if (currentPhase.name !== targetName) {
|
||||||
} else if (currentPhase && currentPhase.name === targetName) {
|
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
await this.run(phaseTarget);
|
const skip = skipFn && skipFn(currentPhase.name);
|
||||||
resolve();
|
if (skip) {
|
||||||
}
|
this.onHold.unshift(currentPhase);
|
||||||
});
|
ErrorInterceptor.getInstance().remove(this);
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to execute actions when about to run a phase. Does not run the phase, stop right before.
|
|
||||||
* @param phaseTarget - The phase to run.
|
|
||||||
* @param skipFn - Optional skip function.
|
|
||||||
* @returns A promise that resolves when the phase is about to run.
|
|
||||||
*/
|
|
||||||
whenAboutToRun(phaseTarget, skipFn?): Promise<void> {
|
|
||||||
return new Promise(async (resolve) => {
|
|
||||||
this.waitUntil(phaseTarget, skipFn).then(() => {
|
|
||||||
resolve();
|
|
||||||
}).catch(() => {
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to remove a phase from the list.
|
|
||||||
* @param phaseTarget - The phase to remove.
|
|
||||||
* @param skipFn - Optional skip function.
|
|
||||||
* @returns A promise that resolves when the phase is removed.
|
|
||||||
*/
|
|
||||||
remove(phaseTarget, skipFn?): Promise<void> {
|
|
||||||
return new Promise(async (resolve) => {
|
|
||||||
this.waitUntil(phaseTarget, skipFn).then(() => {
|
|
||||||
this.onHold.shift();
|
|
||||||
this.scene.getCurrentPhase().end();
|
|
||||||
resolve();
|
|
||||||
}).catch(() => {
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to wait until a specific phase is reached.
|
|
||||||
* @param phaseTarget - The phase to wait for.
|
|
||||||
* @param skipFn - Optional skip function.
|
|
||||||
* @returns A promise that resolves when the phase is reached.
|
|
||||||
*/
|
|
||||||
waitUntil(phaseTarget, skipFn?): Promise<void> {
|
|
||||||
const targetName = typeof phaseTarget === "string" ? phaseTarget : phaseTarget.name;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.interval = setInterval(() => {
|
|
||||||
const currentPhase = this.onHold?.length && this.onHold[0] && this.onHold[0].name;
|
|
||||||
// if the currentPhase here is not filled, it means it's a phase we haven't added to the list
|
|
||||||
if (currentPhase === targetName) {
|
|
||||||
clearInterval(this.interval);
|
|
||||||
return resolve();
|
return resolve();
|
||||||
} else if (skipFn && skipFn()) {
|
}
|
||||||
clearInterval(this.interval);
|
clearInterval(interval);
|
||||||
return reject("Skipped phase");
|
return reject(`Wrong phase: this is ${currentPhase.name} and not ${targetName}`);
|
||||||
|
}
|
||||||
|
clearInterval(interval);
|
||||||
|
this.inProgress = {
|
||||||
|
name: currentPhase.name,
|
||||||
|
callback: () => {
|
||||||
|
ErrorInterceptor.getInstance().remove(this);
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
onError: (error) => reject(error),
|
||||||
|
};
|
||||||
|
currentPhase.call();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
whenAboutToRun(phaseTarget, skipFn?): Promise<void> {
|
||||||
|
const targetName = typeof phaseTarget === "string" ? phaseTarget : phaseTarget.name;
|
||||||
|
this.scene.moveAnimations = null; // Mandatory to avoid crash
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
ErrorInterceptor.getInstance().add(this);
|
||||||
|
const interval = setInterval(async () => {
|
||||||
|
const currentPhase = this.onHold.shift();
|
||||||
|
if (currentPhase) {
|
||||||
|
if (currentPhase.name !== targetName) {
|
||||||
|
this.onHold.unshift(currentPhase);
|
||||||
|
} else {
|
||||||
|
clearInterval(interval);
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -206,10 +198,17 @@ export default class PhaseInterceptor {
|
|||||||
* Method to initialize phases and their corresponding methods.
|
* Method to initialize phases and their corresponding methods.
|
||||||
*/
|
*/
|
||||||
initPhases() {
|
initPhases() {
|
||||||
for (const [phase, method] of this.PHASES) {
|
this.originalSetMode = UI.prototype.setMode;
|
||||||
|
this.originalSuperEnd = Phase.prototype.end;
|
||||||
|
UI.prototype.setMode = (mode, ...args) => this.setMode.call(this, mode, ...args);
|
||||||
|
Phase.prototype.end = () => this.superEndPhase.call(this);
|
||||||
|
for (const [phase, methodStart] of this.PHASES) {
|
||||||
const originalStart = phase.prototype.start;
|
const originalStart = phase.prototype.start;
|
||||||
this.phases[phase.name] = originalStart;
|
this.phases[phase.name] = {
|
||||||
phase.prototype.start = () => method.call(this, phase);
|
start: originalStart,
|
||||||
|
endBySetMode: this.endBySetMode.some((elm) => elm.name === phase.name),
|
||||||
|
};
|
||||||
|
phase.prototype.start = () => methodStart.call(this, phase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,11 +222,44 @@ export default class PhaseInterceptor {
|
|||||||
this.onHold.push({
|
this.onHold.push({
|
||||||
name: phase.name,
|
name: phase.name,
|
||||||
call: () => {
|
call: () => {
|
||||||
this.phases[phase.name].apply(instance);
|
this.phases[phase.name].start.apply(instance);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unlock() {
|
||||||
|
this.inProgress?.callback();
|
||||||
|
this.inProgress = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to end a phase and log it.
|
||||||
|
* @param phase - The phase to start.
|
||||||
|
*/
|
||||||
|
superEndPhase() {
|
||||||
|
const instance = this.scene.getCurrentPhase();
|
||||||
|
console.log(`%c INTERCEPTED Super End Phase ${instance.constructor.name}`, "color:red;");
|
||||||
|
this.originalSuperEnd.apply(instance);
|
||||||
|
this.inProgress?.callback();
|
||||||
|
this.inProgress = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* m2m to set mode.
|
||||||
|
* @param phase - The phase to start.
|
||||||
|
*/
|
||||||
|
setMode(mode: Mode, ...args: any[]): Promise<void> {
|
||||||
|
const currentPhase = this.scene.getCurrentPhase();
|
||||||
|
const instance = this.scene.ui;
|
||||||
|
console.log("setMode", mode, args);
|
||||||
|
const ret = this.originalSetMode.apply(instance, [mode, ...args]);
|
||||||
|
if (this.phases[currentPhase.constructor.name].endBySetMode) {
|
||||||
|
this.inProgress?.callback();
|
||||||
|
this.inProgress = undefined;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to start the prompt handler.
|
* Method to start the prompt handler.
|
||||||
*/
|
*/
|
||||||
@ -271,9 +303,12 @@ export default class PhaseInterceptor {
|
|||||||
*/
|
*/
|
||||||
restoreOg() {
|
restoreOg() {
|
||||||
for (const [phase] of this.PHASES) {
|
for (const [phase] of this.PHASES) {
|
||||||
phase.prototype.start = this.phases[phase.name];
|
phase.prototype.start = this.phases[phase.name].start;
|
||||||
}
|
}
|
||||||
|
UI.prototype.setMode = this.originalSetMode;
|
||||||
|
Phase.prototype.end = this.originalSuperEnd;
|
||||||
clearInterval(this.promptInterval);
|
clearInterval(this.promptInterval);
|
||||||
clearInterval(this.interval);
|
clearInterval(this.interval);
|
||||||
|
clearInterval(this.intervalRun);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,3 +21,5 @@ initPokemonForms();
|
|||||||
initSpecies();
|
initSpecies();
|
||||||
initMoves();
|
initMoves();
|
||||||
initAbilities();
|
initAbilities();
|
||||||
|
|
||||||
|
global.testFailed = false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user