mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-16 20:39:27 +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 { WeatherType } from "#enums/weather-type";
|
||||||
import type { ToHaveEffectiveStatMatcherOptions } from "#test/test-utils/matchers/to-have-effective-stat";
|
import type { ToHaveEffectiveStatMatcherOptions } from "#test/test-utils/matchers/to-have-effective-stat";
|
||||||
import { TurnMove } from "#types/turn-move";
|
import { TurnMove } from "#types/turn-move";
|
||||||
|
import { expectedStatusType } from "#test/test-utils/matchers/to-have-status-effect-matcher";
|
||||||
|
|
||||||
declare module "vitest" {
|
declare module "vitest" {
|
||||||
interface Assertion {
|
interface Assertion {
|
||||||
@ -31,7 +32,7 @@ declare module "vitest" {
|
|||||||
* @param expected - The expected types (in any order).
|
* @param expected - The expected types (in any order).
|
||||||
* @param options - The options passed to the matcher.
|
* @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.
|
* 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}.
|
* 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.
|
* 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 { toHaveFaintedMatcher } from "#test/test-utils/matchers/to-have-fainted";
|
||||||
import { toHaveFullHpMatcher } from "#test/test-utils/matchers/to-have-full-hp";
|
import { toHaveFullHpMatcher } from "#test/test-utils/matchers/to-have-full-hp";
|
||||||
import { toHaveHpMatcher } from "#test/test-utils/matchers/to-have-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 { toHaveStatStageMatcher } from "#test/test-utils/matchers/to-have-stat-stage-matcher";
|
||||||
import { toHaveStatusEffectMatcher } from "#test/test-utils/matchers/to-have-status-effect-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";
|
import { toHaveTakenDamageMatcher } from "#test/test-utils/matchers/to-have-taken-damage-matcher";
|
||||||
@ -23,7 +22,6 @@ import { expect } from "vitest";
|
|||||||
expect.extend({
|
expect.extend({
|
||||||
toEqualArrayUnsorted,
|
toEqualArrayUnsorted,
|
||||||
toHaveTypes,
|
toHaveTypes,
|
||||||
toHaveMoveResult: toHaveMoveResultMatcher,
|
|
||||||
toHaveUsedMove: toHaveUsedMoveMatcher,
|
toHaveUsedMove: toHaveUsedMoveMatcher,
|
||||||
toHaveEffectiveStat: toHaveEffectiveStatMatcher,
|
toHaveEffectiveStat: toHaveEffectiveStatMatcher,
|
||||||
toHaveTakenDamage: toHaveTakenDamageMatcher,
|
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 { 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", () => {
|
describe("Utils - Fff", () => {
|
||||||
it("r", () => {
|
let phaserGame: Phaser.Game;
|
||||||
expect(1).toHaveTypes([PokemonType.FLYING]);
|
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 */
|
/* biome-ignore-end lint/correctness/noUnusedImports: tsdoc imports */
|
||||||
|
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import type { Status } from "#data/status-effect";
|
|
||||||
import { StatusEffect } from "#enums/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 { isPokemonInstance, receivedStr } from "#test/test-utils/test-utils";
|
||||||
import type { NonFunctionPropertiesRecursive } from "#types/type-helpers";
|
|
||||||
import type { MatcherState, SyncExpectationResult } from "@vitest/expect";
|
import type { MatcherState, SyncExpectationResult } from "@vitest/expect";
|
||||||
|
|
||||||
export type expectedType =
|
export type expectedStatusType =
|
||||||
| StatusEffect
|
| StatusEffect
|
||||||
| { effect: StatusEffect.TOXIC; toxicTurnCount: number }
|
| { effect: StatusEffect.TOXIC; toxicTurnCount: number }
|
||||||
| { effect: StatusEffect.SLEEP; sleepTurnsRemaining: number };
|
| { effect: StatusEffect.SLEEP; sleepTurnsRemaining: number };
|
||||||
@ -24,7 +23,7 @@ export type expectedType =
|
|||||||
export function toHaveStatusEffectMatcher(
|
export function toHaveStatusEffectMatcher(
|
||||||
this: MatcherState,
|
this: MatcherState,
|
||||||
received: unknown,
|
received: unknown,
|
||||||
expectedStatus: expectedType,
|
expectedStatus: expectedStatusType,
|
||||||
): SyncExpectationResult {
|
): SyncExpectationResult {
|
||||||
if (!isPokemonInstance(received)) {
|
if (!isPokemonInstance(received)) {
|
||||||
return {
|
return {
|
||||||
@ -33,19 +32,28 @@ export function toHaveStatusEffectMatcher(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to Status
|
const pkmName = getPokemonNameWithAffix(received);
|
||||||
const expStatus: { effect: StatusEffect } & Partial<NonFunctionPropertiesRecursive<Status>> =
|
|
||||||
typeof expectedStatus === "number"
|
|
||||||
? {
|
|
||||||
effect: expectedStatus,
|
|
||||||
}
|
|
||||||
: expectedStatus;
|
|
||||||
|
|
||||||
// If expected to have no status,
|
// Check exclusively effect equality
|
||||||
if (expStatus.effect === StatusEffect.NONE) {
|
if (typeof expectedStatus === "number" || received.status?.effect !== expectedStatus.effect) {
|
||||||
k;
|
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 actualStatus = received.status;
|
||||||
const pass = this.equals(received, expectedStatus, [
|
const pass = this.equals(received, expectedStatus, [
|
||||||
...this.customTesters,
|
...this.customTesters,
|
||||||
@ -53,13 +61,13 @@ export function toHaveStatusEffectMatcher(
|
|||||||
this.utils.iterableEquality,
|
this.utils.iterableEquality,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const pkmName = getPokemonNameWithAffix(received);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pass,
|
pass,
|
||||||
message: () =>
|
message: () =>
|
||||||
pass
|
pass
|
||||||
? `Expected ${pkmName} NOT to have ${expectedStatusEffectStr}, but it did!`
|
? `Expected ${pkmName}'s status NOT to match ${this.utils.stringify(expectedStatus)}, but it did!`
|
||||||
: `Expected ${pkmName} to have status effect: ${expectedStatusEffectStr}, but got: ${actualStatusEffectStr}!`,
|
: `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(
|
export function toHaveTypes(
|
||||||
this: MatcherState,
|
this: MatcherState,
|
||||||
received: unknown,
|
received: unknown,
|
||||||
expected: unknown,
|
expected: [PokemonType, ...PokemonType[]],
|
||||||
options: toHaveTypesOptions = {},
|
options: toHaveTypesOptions = {},
|
||||||
): SyncExpectationResult {
|
): SyncExpectationResult {
|
||||||
if (!isPokemonInstance(received)) {
|
if (!isPokemonInstance(received)) {
|
||||||
@ -36,32 +36,21 @@ export function toHaveTypes(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Array.isArray(expected) || expected.length === 0) {
|
const actualTypes = received.getTypes(...(options.args ?? [])).sort();
|
||||||
return {
|
const expectedTypes = expected.slice().sort();
|
||||||
pass: false,
|
|
||||||
message: () => `Expected to receive an array with length >=1, but got ${this.utils.stringify(expected)}!`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!expected.every((t): t is PokemonType => t in PokemonType)) {
|
const actualStr = stringifyEnumArray(PokemonType, actualTypes);
|
||||||
return {
|
const expectedStr = stringifyEnumArray(PokemonType, expectedTypes);
|
||||||
pass: false,
|
// Exact matches do not care about subset equality
|
||||||
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 matchers = options.exact
|
const matchers = options.exact
|
||||||
? [...this.customTesters, this.utils.iterableEquality]
|
? [...this.customTesters, this.utils.iterableEquality]
|
||||||
: [...this.customTesters, this.utils.subsetEquality, 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 {
|
return {
|
||||||
pass,
|
pass,
|
||||||
message: () =>
|
message: () => `Expected ${getPokemonNameWithAffix(received)} to have types ${expectedStr}, but got ${actualStr}!`,
|
||||||
`Expected ${getPokemonNameWithAffix(received)} to have types ${this.utils.stringify(expectedSorted)}, but got ${actualSorted}!`,
|
actual: actualTypes,
|
||||||
actual: actualSorted,
|
expected: expectedTypes,
|
||||||
expected: expectedSorted,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ interface getEnumStrOptions {
|
|||||||
* @param obj - The {@linkcode EnumOrObject} to source reverse mappings from
|
* @param obj - The {@linkcode EnumOrObject} to source reverse mappings from
|
||||||
* @param enums - One of {@linkcode obj}'s values
|
* @param enums - One of {@linkcode obj}'s values
|
||||||
* @param casing - A string denoting the casing method to use; default `Preserve`
|
* @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.
|
* @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.
|
* @returns The stringified representation of `val` as dictated by the options.
|
||||||
* @example
|
* @example
|
||||||
@ -38,7 +38,6 @@ interface getEnumStrOptions {
|
|||||||
* console.log(getEnumStr(fakeEnum, fakeEnum.ONE)); // Output: "ONE (=1)"
|
* console.log(getEnumStr(fakeEnum, fakeEnum.ONE)); // Output: "ONE (=1)"
|
||||||
* console.log(getEnumStr(fakeEnum, fakeEnum.TWO, {case: "Title", suffix: " Terrain"})); // Output: "Two Terrain (=2)"
|
* console.log(getEnumStr(fakeEnum, fakeEnum.TWO, {case: "Title", suffix: " Terrain"})); // Output: "Two Terrain (=2)"
|
||||||
* ```
|
* ```
|
||||||
|
|
||||||
*/
|
*/
|
||||||
export function getEnumStr<E extends EnumOrObject>(
|
export function getEnumStr<E extends EnumOrObject>(
|
||||||
obj: E,
|
obj: E,
|
||||||
|
Loading…
Reference in New Issue
Block a user