[Dev] Update Biome from 2.3.2 to 2.3.8 (#6799)

* Update Biome to `2.3.8` and run Biome over the repo

* Update comment in `biome.jsonc`
This commit is contained in:
NightKev 2025-11-29 16:39:58 -06:00 committed by GitHub
parent 9bfe5f02d8
commit b6bd9566e2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 303 additions and 360 deletions

View File

@ -5,7 +5,7 @@
*/ */
{ {
"$schema": "https://biomejs.dev/schemas/2.3.2/schema.json", "$schema": "https://biomejs.dev/schemas/2.3.8/schema.json",
"vcs": { "vcs": {
"enabled": true, "enabled": true,
"clientKind": "git", "clientKind": "git",
@ -16,7 +16,7 @@
"enabled": true, "enabled": true,
"useEditorconfig": true, "useEditorconfig": true,
"indentStyle": "space", "indentStyle": "space",
"includes": ["**", "!**/src/data/balance/**"], "includes": ["**", "!src/data/balance/**"], // TODO: enable formatting of balance folder
"lineWidth": 120 "lineWidth": 120
}, },
"files": { "files": {
@ -25,18 +25,23 @@
// and having to verify whether each individual file is ignored // and having to verify whether each individual file is ignored
"includes": [ "includes": [
"**", "**",
"!**/dist", "!!.github",
"!**/coverage", "!!assets",
"!**/assets", "!!coverage",
"!**/locales", "!!dist",
"!**/.github", "!!docs",
"!**/node_modules", "!!locales",
"!**/typedoc", "!!typedoc",
// TODO: lint css and html? // TODO: lint css and html?
"!**/*.css", "!!*.css",
"!**/*.html", "!!*.html",
// this file is too big // this file is too big
"!**/src/data/balance/tm-species-map.ts" "!src/data/balance/tm-species-map.ts",
// there's some sort of bug when Biome parses this file
// relating to recursive variable assignment
// cf https://github.com/biomejs/biome/issues/8204
// TODO: remove this exclusion when the bug is fixed
"!!test/test-utils/setup/test-end-log.ts"
] ]
}, },
"assist": { "assist": {

View File

@ -39,7 +39,7 @@
"update-submodules:remote": "pnpm update-locales:remote && pnpm update-assets:remote" "update-submodules:remote": "pnpm update-locales:remote && pnpm update-assets:remote"
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "2.3.2", "@biomejs/biome": "2.3.8",
"@ls-lint/ls-lint": "2.3.1", "@ls-lint/ls-lint": "2.3.1",
"@types/crypto-js": "^4.2.2", "@types/crypto-js": "^4.2.2",
"@types/jsdom": "^27.0.0", "@types/jsdom": "^27.0.0",

View File

@ -46,8 +46,8 @@ importers:
version: 1.80.17(graphology-types@0.24.8) version: 1.80.17(graphology-types@0.24.8)
devDependencies: devDependencies:
'@biomejs/biome': '@biomejs/biome':
specifier: 2.3.2 specifier: 2.3.8
version: 2.3.2 version: 2.3.8
'@ls-lint/ls-lint': '@ls-lint/ls-lint':
specifier: 2.3.1 specifier: 2.3.1
version: 2.3.1 version: 2.3.1
@ -203,59 +203,59 @@ packages:
resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
'@biomejs/biome@2.3.2': '@biomejs/biome@2.3.8':
resolution: {integrity: sha512-8e9tzamuDycx7fdrcJ/F/GDZ8SYukc5ud6tDicjjFqURKYFSWMl0H0iXNXZEGmcmNUmABgGuHThPykcM41INgg==} resolution: {integrity: sha512-Qjsgoe6FEBxWAUzwFGFrB+1+M8y/y5kwmg5CHac+GSVOdmOIqsAiXM5QMVGZJ1eCUCLlPZtq4aFAQ0eawEUuUA==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
hasBin: true hasBin: true
'@biomejs/cli-darwin-arm64@2.3.2': '@biomejs/cli-darwin-arm64@2.3.8':
resolution: {integrity: sha512-4LECm4kc3If0JISai4c3KWQzukoUdpxy4fRzlrPcrdMSRFksR9ZoXK7JBcPuLBmd2SoT4/d7CQS33VnZpgBjew==} resolution: {integrity: sha512-HM4Zg9CGQ3txTPflxD19n8MFPrmUAjaC7PQdLkugeeC0cQ+PiVrd7i09gaBS/11QKsTDBJhVg85CEIK9f50Qww==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@biomejs/cli-darwin-x64@2.3.2': '@biomejs/cli-darwin-x64@2.3.8':
resolution: {integrity: sha512-jNMnfwHT4N3wi+ypRfMTjLGnDmKYGzxVr1EYAPBcauRcDnICFXN81wD6wxJcSUrLynoyyYCdfW6vJHS/IAoTDA==} resolution: {integrity: sha512-lUDQ03D7y/qEao7RgdjWVGCu+BLYadhKTm40HkpJIi6kn8LSv5PAwRlew/DmwP4YZ9ke9XXoTIQDO1vAnbRZlA==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@biomejs/cli-linux-arm64-musl@2.3.2': '@biomejs/cli-linux-arm64-musl@2.3.8':
resolution: {integrity: sha512-2Zz4usDG1GTTPQnliIeNx6eVGGP2ry5vE/v39nT73a3cKN6t5H5XxjcEoZZh62uVZvED7hXXikclvI64vZkYqw==} resolution: {integrity: sha512-PShR4mM0sjksUMyxbyPNMxoKFPVF48fU8Qe8Sfx6w6F42verbwRLbz+QiKNiDPRJwUoMG1nPM50OBL3aOnTevA==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl] libc: [musl]
'@biomejs/cli-linux-arm64@2.3.2': '@biomejs/cli-linux-arm64@2.3.8':
resolution: {integrity: sha512-amnqvk+gWybbQleRRq8TMe0rIv7GHss8mFJEaGuEZYWg1Tw14YKOkeo8h6pf1c+d3qR+JU4iT9KXnBKGON4klw==} resolution: {integrity: sha512-Uo1OJnIkJgSgF+USx970fsM/drtPcQ39I+JO+Fjsaa9ZdCN1oysQmy6oAGbyESlouz+rzEckLTF6DS7cWse95g==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc] libc: [glibc]
'@biomejs/cli-linux-x64-musl@2.3.2': '@biomejs/cli-linux-x64-musl@2.3.8':
resolution: {integrity: sha512-gzB19MpRdTuOuLtPpFBGrV3Lq424gHyq2lFj8wfX9tvLMLdmA/R9C7k/mqBp/spcbWuHeIEKgEs3RviOPcWGBA==} resolution: {integrity: sha512-YGLkqU91r1276uwSjiUD/xaVikdxgV1QpsicT0bIA1TaieM6E5ibMZeSyjQ/izBn4tKQthUSsVZacmoJfa3pDA==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl] libc: [musl]
'@biomejs/cli-linux-x64@2.3.2': '@biomejs/cli-linux-x64@2.3.8':
resolution: {integrity: sha512-8BG/vRAhFz1pmuyd24FQPhNeueLqPtwvZk6yblABY2gzL2H8fLQAF/Z2OPIc+BPIVPld+8cSiKY/KFh6k81xfA==} resolution: {integrity: sha512-QDPMD5bQz6qOVb3kiBui0zKZXASLo0NIQ9JVJio5RveBEFgDgsvJFUvZIbMbUZT3T00M/1wdzwWXk4GIh0KaAw==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc] libc: [glibc]
'@biomejs/cli-win32-arm64@2.3.2': '@biomejs/cli-win32-arm64@2.3.8':
resolution: {integrity: sha512-lCruqQlfWjhMlOdyf5pDHOxoNm4WoyY2vZ4YN33/nuZBRstVDuqPPjS0yBkbUlLEte11FbpW+wWSlfnZfSIZvg==} resolution: {integrity: sha512-H4IoCHvL1fXKDrTALeTKMiE7GGWFAraDwBYFquE/L/5r1927Te0mYIGseXi4F+lrrwhSWbSGt5qPFswNoBaCxg==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@biomejs/cli-win32-x64@2.3.2': '@biomejs/cli-win32-x64@2.3.8':
resolution: {integrity: sha512-6Ee9P26DTb4D8sN9nXxgbi9Dw5vSOfH98M7UlmkjKB2vtUbrRqCbZiNfryGiwnPIpd6YUoTl7rLVD2/x1CyEHQ==} resolution: {integrity: sha512-RguzimPoZWtBapfKhKjcWXBVI91tiSprqdBYu7tWhgN8pKRZhw24rFeNZTNf6UiBfjCYCi9eFQs/JzJZIhuK4w==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
@ -2138,39 +2138,39 @@ snapshots:
'@babel/helper-string-parser': 7.27.1 '@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.28.5 '@babel/helper-validator-identifier': 7.28.5
'@biomejs/biome@2.3.2': '@biomejs/biome@2.3.8':
optionalDependencies: optionalDependencies:
'@biomejs/cli-darwin-arm64': 2.3.2 '@biomejs/cli-darwin-arm64': 2.3.8
'@biomejs/cli-darwin-x64': 2.3.2 '@biomejs/cli-darwin-x64': 2.3.8
'@biomejs/cli-linux-arm64': 2.3.2 '@biomejs/cli-linux-arm64': 2.3.8
'@biomejs/cli-linux-arm64-musl': 2.3.2 '@biomejs/cli-linux-arm64-musl': 2.3.8
'@biomejs/cli-linux-x64': 2.3.2 '@biomejs/cli-linux-x64': 2.3.8
'@biomejs/cli-linux-x64-musl': 2.3.2 '@biomejs/cli-linux-x64-musl': 2.3.8
'@biomejs/cli-win32-arm64': 2.3.2 '@biomejs/cli-win32-arm64': 2.3.8
'@biomejs/cli-win32-x64': 2.3.2 '@biomejs/cli-win32-x64': 2.3.8
'@biomejs/cli-darwin-arm64@2.3.2': '@biomejs/cli-darwin-arm64@2.3.8':
optional: true optional: true
'@biomejs/cli-darwin-x64@2.3.2': '@biomejs/cli-darwin-x64@2.3.8':
optional: true optional: true
'@biomejs/cli-linux-arm64-musl@2.3.2': '@biomejs/cli-linux-arm64-musl@2.3.8':
optional: true optional: true
'@biomejs/cli-linux-arm64@2.3.2': '@biomejs/cli-linux-arm64@2.3.8':
optional: true optional: true
'@biomejs/cli-linux-x64-musl@2.3.2': '@biomejs/cli-linux-x64-musl@2.3.8':
optional: true optional: true
'@biomejs/cli-linux-x64@2.3.2': '@biomejs/cli-linux-x64@2.3.8':
optional: true optional: true
'@biomejs/cli-win32-arm64@2.3.2': '@biomejs/cli-win32-arm64@2.3.8':
optional: true optional: true
'@biomejs/cli-win32-x64@2.3.2': '@biomejs/cli-win32-x64@2.3.8':
optional: true optional: true
'@csstools/color-helpers@5.1.0': {} '@csstools/color-helpers@5.1.0': {}

View File

@ -55,6 +55,7 @@ describe("AbilityId - Magic Guard", () => {
expect(magikarp.hp).toBe(magikarp.getMaxHp()); expect(magikarp.hp).toBe(magikarp.getMaxHp());
}); });
// biome-ignore format: prefer pre-2.3.6 formatting
it.each<{ abName: string; move?: MoveId; enemyMove?: MoveId; passive?: AbilityId; enemyAbility?: AbilityId }>([ it.each<{ abName: string; move?: MoveId; enemyMove?: MoveId; passive?: AbilityId; enemyAbility?: AbilityId }>([
{ abName: "Bad Dreams", enemyMove: MoveId.SPORE, enemyAbility: AbilityId.BAD_DREAMS }, { abName: "Bad Dreams", enemyMove: MoveId.SPORE, enemyAbility: AbilityId.BAD_DREAMS },
{ abName: "Aftermath", move: MoveId.PSYCHIC_FANGS, enemyAbility: AbilityId.AFTERMATH }, { abName: "Aftermath", move: MoveId.PSYCHIC_FANGS, enemyAbility: AbilityId.AFTERMATH },

View File

@ -49,25 +49,21 @@ describe("Abilities - Moxie", () => {
}); });
// TODO: Activate this test when MOXIE is corrected to work on faint and not on battle victory // TODO: Activate this test when MOXIE is corrected to work on faint and not on battle victory
it.todo( it.todo("should raise ATK stat stage by 1 when defeating an ally Pokemon", async () => {
"should raise ATK stat stage by 1 when defeating an ally Pokemon", game.override.battleStyle("double");
async () => { const moveToUse = MoveId.AERIAL_ACE;
game.override.battleStyle("double"); await game.classicMode.startBattle([SpeciesId.MIGHTYENA, SpeciesId.MIGHTYENA]);
const moveToUse = MoveId.AERIAL_ACE;
await game.classicMode.startBattle([SpeciesId.MIGHTYENA, SpeciesId.MIGHTYENA]);
const [firstPokemon, secondPokemon] = game.scene.getPlayerField(); const [firstPokemon, secondPokemon] = game.scene.getPlayerField();
expect(firstPokemon.getStatStage(Stat.ATK)).toBe(0); expect(firstPokemon.getStatStage(Stat.ATK)).toBe(0);
secondPokemon.hp = 1; secondPokemon.hp = 1;
game.move.select(moveToUse, BattlerIndex.PLAYER_2); game.move.select(moveToUse, BattlerIndex.PLAYER_2);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(firstPokemon.getStatStage(Stat.ATK)).toBe(1); expect(firstPokemon.getStatStage(Stat.ATK)).toBe(1);
}, }, 20000);
20000,
);
}); });

View File

@ -121,6 +121,7 @@ describe("Abilities - Protean/Libero", () => {
expectTypeChange(bulbasaur); expectTypeChange(bulbasaur);
}); });
// biome-ignore format: prefer pre-2.3.6 formatting
it.each<{ category: string; move?: MoveId; passive?: AbilityId; enemyMove?: MoveId }>([ it.each<{ category: string; move?: MoveId; passive?: AbilityId; enemyMove?: MoveId }>([
{ category: "Variable type Moves'", move: MoveId.WEATHER_BALL, passive: AbilityId.DROUGHT }, { category: "Variable type Moves'", move: MoveId.WEATHER_BALL, passive: AbilityId.DROUGHT },
{ category: "Type Change Abilities'", passive: AbilityId.REFRIGERATE }, { category: "Type Change Abilities'", passive: AbilityId.REFRIGERATE },
@ -146,6 +147,7 @@ describe("Abilities - Protean/Libero", () => {
}, },
); );
// biome-ignore format: prefer pre-2.3.6 formatting
it.each<{ cause: string; move?: MoveId; passive?: AbilityId; enemyMove?: MoveId }>([ it.each<{ cause: string; move?: MoveId; passive?: AbilityId; enemyMove?: MoveId }>([
{ cause: "misses", move: MoveId.FOCUS_BLAST }, { cause: "misses", move: MoveId.FOCUS_BLAST },
{ cause: "is protected against", enemyMove: MoveId.PROTECT }, { cause: "is protected against", enemyMove: MoveId.PROTECT },

View File

@ -35,33 +35,31 @@ describe("Abilities - Shields Down", () => {
.enemyMoveset(MoveId.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
it.each([0, 1, 2, 3, 4, 5, 6])( it.each([0, 1, 2, 3, 4, 5, 6])(//
"should change from Meteor Form to Core Form on entry/turn end based on HP - form index %i", "should change from Meteor Form to Core Form on entry/turn end based on HP - form index %i", async meteorIndex => {
async meteorIndex => { game.override.starterForms({
game.override.starterForms({ // Start in meteor form
// Start in meteor form [SpeciesId.MINIOR]: meteorIndex,
[SpeciesId.MINIOR]: meteorIndex, });
});
await game.classicMode.startBattle([SpeciesId.MAGIKARP, SpeciesId.MINIOR]); await game.classicMode.startBattle([SpeciesId.MAGIKARP, SpeciesId.MINIOR]);
const minior = game.scene.getPlayerParty()[1]; const minior = game.scene.getPlayerParty()[1];
expect(minior.formIndex).toBe(meteorIndex); expect(minior.formIndex).toBe(meteorIndex);
minior.hp *= 0.49; minior.hp *= 0.49;
// Switch to minior - should change to Core due to being <50% HP // Switch to minior - should change to Core due to being <50% HP
game.doSwitchPokemon(1); game.doSwitchPokemon(1);
await game.toNextTurn(); await game.toNextTurn();
expect(minior.formIndex).toBe(meteorIndex + 7); expect(minior.formIndex).toBe(meteorIndex + 7);
// Use roost to regain 50% HP; should transform back into Meteor Form at turn end // Use roost to regain 50% HP; should transform back into Meteor Form at turn end
game.move.use(MoveId.ROOST); game.move.use(MoveId.ROOST);
await game.toNextTurn(); await game.toNextTurn();
expect(minior.formIndex).toBe(meteorIndex); expect(minior.formIndex).toBe(meteorIndex);
}, });
);
it("should revert to base form on arena reset, even when fainted", async () => { it("should revert to base form on arena reset, even when fainted", async () => {
game.override.startingWave(4).starterForms({ game.override.startingWave(4).starterForms({

View File

@ -79,17 +79,14 @@ describe.each<{ name: string; ability: AbilityId; status: StatusEffect }>([
}); });
// TODO: This does not propagate failures currently // TODO: This does not propagate failures currently
it.todo( it.todo(`should cause status moves inflicting ${statusStr} to count as failed if no other effects can be applied`, async () => {
`should cause status moves inflicting ${statusStr} to count as failed if no other effects can be applied`, await game.classicMode.startBattle([SpeciesId.FEEBAS]);
async () => {
await game.classicMode.startBattle([SpeciesId.FEEBAS]);
game.move.use(MoveId.SPORE); game.move.use(MoveId.SPORE);
await game.toEndOfTurn(); await game.toEndOfTurn();
const karp = game.field.getEnemyPokemon(); const karp = game.field.getEnemyPokemon();
expect(karp.status?.effect).toBeUndefined(); expect(karp.status?.effect).toBeUndefined();
expect(game.field.getPlayerPokemon().getLastXMoves()[0].result).toBe(MoveResult.FAIL); expect(game.field.getPlayerPokemon().getLastXMoves()[0].result).toBe(MoveResult.FAIL);
}, });
);
}); });

View File

@ -199,29 +199,26 @@ describe("Abilities - Wimp Out", () => {
// TODO: Enable when this behavior is fixed (currently Shell Bell won't activate if Wimp Out activates because // TODO: Enable when this behavior is fixed (currently Shell Bell won't activate if Wimp Out activates because
// the pokemon is removed from the field before the Shell Bell modifier is applied, so it can't see the // the pokemon is removed from the field before the Shell Bell modifier is applied, so it can't see the
// damage dealt and doesn't heal the pokemon) // damage dealt and doesn't heal the pokemon)
it.todo( it.todo("If it falls below half and recovers back above half from a Shell Bell, Wimp Out will activate even after the Shell Bell recovery", async () => {
"If it falls below half and recovers back above half from a Shell Bell, Wimp Out will activate even after the Shell Bell recovery", game.override
async () => { .moveset([MoveId.DOUBLE_EDGE])
game.override .enemyMoveset([MoveId.SPLASH])
.moveset([MoveId.DOUBLE_EDGE]) .startingHeldItems([{ name: "SHELL_BELL", count: 4 }]);
.enemyMoveset([MoveId.SPLASH]) await game.classicMode.startBattle([SpeciesId.WIMPOD, SpeciesId.TYRUNT]);
.startingHeldItems([{ name: "SHELL_BELL", count: 4 }]);
await game.classicMode.startBattle([SpeciesId.WIMPOD, SpeciesId.TYRUNT]);
const wimpod = game.field.getPlayerPokemon(); const wimpod = game.field.getPlayerPokemon();
wimpod.damageAndUpdate(toDmgValue(wimpod.getMaxHp() * 0.4)); wimpod.damageAndUpdate(toDmgValue(wimpod.getMaxHp() * 0.4));
game.move.select(MoveId.DOUBLE_EDGE); game.move.select(MoveId.DOUBLE_EDGE);
game.doSelectPartyPokemon(1); game.doSelectPartyPokemon(1);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(game.scene.getPlayerParty()[1]).toBe(wimpod); expect(game.scene.getPlayerParty()[1]).toBe(wimpod);
expect(wimpod.hp).toBeGreaterThan(toDmgValue(wimpod.getMaxHp() / 2)); expect(wimpod.hp).toBeGreaterThan(toDmgValue(wimpod.getMaxHp() / 2));
expect(game.phaseInterceptor.log).toContain("SwitchSummonPhase"); expect(game.phaseInterceptor.log).toContain("SwitchSummonPhase");
expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.TYRUNT); expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.TYRUNT);
}, });
);
it("Wimp Out will activate due to weather damage", async () => { it("Wimp Out will activate due to weather damage", async () => {
game.override.weather(WeatherType.HAIL).enemyMoveset([MoveId.SPLASH]); game.override.weather(WeatherType.HAIL).enemyMoveset([MoveId.SPLASH]);
@ -460,26 +457,23 @@ describe("Abilities - Wimp Out", () => {
}); });
// TODO: This interaction is not implemented yet // TODO: This interaction is not implemented yet
it.todo( it.todo("Wimp Out will not activate if the Pokémon's HP falls below half due to hurting itself in confusion", async () => {
"Wimp Out will not activate if the Pokémon's HP falls below half due to hurting itself in confusion", game.override.moveset([MoveId.SWORDS_DANCE]).enemyMoveset([MoveId.SWAGGER]);
async () => { await game.classicMode.startBattle([SpeciesId.WIMPOD, SpeciesId.TYRUNT]);
game.override.moveset([MoveId.SWORDS_DANCE]).enemyMoveset([MoveId.SWAGGER]); const playerPokemon = game.field.getPlayerPokemon();
await game.classicMode.startBattle([SpeciesId.WIMPOD, SpeciesId.TYRUNT]); playerPokemon.hp *= 0.51;
const playerPokemon = game.field.getPlayerPokemon(); playerPokemon.setStatStage(Stat.ATK, 6);
playerPokemon.hp *= 0.51; playerPokemon.addTag(BattlerTagType.CONFUSED);
playerPokemon.setStatStage(Stat.ATK, 6);
playerPokemon.addTag(BattlerTagType.CONFUSED);
// TODO: add helper function to force confusion self-hits // TODO: add helper function to force confusion self-hits
while (playerPokemon.getHpRatio() > 0.49) { while (playerPokemon.getHpRatio() > 0.49) {
game.move.select(MoveId.SWORDS_DANCE); game.move.select(MoveId.SWORDS_DANCE);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
} }
confirmNoSwitch(); confirmNoSwitch();
}, });
);
it("should not activate on wave X0 bosses", async () => { it("should not activate on wave X0 bosses", async () => {
game.override.enemyAbility(AbilityId.WIMP_OUT).startingLevel(5850).startingWave(10); game.override.enemyAbility(AbilityId.WIMP_OUT).startingLevel(5850).startingWave(10);

View File

@ -65,6 +65,7 @@ describe("Arena Tags", () => {
})), })),
); );
// biome-ignore format: prefer pre-2.3.6 formatting
it.each(arenaTags)( it.each(arenaTags)(
"$name should display a message on addition, and a separate one on removal - $sideName", "$name should display a message on addition, and a separate one on removal - $sideName",
({ tagType, side }) => { ({ tagType, side }) => {

View File

@ -199,19 +199,17 @@ describe("Spec - Pokemon", () => {
}); });
}); });
it.each([5, 25, 55, 95, 145, 195])( it.each([5, 25, 55, 95, 145, 195])(//
"should set minimum IVs for enemy trainer pokemon based on wave (%i)", "should set minimum IVs for enemy trainer pokemon based on wave (%i)", async wave => {
async wave => { game.override.startingWave(wave);
game.override.startingWave(wave); await game.classicMode.runToSummon([SpeciesId.FEEBAS]);
await game.classicMode.runToSummon([SpeciesId.FEEBAS]);
for (const pokemon of game.field.getEnemyParty()) { for (const pokemon of game.field.getEnemyParty()) {
for (const iv of pokemon.ivs) { for (const iv of pokemon.ivs) {
expect(iv).toBeGreaterThanOrEqual(Math.floor(wave / 10)); expect(iv).toBeGreaterThanOrEqual(Math.floor(wave / 10));
}
} }
}, }
); });
it.each([ it.each([
{ wave: 5, friendship: 6 }, { wave: 5, friendship: 6 },

View File

@ -37,6 +37,7 @@ describe("Items - Multi Lens", () => {
.enemyLevel(99); .enemyLevel(99);
}); });
// biome-ignore format: prefer pre-2.3.6 formatting
it.each([ it.each([
{ stackCount: 1, firstHitDamage: 0.75 }, { stackCount: 1, firstHitDamage: 0.75 },
{ stackCount: 2, firstHitDamage: 0.5 }, { stackCount: 2, firstHitDamage: 0.5 },

View File

@ -219,30 +219,27 @@ describe("Moves - Magic Coat", () => {
}); });
// TODO: stomping tantrum should consider moves that were bounced. // TODO: stomping tantrum should consider moves that were bounced.
it.todo( it.todo("should properly cause the enemy's stomping tantrum to be doubled in power after bouncing and failing", async () => {
"should properly cause the enemy's stomping tantrum to be doubled in power after bouncing and failing", game.override.enemyMoveset([MoveId.STOMPING_TANTRUM, MoveId.SPLASH, MoveId.CHARM]);
async () => { await game.classicMode.startBattle([SpeciesId.BULBASAUR]);
game.override.enemyMoveset([MoveId.STOMPING_TANTRUM, MoveId.SPLASH, MoveId.CHARM]);
await game.classicMode.startBattle([SpeciesId.BULBASAUR]);
const stomping_tantrum = allMoves[MoveId.STOMPING_TANTRUM]; const stomping_tantrum = allMoves[MoveId.STOMPING_TANTRUM];
const enemy = game.field.getEnemyPokemon(); const enemy = game.field.getEnemyPokemon();
vi.spyOn(stomping_tantrum, "calculateBattlePower"); vi.spyOn(stomping_tantrum, "calculateBattlePower");
game.move.select(MoveId.SPORE); game.move.select(MoveId.SPORE);
await game.move.selectEnemyMove(MoveId.CHARM); await game.move.selectEnemyMove(MoveId.CHARM);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(enemy.getLastXMoves(1)[0].result).toBe("success"); expect(enemy.getLastXMoves(1)[0].result).toBe("success");
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(stomping_tantrum.calculateBattlePower).toHaveReturnedWith(75); expect(stomping_tantrum.calculateBattlePower).toHaveReturnedWith(75);
await game.toNextTurn(); await game.toNextTurn();
game.move.select(MoveId.GROWL); game.move.select(MoveId.GROWL);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(stomping_tantrum.calculateBattlePower).toHaveReturnedWith(75); expect(stomping_tantrum.calculateBattlePower).toHaveReturnedWith(75);
}, });
);
it("should respect immunities when bouncing a move", async () => { it("should respect immunities when bouncing a move", async () => {
vi.spyOn(allMoves[MoveId.THUNDER_WAVE], "accuracy", "get").mockReturnValue(100); vi.spyOn(allMoves[MoveId.THUNDER_WAVE], "accuracy", "get").mockReturnValue(100);

View File

@ -40,6 +40,7 @@ describe("Moves - Order Up", () => {
vi.spyOn(game.scene, "triggerPokemonBattleAnim").mockReturnValue(true); vi.spyOn(game.scene, "triggerPokemonBattleAnim").mockReturnValue(true);
}); });
// biome-ignore format: prefer pre-2.3.6 formatting
it.each([ it.each([
{ formIndex: 0, formName: "Curly", stat: Stat.ATK, statName: "Attack" }, { formIndex: 0, formName: "Curly", stat: Stat.ATK, statName: "Attack" },
{ formIndex: 1, formName: "Droopy", stat: Stat.DEF, statName: "Defense" }, { formIndex: 1, formName: "Droopy", stat: Stat.DEF, statName: "Defense" },

View File

@ -60,113 +60,101 @@ describe("Moves - Parting Shot", () => {
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW);
}); });
it.todo( // TODO: fix this bug to pass the test!
// TODO: fix this bug to pass the test! it.todo("Parting shot should fail if target is -6/-6 de-buffed", async () => {
"Parting shot should fail if target is -6/-6 de-buffed", game.override.moveset([MoveId.PARTING_SHOT, MoveId.MEMENTO, MoveId.SPLASH]);
async () => { await game.classicMode.startBattle([
game.override.moveset([MoveId.PARTING_SHOT, MoveId.MEMENTO, MoveId.SPLASH]); SpeciesId.MEOWTH,
await game.classicMode.startBattle([ SpeciesId.MEOWTH,
SpeciesId.MEOWTH, SpeciesId.MEOWTH,
SpeciesId.MEOWTH, SpeciesId.MURKROW,
SpeciesId.MEOWTH, SpeciesId.ABRA,
SpeciesId.MURKROW, ]);
SpeciesId.ABRA,
]);
// use Memento 3 times to debuff enemy // use Memento 3 times to debuff enemy
game.move.select(MoveId.MEMENTO); game.move.select(MoveId.MEMENTO);
await game.phaseInterceptor.to("FaintPhase"); await game.phaseInterceptor.to("FaintPhase");
expect(game.field.getPlayerPokemon().isFainted()).toBe(true); expect(game.field.getPlayerPokemon().isFainted()).toBe(true);
game.doSelectPartyPokemon(1); game.doSelectPartyPokemon(1);
await game.phaseInterceptor.to("TurnInitPhase", false); await game.phaseInterceptor.to("TurnInitPhase", false);
game.move.select(MoveId.MEMENTO); game.move.select(MoveId.MEMENTO);
await game.phaseInterceptor.to("FaintPhase"); await game.phaseInterceptor.to("FaintPhase");
expect(game.field.getPlayerPokemon().isFainted()).toBe(true); expect(game.field.getPlayerPokemon().isFainted()).toBe(true);
game.doSelectPartyPokemon(2); game.doSelectPartyPokemon(2);
await game.phaseInterceptor.to("TurnInitPhase", false); await game.phaseInterceptor.to("TurnInitPhase", false);
game.move.select(MoveId.MEMENTO); game.move.select(MoveId.MEMENTO);
await game.phaseInterceptor.to("FaintPhase"); await game.phaseInterceptor.to("FaintPhase");
expect(game.field.getPlayerPokemon().isFainted()).toBe(true); expect(game.field.getPlayerPokemon().isFainted()).toBe(true);
game.doSelectPartyPokemon(3); game.doSelectPartyPokemon(3);
// set up done // set up done
await game.phaseInterceptor.to("TurnInitPhase", false); await game.phaseInterceptor.to("TurnInitPhase", false);
const enemyPokemon = game.field.getEnemyPokemon(); const enemyPokemon = game.field.getEnemyPokemon();
expect(enemyPokemon).toBeDefined(); expect(enemyPokemon).toBeDefined();
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-6); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-6);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(-6); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(-6);
// now parting shot should fail // now parting shot should fail
game.move.select(MoveId.PARTING_SHOT); game.move.select(MoveId.PARTING_SHOT);
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-6); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-6);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(-6); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(-6);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW);
}, });
);
it.todo( // TODO: fix this bug to pass the test!
// TODO: fix this bug to pass the test! it.todo("Parting shot shouldn't allow switch out when mist is active", async () => {
"Parting shot shouldn't allow switch out when mist is active", game.override.enemySpecies(SpeciesId.ALTARIA).enemyAbility(AbilityId.NONE).enemyMoveset([MoveId.MIST]);
async () => { await game.classicMode.startBattle([SpeciesId.SNORLAX, SpeciesId.MEOWTH]);
game.override.enemySpecies(SpeciesId.ALTARIA).enemyAbility(AbilityId.NONE).enemyMoveset([MoveId.MIST]);
await game.classicMode.startBattle([SpeciesId.SNORLAX, SpeciesId.MEOWTH]);
const enemyPokemon = game.field.getEnemyPokemon(); const enemyPokemon = game.field.getEnemyPokemon();
expect(enemyPokemon).toBeDefined(); expect(enemyPokemon).toBeDefined();
game.move.select(MoveId.PARTING_SHOT); game.move.select(MoveId.PARTING_SHOT);
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW);
}, });
);
it.todo( // TODO: fix this bug to pass the test!
// TODO: fix this bug to pass the test! it.todo("Parting shot shouldn't allow switch out against clear body ability", async () => {
"Parting shot shouldn't allow switch out against clear body ability", game.override.enemySpecies(SpeciesId.TENTACOOL).enemyAbility(AbilityId.CLEAR_BODY);
async () => { await game.classicMode.startBattle([SpeciesId.SNORLAX, SpeciesId.MEOWTH]);
game.override.enemySpecies(SpeciesId.TENTACOOL).enemyAbility(AbilityId.CLEAR_BODY);
await game.classicMode.startBattle([SpeciesId.SNORLAX, SpeciesId.MEOWTH]);
const enemyPokemon = game.field.getEnemyPokemon(); const enemyPokemon = game.field.getEnemyPokemon();
expect(enemyPokemon).toBeDefined(); expect(enemyPokemon).toBeDefined();
game.move.select(MoveId.PARTING_SHOT); game.move.select(MoveId.PARTING_SHOT);
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW);
}, });
);
it.todo( // TODO: fix this bug to pass the test!
// TODO: fix this bug to pass the test! it.todo("should lower stats without failing if no alive party members available to switch", async () => {
"should lower stats without failing if no alive party members available to switch", await game.classicMode.startBattle([SpeciesId.MURKROW, SpeciesId.MEOWTH]);
async () => {
await game.classicMode.startBattle([SpeciesId.MURKROW, SpeciesId.MEOWTH]);
const meowth = game.scene.getPlayerParty()[1]; const meowth = game.scene.getPlayerParty()[1];
meowth.hp = 0; meowth.hp = 0;
game.move.select(MoveId.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
game.move.select(MoveId.PARTING_SHOT); game.move.select(MoveId.PARTING_SHOT);
game.doSelectPartyPokemon(1); game.doSelectPartyPokemon(1);
await game.toEndOfTurn(); await game.toEndOfTurn();
const enemyPokemon = game.field.getEnemyPokemon(); const enemyPokemon = game.field.getEnemyPokemon();
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0);
expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.MURKROW); expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.MURKROW);
}, });
);
}); });

View File

@ -38,19 +38,20 @@ describe("UI - Battle Info", () => {
.enemySpecies(SpeciesId.CATERPIE); .enemySpecies(SpeciesId.CATERPIE);
}); });
it.each([ExpGainsSpeed.FAST, ExpGainsSpeed.FASTER, ExpGainsSpeed.SKIP])( it.each([
"should increase exp gains animation by 2^%i", ExpGainsSpeed.FAST,
async expGainsSpeed => { ExpGainsSpeed.FASTER,
game.settings.expGainsSpeed(expGainsSpeed); ExpGainsSpeed.SKIP,
vi.spyOn(Math, "pow"); ])("should increase exp gains animation by 2^%i", async expGainsSpeed => {
game.settings.expGainsSpeed(expGainsSpeed);
vi.spyOn(Math, "pow");
await game.classicMode.startBattle([SpeciesId.CHARIZARD]); await game.classicMode.startBattle([SpeciesId.CHARIZARD]);
game.move.select(MoveId.SPLASH); game.move.select(MoveId.SPLASH);
await game.doKillOpponents(); await game.doKillOpponents();
await game.phaseInterceptor.to(ExpPhase, true); await game.phaseInterceptor.to(ExpPhase, true);
expect(Math.pow).not.toHaveBeenCalledWith(2, expGainsSpeed); expect(Math.pow).not.toHaveBeenCalledWith(2, expGainsSpeed);
}, });
);
}); });

View File

@ -61,6 +61,8 @@ describe("UI - Pokedex", () => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
}); });
// #region Helper Functions
/** /**
* Run the game to open the pokedex UI. * Run the game to open the pokedex UI.
* @returns The handler for the pokedex UI. * @returns The handler for the pokedex UI.
@ -188,9 +190,8 @@ describe("UI - Pokedex", () => {
} }
} }
/*************************** // #endregion
* Tests for Filters * // #region Filter Tests
***************************/
it("should filter to show only the pokemon with an ability when filtering by ability", async () => { it("should filter to show only the pokemon with an ability when filtering by ability", async () => {
// await game.importData("test/test-utils/saves/everything.prsv"); // await game.importData("test/test-utils/saves/everything.prsv");
@ -199,13 +200,11 @@ describe("UI - Pokedex", () => {
// Get name of overgrow // Get name of overgrow
const overgrow = allAbilities[AbilityId.OVERGROW].name; const overgrow = allAbilities[AbilityId.OVERGROW].name;
// @ts-expect-error `filterText` is private pokedexHandler["filterText"].setValue(FilterTextRow.ABILITY_1, overgrow);
pokedexHandler.filterText.setValue(FilterTextRow.ABILITY_1, overgrow);
// filter all species to be the pokemon that have overgrow // filter all species to be the pokemon that have overgrow
const overgrowSpecies = getSpeciesWithAbility(AbilityId.OVERGROW); const overgrowSpecies = getSpeciesWithAbility(AbilityId.OVERGROW);
// @ts-expect-error - `filteredPokemonData` is private const filteredSpecies = new Set(pokedexHandler["filteredPokemonData"].map(pokemon => pokemon.species.speciesId));
const filteredSpecies = new Set(pokedexHandler.filteredPokemonData.map(pokemon => pokemon.species.speciesId));
expect(filteredSpecies).toEqual(overgrowSpecies); expect(filteredSpecies).toEqual(overgrowSpecies);
}); });
@ -245,14 +244,11 @@ describe("UI - Pokedex", () => {
const pokedexHandler = await runToOpenPokedex(); const pokedexHandler = await runToOpenPokedex();
// @ts-expect-error `filterText` is private pokedexHandler["filterText"].setValue(FilterTextRow.ABILITY_1, ab1_instance.name);
pokedexHandler.filterText.setValue(FilterTextRow.ABILITY_1, ab1_instance.name); pokedexHandler["filterText"].setValue(FilterTextRow.ABILITY_2, ab2_instance.name);
// @ts-expect-error `filterText` is private
pokedexHandler.filterText.setValue(FilterTextRow.ABILITY_2, ab2_instance.name);
let whiteListCount = 0; let whiteListCount = 0;
// @ts-expect-error `filteredPokemonData` is private for (const species of pokedexHandler["filteredPokemonData"]) {
for (const species of pokedexHandler.filteredPokemonData) {
expect(blacklist, "entry must have one of the abilities as a passive").not.toContain(species.species.speciesId); expect(blacklist, "entry must have one of the abilities as a passive").not.toContain(species.species.speciesId);
const rawAbility = [species.species.ability1, species.species.ability2, species.species.abilityHidden]; const rawAbility = [species.species.ability1, species.species.ability2, species.species.abilityHidden];
@ -273,12 +269,10 @@ describe("UI - Pokedex", () => {
it("should filter to show only the pokemon with a type when filtering by a single type", async () => { it("should filter to show only the pokemon with a type when filtering by a single type", async () => {
const pokedexHandler = await runToOpenPokedex(); const pokedexHandler = await runToOpenPokedex();
// @ts-expect-error - `filterBar` is private pokedexHandler["filterBar"].getFilter(DropDownColumn.TYPES).toggleOptionState(PokemonType.NORMAL + 1);
pokedexHandler.filterBar.getFilter(DropDownColumn.TYPES).toggleOptionState(PokemonType.NORMAL + 1);
const expectedPokemon = getSpeciesWithType(PokemonType.NORMAL); const expectedPokemon = getSpeciesWithType(PokemonType.NORMAL);
// @ts-expect-error - `filteredPokemonData` is private const filteredPokemon = new Set(pokedexHandler["filteredPokemonData"].map(pokemon => pokemon.species.speciesId));
const filteredPokemon = new Set(pokedexHandler.filteredPokemonData.map(pokemon => pokemon.species.speciesId));
expect(filteredPokemon).toEqual(expectedPokemon); expect(filteredPokemon).toEqual(expectedPokemon);
}); });
@ -287,14 +281,11 @@ describe("UI - Pokedex", () => {
it.todo("should show only the pokemon with one of the types when filtering by multiple types", async () => { it.todo("should show only the pokemon with one of the types when filtering by multiple types", async () => {
const pokedexHandler = await runToOpenPokedex(); const pokedexHandler = await runToOpenPokedex();
// @ts-expect-error - `filterBar` is private pokedexHandler["filterBar"].getFilter(DropDownColumn.TYPES).toggleOptionState(PokemonType.NORMAL + 1);
pokedexHandler.filterBar.getFilter(DropDownColumn.TYPES).toggleOptionState(PokemonType.NORMAL + 1); pokedexHandler["filterBar"].getFilter(DropDownColumn.TYPES).toggleOptionState(PokemonType.FLYING + 1);
// @ts-expect-error - `filterBar` is private
pokedexHandler.filterBar.getFilter(DropDownColumn.TYPES).toggleOptionState(PokemonType.FLYING + 1);
const expectedPokemon = getSpeciesWithType(PokemonType.NORMAL, PokemonType.FLYING); const expectedPokemon = getSpeciesWithType(PokemonType.NORMAL, PokemonType.FLYING);
// @ts-expect-error - `filteredPokemonData` is private const filteredPokemon = new Set(pokedexHandler["filteredPokemonData"].map(pokemon => pokemon.species.speciesId));
const filteredPokemon = new Set(pokedexHandler.filteredPokemonData.map(pokemon => pokemon.species.speciesId));
expect(filteredPokemon).toEqual(expectedPokemon); expect(filteredPokemon).toEqual(expectedPokemon);
}); });
@ -304,8 +295,7 @@ describe("UI - Pokedex", () => {
await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv"); await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv");
const pokedexHandler = await runToOpenPokedex(); const pokedexHandler = await runToOpenPokedex();
// @ts-expect-error - `filterBar` is private const filter = pokedexHandler["filterBar"].getFilter(DropDownColumn.UNLOCKS);
const filter = pokedexHandler.filterBar.getFilter(DropDownColumn.UNLOCKS);
// Cycling 4 times to get to the "can unlock" for cost reduction // Cycling 4 times to get to the "can unlock" for cost reduction
for (let i = 0; i < 4; i++) { for (let i = 0; i < 4; i++) {
@ -322,8 +312,7 @@ describe("UI - Pokedex", () => {
SpeciesId.MUDKIP, SpeciesId.MUDKIP,
]); ]);
expect( expect(
// @ts-expect-error - `filteredPokemonData` is private pokedexHandler["filteredPokemonData"].every(pokemon =>
pokedexHandler.filteredPokemonData.every(pokemon =>
expectedPokemon.has(pokedexHandler.getStarterSpeciesId(pokemon.species.speciesId)), expectedPokemon.has(pokedexHandler.getStarterSpeciesId(pokemon.species.speciesId)),
), ),
).toBe(true); ).toBe(true);
@ -333,14 +322,12 @@ describe("UI - Pokedex", () => {
await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv"); await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv");
const pokedexHandler = await runToOpenPokedex(); const pokedexHandler = await runToOpenPokedex();
// @ts-expect-error - `filterBar` is private const filter = pokedexHandler["filterBar"].getFilter(DropDownColumn.UNLOCKS);
const filter = pokedexHandler.filterBar.getFilter(DropDownColumn.UNLOCKS);
filter.toggleOptionState(0); // cycle to Passive: Yes filter.toggleOptionState(0); // cycle to Passive: Yes
expect( expect(
// @ts-expect-error - `filteredPokemonData` is private pokedexHandler["filteredPokemonData"].every(
pokedexHandler.filteredPokemonData.every(
pokemon => pokedexHandler.getStarterSpeciesId(pokemon.species.speciesId) === SpeciesId.MUDKIP, pokemon => pokedexHandler.getStarterSpeciesId(pokemon.species.speciesId) === SpeciesId.MUDKIP,
), ),
).toBe(true); ).toBe(true);
@ -350,8 +337,7 @@ describe("UI - Pokedex", () => {
await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv"); await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv");
const pokedexHandler = await runToOpenPokedex(); const pokedexHandler = await runToOpenPokedex();
// @ts-expect-error - `filterBar` is private const filter = pokedexHandler["filterBar"].getFilter(DropDownColumn.UNLOCKS);
const filter = pokedexHandler.filterBar.getFilter(DropDownColumn.UNLOCKS);
// Cycling 4 times to get to the "can unlock" for passive // Cycling 4 times to get to the "can unlock" for passive
const expectedPokemon = new Set([ const expectedPokemon = new Set([
@ -367,8 +353,7 @@ describe("UI - Pokedex", () => {
filter.toggleOptionState(0); filter.toggleOptionState(0);
expect( expect(
// @ts-expect-error - `filteredPokemonData` is private pokedexHandler["filteredPokemonData"].every(pokemon =>
pokedexHandler.filteredPokemonData.every(pokemon =>
expectedPokemon.has(pokedexHandler.getStarterSpeciesId(pokemon.species.speciesId)), expectedPokemon.has(pokedexHandler.getStarterSpeciesId(pokemon.species.speciesId)),
), ),
).toBe(true); ).toBe(true);
@ -380,14 +365,12 @@ describe("UI - Pokedex", () => {
const expectedPokemon = new Set([SpeciesId.TREECKO, SpeciesId.CYNDAQUIL, SpeciesId.TOTODILE]); const expectedPokemon = new Set([SpeciesId.TREECKO, SpeciesId.CYNDAQUIL, SpeciesId.TOTODILE]);
// @ts-expect-error - `filterBar` is private const filter = pokedexHandler["filterBar"].getFilter(DropDownColumn.UNLOCKS);
const filter = pokedexHandler.filterBar.getFilter(DropDownColumn.UNLOCKS);
// Cycle 1 time for cost reduction // Cycle 1 time for cost reduction
filter.toggleOptionState(1); filter.toggleOptionState(1);
expect( expect(
// @ts-expect-error - `filteredPokemonData` is private pokedexHandler["filteredPokemonData"].every(pokemon =>
pokedexHandler.filteredPokemonData.every(pokemon =>
expectedPokemon.has(pokedexHandler.getStarterSpeciesId(pokemon.species.speciesId)), expectedPokemon.has(pokedexHandler.getStarterSpeciesId(pokemon.species.speciesId)),
), ),
).toBe(true); ).toBe(true);
@ -399,15 +382,13 @@ describe("UI - Pokedex", () => {
const expectedPokemon = new Set([SpeciesId.CYNDAQUIL, SpeciesId.TOTODILE]); const expectedPokemon = new Set([SpeciesId.CYNDAQUIL, SpeciesId.TOTODILE]);
// @ts-expect-error - `filterBar` is private const filter = pokedexHandler["filterBar"].getFilter(DropDownColumn.UNLOCKS);
const filter = pokedexHandler.filterBar.getFilter(DropDownColumn.UNLOCKS);
// Cycle 2 times for one cost reduction // Cycle 2 times for one cost reduction
filter.toggleOptionState(1); filter.toggleOptionState(1);
filter.toggleOptionState(1); filter.toggleOptionState(1);
expect( expect(
// @ts-expect-error - `filteredPokemonData` is private pokedexHandler["filteredPokemonData"].every(pokemon =>
pokedexHandler.filteredPokemonData.every(pokemon =>
expectedPokemon.has(pokedexHandler.getStarterSpeciesId(pokemon.species.speciesId)), expectedPokemon.has(pokedexHandler.getStarterSpeciesId(pokemon.species.speciesId)),
), ),
).toBe(true); ).toBe(true);
@ -417,16 +398,14 @@ describe("UI - Pokedex", () => {
await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv"); await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv");
const pokedexHandler = await runToOpenPokedex(); const pokedexHandler = await runToOpenPokedex();
// @ts-expect-error - `filterBar` is private const filter = pokedexHandler["filterBar"].getFilter(DropDownColumn.UNLOCKS);
const filter = pokedexHandler.filterBar.getFilter(DropDownColumn.UNLOCKS);
// Cycle 3 time for two cost reductions // Cycle 3 time for two cost reductions
filter.toggleOptionState(1); filter.toggleOptionState(1);
filter.toggleOptionState(1); filter.toggleOptionState(1);
filter.toggleOptionState(1); filter.toggleOptionState(1);
expect( expect(
// @ts-expect-error - `filteredPokemonData` is private pokedexHandler["filteredPokemonData"].every(
pokedexHandler.filteredPokemonData.every(
pokemon => pokedexHandler.getStarterSpeciesId(pokemon.species.speciesId) === SpeciesId.TREECKO, pokemon => pokedexHandler.getStarterSpeciesId(pokemon.species.speciesId) === SpeciesId.TREECKO,
), ),
).toBe(true); ).toBe(true);
@ -435,12 +414,10 @@ describe("UI - Pokedex", () => {
it("filtering by shiny status shows the caught pokemon with the selected shiny tier", async () => { it("filtering by shiny status shows the caught pokemon with the selected shiny tier", async () => {
await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv"); await game.importData("./test/test-utils/saves/data_pokedex_tests.prsv");
const pokedexHandler = await runToOpenPokedex(); const pokedexHandler = await runToOpenPokedex();
// @ts-expect-error - `filterBar` is private const filter = pokedexHandler["filterBar"].getFilter(DropDownColumn.CAUGHT);
const filter = pokedexHandler.filterBar.getFilter(DropDownColumn.CAUGHT);
filter.toggleOptionState(3); filter.toggleOptionState(3);
// @ts-expect-error - `filteredPokemonData` is private let filteredPokemon = pokedexHandler["filteredPokemonData"].map(pokemon => pokemon.species.speciesId);
let filteredPokemon = pokedexHandler.filteredPokemonData.map(pokemon => pokemon.species.speciesId);
// Red shiny // Red shiny
expect(filteredPokemon.length).toBe(1); expect(filteredPokemon.length).toBe(1);
@ -450,15 +427,13 @@ describe("UI - Pokedex", () => {
filter.toggleOptionState(3); filter.toggleOptionState(3);
filter.toggleOptionState(2); filter.toggleOptionState(2);
// @ts-expect-error - `filteredPokemonData` is private filteredPokemon = pokedexHandler["filteredPokemonData"].map(pokemon => pokemon.species.speciesId);
filteredPokemon = pokedexHandler.filteredPokemonData.map(pokemon => pokemon.species.speciesId);
expect(filteredPokemon.length).toBe(1); expect(filteredPokemon.length).toBe(1);
expect(filteredPokemon[0], "tier 2 shiny").toBe(SpeciesId.RATTATA); expect(filteredPokemon[0], "tier 2 shiny").toBe(SpeciesId.RATTATA);
filter.toggleOptionState(2); filter.toggleOptionState(2);
filter.toggleOptionState(1); filter.toggleOptionState(1);
// @ts-expect-error - `filteredPokemonData` is private filteredPokemon = pokedexHandler["filteredPokemonData"].map(pokemon => pokemon.species.speciesId);
filteredPokemon = pokedexHandler.filteredPokemonData.map(pokemon => pokemon.species.speciesId);
expect(filteredPokemon.length).toBe(1); expect(filteredPokemon.length).toBe(1);
expect(filteredPokemon[0], "tier 3 shiny").toBe(SpeciesId.EKANS); expect(filteredPokemon[0], "tier 3 shiny").toBe(SpeciesId.EKANS);
@ -466,78 +441,66 @@ describe("UI - Pokedex", () => {
filter.toggleOptionState(1); filter.toggleOptionState(1);
filter.toggleOptionState(4); filter.toggleOptionState(4);
// @ts-expect-error - `filteredPokemonData` is private filteredPokemon = pokedexHandler["filteredPokemonData"].map(pokemon => pokemon.species.speciesId);
filteredPokemon = pokedexHandler.filteredPokemonData.map(pokemon => pokemon.species.speciesId);
expect(filteredPokemon.length).toBe(27); expect(filteredPokemon.length).toBe(27);
expect(filteredPokemon, "not shiny").not.toContain(SpeciesId.CATERPIE); expect(filteredPokemon, "not shiny").not.toContain(SpeciesId.CATERPIE);
expect(filteredPokemon, "not shiny").not.toContain(SpeciesId.RATTATA); expect(filteredPokemon, "not shiny").not.toContain(SpeciesId.RATTATA);
expect(filteredPokemon, "not shiny").not.toContain(SpeciesId.EKANS); expect(filteredPokemon, "not shiny").not.toContain(SpeciesId.EKANS);
}); });
/**************************** // #endregion
* Tests for UI Input * // #region UI Input Tests
****************************/
// TODO: fix cursor wrapping // TODO: fix cursor wrapping
it.todo( it.todo("should wrap the cursor to the top when moving to an empty entry when there are more than 81 pokemon", async () => {
"should wrap the cursor to the top when moving to an empty entry when there are more than 81 pokemon", const pokedexHandler = await runToOpenPokedex();
async () => {
const pokedexHandler = await runToOpenPokedex();
// Filter by gen 2 so we can pan a specific amount. // Filter by gen 2 so we can pan a specific amount.
// @ts-expect-error `filterBar` is private pokedexHandler["filterBar"].getFilter(DropDownColumn.GEN).options[2].toggleOptionState();
pokedexHandler.filterBar.getFilter(DropDownColumn.GEN).options[2].toggleOptionState(); pokedexHandler.updateStarters();
pokedexHandler.updateStarters(); expect(pokedexHandler["filteredPokemonData"].length, "pokemon in gen2").toBe(100);
// @ts-expect-error - `filteredPokemonData` is private
expect(pokedexHandler.filteredPokemonData.length, "pokemon in gen2").toBe(100);
// Let's try to pan to the right to see what the pokemon it points to is. // Let's try to pan to the right to see what the pokemon it points to is.
// pan to the right once and down 11 times // pan to the right once and down 11 times
pokedexHandler.processInput(Button.RIGHT); pokedexHandler.processInput(Button.RIGHT);
// Nab the pokemon that is selected for comparison later. // Nab the pokemon that is selected for comparison later.
// @ts-expect-error - `lastSpecies` is private const selectedPokemon = pokedexHandler["lastSpeciesId"].speciesId;
const selectedPokemon = pokedexHandler.lastSpeciesId.speciesId; for (let i = 0; i < 11; i++) {
for (let i = 0; i < 11; i++) { pokedexHandler.processInput(Button.DOWN);
pokedexHandler.processInput(Button.DOWN); }
}
// @ts-expect-error `lastSpecies` is private expect(selectedPokemon).toEqual(pokedexHandler["lastSpeciesId"].speciesId);
expect(selectedPokemon).toEqual(pokedexHandler.lastSpeciesId.speciesId); });
},
);
/**************************** // #endregion
* Tests for Pokédex Pages * // #region Pokedex Pages Tests
****************************/
it("should show caught battle form as caught", async () => { it("should show caught battle form as caught", async () => {
await game.importData("./test/test-utils/saves/data_pokedex_tests_v2.prsv"); await game.importData("./test/test-utils/saves/data_pokedex_tests_v2.prsv");
const pageHandler = await runToPokedexPage(getPokemonSpecies(SpeciesId.VENUSAUR), { form: 1 }); const pageHandler = await runToPokedexPage(getPokemonSpecies(SpeciesId.VENUSAUR), { form: 1 });
// @ts-expect-error - `species` is private expect(pageHandler["species"].speciesId).toEqual(SpeciesId.VENUSAUR);
expect(pageHandler.species.speciesId).toEqual(SpeciesId.VENUSAUR);
// @ts-expect-error - `formIndex` is private expect(pageHandler["formIndex"]).toEqual(1);
expect(pageHandler.formIndex).toEqual(1);
expect(pageHandler.isFormCaught()).toEqual(true); expect(pageHandler.isFormCaught()).toEqual(true);
expect(pageHandler.isSeen()).toEqual(true); expect(pageHandler.isSeen()).toEqual(true);
}); });
//TODO: check tint of the sprite // TODO: check tint of the sprite
it("should show uncaught battle form as seen", async () => { it("should show uncaught battle form as seen", async () => {
await game.importData("./test/test-utils/saves/data_pokedex_tests_v2.prsv"); await game.importData("./test/test-utils/saves/data_pokedex_tests_v2.prsv");
const pageHandler = await runToPokedexPage(getPokemonSpecies(SpeciesId.VENUSAUR), { form: 2 }); const pageHandler = await runToPokedexPage(getPokemonSpecies(SpeciesId.VENUSAUR), { form: 2 });
// @ts-expect-error - `species` is private expect(pageHandler["species"].speciesId).toEqual(SpeciesId.VENUSAUR);
expect(pageHandler.species.speciesId).toEqual(SpeciesId.VENUSAUR);
// @ts-expect-error - `formIndex` is private expect(pageHandler["formIndex"]).toEqual(2);
expect(pageHandler.formIndex).toEqual(2);
expect(pageHandler.isFormCaught()).toEqual(false); expect(pageHandler.isFormCaught()).toEqual(false);
expect(pageHandler.isSeen()).toEqual(true); expect(pageHandler.isSeen()).toEqual(true);
}); });
// #endregion
}); });