mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-15 20:09:30 +02:00
Cleaned up some more matchers
This commit is contained in:
parent
917fb596b4
commit
3a6026d637
8
test/@types/vitest.d.ts
vendored
8
test/@types/vitest.d.ts
vendored
@ -11,6 +11,7 @@ import type { TerrainType } from "#app/data/terrain";
|
||||
import type { WeatherType } from "#enums/weather-type";
|
||||
import type { ToHaveEffectiveStatMatcherOptions } from "#test/test-utils/matchers/to-have-effective-stat";
|
||||
import { TurnMove } from "#types/turn-move";
|
||||
import { expectedStatusType } from "#test/test-utils/matchers/to-have-status-effect-matcher";
|
||||
|
||||
declare module "vitest" {
|
||||
interface Assertion {
|
||||
@ -31,7 +32,7 @@ declare module "vitest" {
|
||||
* @param expected - The expected types (in any order).
|
||||
* @param options - The options passed to the matcher.
|
||||
*/
|
||||
toHaveTypes(expected: PokemonType[], options?: toHaveTypesOptions): void;
|
||||
toHaveTypes(expected: [PokemonType, ...PokemonType[]], options?: toHaveTypesOptions): void;
|
||||
|
||||
/**
|
||||
* Matcher to check the contents of a {@linkcode Pokemon}'s move history.
|
||||
@ -64,9 +65,10 @@ declare module "vitest" {
|
||||
|
||||
/**
|
||||
* Matcher to check if a {@linkcode Pokemon} has a specific {@linkcode StatusEffect | non-volatile status effect}.
|
||||
* @param expectedStatusEffect - The expected {@linkcode StatusEffect}
|
||||
* @param expectedStatusEffect - The {@linkcode StatusEffect} the Pokemon is expected to have,
|
||||
* or a partially filled {@linkcode Status} containing the desired properties
|
||||
*/
|
||||
toHaveStatusEffect(expectedStatusEffect: StatusEffect): void;
|
||||
toHaveStatusEffect(expectedStatusEffect: expectedStatusType): void;
|
||||
|
||||
/**
|
||||
* Matcher to check if the current {@linkcode WeatherType} is as expected.
|
||||
|
@ -5,7 +5,6 @@ import { toHaveEffectiveStatMatcher } from "#test/test-utils/matchers/to-have-ef
|
||||
import { toHaveFaintedMatcher } from "#test/test-utils/matchers/to-have-fainted";
|
||||
import { toHaveFullHpMatcher } from "#test/test-utils/matchers/to-have-full-hp";
|
||||
import { toHaveHpMatcher } from "#test/test-utils/matchers/to-have-hp";
|
||||
import { toHaveMoveResultMatcher } from "#test/test-utils/matchers/to-have-move-result-matcher";
|
||||
import { toHaveStatStageMatcher } from "#test/test-utils/matchers/to-have-stat-stage-matcher";
|
||||
import { toHaveStatusEffectMatcher } from "#test/test-utils/matchers/to-have-status-effect-matcher";
|
||||
import { toHaveTakenDamageMatcher } from "#test/test-utils/matchers/to-have-taken-damage-matcher";
|
||||
@ -23,7 +22,6 @@ import { expect } from "vitest";
|
||||
expect.extend({
|
||||
toEqualArrayUnsorted,
|
||||
toHaveTypes,
|
||||
toHaveMoveResult: toHaveMoveResultMatcher,
|
||||
toHaveUsedMove: toHaveUsedMoveMatcher,
|
||||
toHaveEffectiveStat: toHaveEffectiveStatMatcher,
|
||||
toHaveTakenDamage: toHaveTakenDamageMatcher,
|
||||
|
@ -1,8 +1,43 @@
|
||||
import { AbilityId } from "#enums/ability-id";
|
||||
import { MoveId } from "#enums/move-id";
|
||||
import { PokemonType } from "#enums/pokemon-type";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
import { GameManager } from "#test/test-utils/game-manager";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
describe("a", () => {
|
||||
it("r", () => {
|
||||
expect(1).toHaveTypes([PokemonType.FLYING]);
|
||||
describe("Utils - Fff", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
game.override
|
||||
.ability(AbilityId.BALL_FETCH)
|
||||
.battleStyle("single")
|
||||
.criticalHits(false)
|
||||
.enemySpecies(SpeciesId.MAGIKARP)
|
||||
.enemyAbility(AbilityId.BALL_FETCH)
|
||||
.enemyMoveset(MoveId.SPLASH)
|
||||
.startingLevel(100)
|
||||
.enemyLevel(100);
|
||||
});
|
||||
|
||||
it("should do XYZ", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.FEEBAS]);
|
||||
|
||||
expect(game.field.getPlayerPokemon()).toHaveTypes([PokemonType.WATER]);
|
||||
expect.soft(game.field.getPlayerPokemon()).toHaveTypes([PokemonType.FLYING]);
|
||||
expect.soft(game.field.getPlayerPokemon()).toHaveTypes([PokemonType.WATER]);
|
||||
});
|
||||
});
|
||||
|
@ -3,13 +3,12 @@ import type { Pokemon } from "#field/pokemon";
|
||||
/* biome-ignore-end lint/correctness/noUnusedImports: tsdoc imports */
|
||||
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import type { Status } from "#data/status-effect";
|
||||
import { StatusEffect } from "#enums/status-effect";
|
||||
import { getEnumStr } from "#test/test-utils/string-utils";
|
||||
import { isPokemonInstance, receivedStr } from "#test/test-utils/test-utils";
|
||||
import type { NonFunctionPropertiesRecursive } from "#types/type-helpers";
|
||||
import type { MatcherState, SyncExpectationResult } from "@vitest/expect";
|
||||
|
||||
export type expectedType =
|
||||
export type expectedStatusType =
|
||||
| StatusEffect
|
||||
| { effect: StatusEffect.TOXIC; toxicTurnCount: number }
|
||||
| { effect: StatusEffect.SLEEP; sleepTurnsRemaining: number };
|
||||
@ -24,7 +23,7 @@ export type expectedType =
|
||||
export function toHaveStatusEffectMatcher(
|
||||
this: MatcherState,
|
||||
received: unknown,
|
||||
expectedStatus: expectedType,
|
||||
expectedStatus: expectedStatusType,
|
||||
): SyncExpectationResult {
|
||||
if (!isPokemonInstance(received)) {
|
||||
return {
|
||||
@ -33,19 +32,28 @@ export function toHaveStatusEffectMatcher(
|
||||
};
|
||||
}
|
||||
|
||||
// Convert to Status
|
||||
const expStatus: { effect: StatusEffect } & Partial<NonFunctionPropertiesRecursive<Status>> =
|
||||
typeof expectedStatus === "number"
|
||||
? {
|
||||
effect: expectedStatus,
|
||||
}
|
||||
: expectedStatus;
|
||||
const pkmName = getPokemonNameWithAffix(received);
|
||||
|
||||
// If expected to have no status,
|
||||
if (expStatus.effect === StatusEffect.NONE) {
|
||||
k;
|
||||
// Check exclusively effect equality
|
||||
if (typeof expectedStatus === "number" || received.status?.effect !== expectedStatus.effect) {
|
||||
const actualEffect = received.status?.effect ?? StatusEffect.NONE;
|
||||
const pass = this.equals(actualEffect, expectedStatus, [...this.customTesters, this.utils.iterableEquality]);
|
||||
|
||||
const actualStr = getEnumStr(StatusEffect, actualEffect, { prefix: "StatusEffect." });
|
||||
const expectedStr = getEnumStr(StatusEffect, actualEffect, { prefix: "StatusEffect." });
|
||||
|
||||
return {
|
||||
pass,
|
||||
message: () =>
|
||||
pass
|
||||
? `Expected ${pkmName} NOT to have ${expectedStr}, but it did!`
|
||||
: `Expected ${pkmName} to have status effect ${expectedStr}, but got ${actualStr} instead!`,
|
||||
expected: expectedStatus,
|
||||
actual: actualEffect,
|
||||
};
|
||||
}
|
||||
|
||||
// Check for equality of all fields (for toxic turn count)
|
||||
const actualStatus = received.status;
|
||||
const pass = this.equals(received, expectedStatus, [
|
||||
...this.customTesters,
|
||||
@ -53,13 +61,13 @@ export function toHaveStatusEffectMatcher(
|
||||
this.utils.iterableEquality,
|
||||
]);
|
||||
|
||||
const pkmName = getPokemonNameWithAffix(received);
|
||||
|
||||
return {
|
||||
pass,
|
||||
message: () =>
|
||||
pass
|
||||
? `Expected ${pkmName} NOT to have ${expectedStatusEffectStr}, but it did!`
|
||||
: `Expected ${pkmName} to have status effect: ${expectedStatusEffectStr}, but got: ${actualStatusEffectStr}!`,
|
||||
? `Expected ${pkmName}'s status NOT to match ${this.utils.stringify(expectedStatus)}, but it did!`
|
||||
: `Expected ${pkmName}'s status to match ${this.utils.stringify(expectedStatus)}, but got ${this.utils.stringify(actualStatus)} instead!`,
|
||||
expected: expectedStatus,
|
||||
actual: actualStatus,
|
||||
};
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ export interface toHaveTypesOptions {
|
||||
export function toHaveTypes(
|
||||
this: MatcherState,
|
||||
received: unknown,
|
||||
expected: unknown,
|
||||
expected: [PokemonType, ...PokemonType[]],
|
||||
options: toHaveTypesOptions = {},
|
||||
): SyncExpectationResult {
|
||||
if (!isPokemonInstance(received)) {
|
||||
@ -36,32 +36,21 @@ export function toHaveTypes(
|
||||
};
|
||||
}
|
||||
|
||||
if (!Array.isArray(expected) || expected.length === 0) {
|
||||
return {
|
||||
pass: false,
|
||||
message: () => `Expected to receive an array with length >=1, but got ${this.utils.stringify(expected)}!`,
|
||||
};
|
||||
}
|
||||
const actualTypes = received.getTypes(...(options.args ?? [])).sort();
|
||||
const expectedTypes = expected.slice().sort();
|
||||
|
||||
if (!expected.every((t): t is PokemonType => t in PokemonType)) {
|
||||
return {
|
||||
pass: false,
|
||||
message: () => `Expected to receive array of PokemonTypes but got ${this.utils.stringify(expected)}!`,
|
||||
};
|
||||
}
|
||||
|
||||
const actualSorted = stringifyEnumArray(PokemonType, received.getTypes(...(options.args ?? [])).sort());
|
||||
const expectedSorted = stringifyEnumArray(PokemonType, expected.slice().sort());
|
||||
const actualStr = stringifyEnumArray(PokemonType, actualTypes);
|
||||
const expectedStr = stringifyEnumArray(PokemonType, expectedTypes);
|
||||
// Exact matches do not care about subset equality
|
||||
const matchers = options.exact
|
||||
? [...this.customTesters, this.utils.iterableEquality]
|
||||
: [...this.customTesters, this.utils.subsetEquality, this.utils.iterableEquality];
|
||||
const pass = this.equals(actualSorted, expectedSorted, matchers);
|
||||
const pass = this.equals(actualStr, expectedStr, matchers);
|
||||
|
||||
return {
|
||||
pass,
|
||||
message: () =>
|
||||
`Expected ${getPokemonNameWithAffix(received)} to have types ${this.utils.stringify(expectedSorted)}, but got ${actualSorted}!`,
|
||||
actual: actualSorted,
|
||||
expected: expectedSorted,
|
||||
message: () => `Expected ${getPokemonNameWithAffix(received)} to have types ${expectedStr}, but got ${actualStr}!`,
|
||||
actual: actualTypes,
|
||||
expected: expectedTypes,
|
||||
};
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ interface getEnumStrOptions {
|
||||
* @param obj - The {@linkcode EnumOrObject} to source reverse mappings from
|
||||
* @param enums - One of {@linkcode obj}'s values
|
||||
* @param casing - A string denoting the casing method to use; default `Preserve`
|
||||
* @param suffix - An optional string to be prepended to the enum's string representation.
|
||||
* @param prefix - An optional string to be prepended to the enum's string representation.
|
||||
* @param suffix - An optional string to be appended to the enum's string representation.
|
||||
* @returns The stringified representation of `val` as dictated by the options.
|
||||
* @example
|
||||
@ -38,7 +38,6 @@ interface getEnumStrOptions {
|
||||
* console.log(getEnumStr(fakeEnum, fakeEnum.ONE)); // Output: "ONE (=1)"
|
||||
* console.log(getEnumStr(fakeEnum, fakeEnum.TWO, {case: "Title", suffix: " Terrain"})); // Output: "Two Terrain (=2)"
|
||||
* ```
|
||||
|
||||
*/
|
||||
export function getEnumStr<E extends EnumOrObject>(
|
||||
obj: E,
|
||||
|
Loading…
Reference in New Issue
Block a user