mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-12-24 02:29:25 +01:00
[Test] Improve error message + typing on toHaveUsedMove (#6681)
* [Test] Improve error message on `toHaveUsedMove` * Fixed typing on test stuff + added caching on `toHaveArenaTagOptions` * Fixed matcher breaking with single move arguments * Fixed typing errors in `vitest.d.ts` * Fixed typing importing from the wrong file * Fixed wish test type errors * Reverted type changes to battler tag matchers by request
This commit is contained in:
parent
f48ec4c51e
commit
b381d196cf
@ -1,4 +1,4 @@
|
||||
import type { AtLeastOne, NonFunctionPropertiesRecursive as nonFunc } from "#types/type-helpers";
|
||||
import type { AtLeastOne, NonFunctionProperties } from "#types/type-helpers";
|
||||
|
||||
/**
|
||||
* Helper type to admit an object containing the given properties
|
||||
@ -22,6 +22,6 @@ import type { AtLeastOne, NonFunctionPropertiesRecursive as nonFunc } from "#typ
|
||||
* @typeParam O - The object to source keys from
|
||||
* @typeParam K - One or more of O's keys to render mandatory
|
||||
*/
|
||||
export type OneOther<O extends object, K extends keyof O> = AtLeastOne<Omit<nonFunc<O>, K>> & {
|
||||
[key in K]: O[K];
|
||||
};
|
||||
// NB: no need to recursively exclude non function properties
|
||||
// TODO: Figure out how to force K to not be a method property
|
||||
export type OneOther<O extends object, K extends keyof O> = Pick<O, K> & AtLeastOne<Omit<NonFunctionProperties<O>, K>>;
|
||||
|
||||
6
test/@types/vitest.d.ts
vendored
6
test/@types/vitest.d.ts
vendored
@ -3,6 +3,7 @@ import "vitest";
|
||||
import type Overrides from "#app/overrides";
|
||||
import type { Phase } from "#app/phase";
|
||||
import type { ArenaTag } from "#data/arena-tag";
|
||||
import type { PositionalTag } from "#data/positional-tags/positional-tag";
|
||||
import type { TerrainType } from "#data/terrain";
|
||||
import type { AbilityId } from "#enums/ability-id";
|
||||
import type { ArenaTagSide } from "#enums/arena-tag-side";
|
||||
@ -10,11 +11,11 @@ import type { ArenaTagType } from "#enums/arena-tag-type";
|
||||
import type { BattlerTagType } from "#enums/battler-tag-type";
|
||||
import type { MoveId } from "#enums/move-id";
|
||||
import type { PokemonType } from "#enums/pokemon-type";
|
||||
import type { PositionalTag } from "#data/positional-tags/positional-tag";
|
||||
import type { PositionalTagType } from "#enums/positional-tag-type";
|
||||
import type { BattleStat, EffectiveStat } from "#enums/stat";
|
||||
import type { WeatherType } from "#enums/weather-type";
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
import type { OneOther } from "#test/@types/test-helpers";
|
||||
import type { GameManager } from "#test/test-utils/game-manager";
|
||||
import type { toHaveArenaTagOptions } from "#test/test-utils/matchers/to-have-arena-tag";
|
||||
import type { toHaveBattlerTagOptions } from "#test/test-utils/matchers/to-have-battler-tag";
|
||||
@ -24,7 +25,6 @@ import type { expectedStatusType } from "#test/test-utils/matchers/to-have-statu
|
||||
import type { toHaveTypesOptions } from "#test/test-utils/matchers/to-have-types";
|
||||
import type { PhaseString } from "#types/phase-types";
|
||||
import type { TurnMove } from "#types/turn-move";
|
||||
import type { AtLeastOne } from "#types/type-helpers";
|
||||
import type { toDmgValue } from "#utils/common";
|
||||
import type { expect } from "vitest";
|
||||
|
||||
@ -154,7 +154,7 @@ interface PokemonMatchers {
|
||||
* @param index - The index of the move history entry to check, in order from most recent to least recent; default `0`
|
||||
* @see {@linkcode Pokemon.getLastXMoves}
|
||||
*/
|
||||
toHaveUsedMove(expectedMove: MoveId | AtLeastOne<TurnMove>, index?: number): void;
|
||||
toHaveUsedMove(expectedMove: MoveId | OneOther<TurnMove, "move">, index?: number): void;
|
||||
|
||||
/**
|
||||
* Check whether a {@linkcode Pokemon}'s effective stat is as expected
|
||||
|
||||
@ -79,7 +79,7 @@ describe("Moves - Sleep Talk", () => {
|
||||
game.move.select(MoveId.SLEEP_TALK);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(feebas).toHaveUsedMove({ result: MoveResult.FAIL });
|
||||
expect(feebas).toHaveUsedMove({ move: MoveId.SLEEP_TALK, result: MoveResult.FAIL });
|
||||
});
|
||||
|
||||
it("should fail if the user has no valid moves", async () => {
|
||||
|
||||
@ -79,7 +79,7 @@ describe("Move - Wish", () => {
|
||||
await game.toEndOfTurn();
|
||||
|
||||
expect(alomomola.hp).toBe(toDmgValue(alomomola.getMaxHp() / 2) + 1);
|
||||
expect(alomomola).toHaveUsedMove({ result: MoveResult.FAIL });
|
||||
expect(alomomola).toHaveUsedMove({ move: MoveId.WISH, result: MoveResult.FAIL });
|
||||
});
|
||||
|
||||
it("should function independently of Future Sight", async () => {
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import type { MoveId } from "#enums/move-id";
|
||||
import { MoveId } from "#enums/move-id";
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
import { getOnelineDiffStr, getOrdinal } from "#test/test-utils/string-utils";
|
||||
import type { OneOther } from "#test/@types/test-helpers";
|
||||
import { getEnumStr, getOnelineDiffStr, getOrdinal } from "#test/test-utils/string-utils";
|
||||
import { isPokemonInstance, receivedStr } from "#test/test-utils/test-utils";
|
||||
import type { TurnMove } from "#types/turn-move";
|
||||
import type { AtLeastOne } from "#types/type-helpers";
|
||||
import type { MatcherState, SyncExpectationResult } from "@vitest/expect";
|
||||
|
||||
/**
|
||||
@ -12,14 +12,14 @@ import type { MatcherState, SyncExpectationResult } from "@vitest/expect";
|
||||
* @param received - The actual value received. Should be a {@linkcode Pokemon}
|
||||
* @param expectedMove - The {@linkcode MoveId} the Pokemon is expected to have used,
|
||||
* or a partially filled {@linkcode TurnMove} containing the desired properties to check
|
||||
* @param index - The index of the move history entry to check, in order from most recent to least recent.
|
||||
* Default `0` (last used move)
|
||||
* @param index - The index of the move history entry to check, in order from most recent to least recent;
|
||||
* default `0` (last used move)
|
||||
* @returns Whether the matcher passed
|
||||
*/
|
||||
export function toHaveUsedMove(
|
||||
this: MatcherState,
|
||||
received: unknown,
|
||||
expectedMove: MoveId | AtLeastOne<TurnMove>,
|
||||
expectedMove: MoveId | OneOther<TurnMove, "move">,
|
||||
index = 0,
|
||||
): SyncExpectationResult {
|
||||
if (!isPokemonInstance(received)) {
|
||||
@ -29,10 +29,10 @@ export function toHaveUsedMove(
|
||||
};
|
||||
}
|
||||
|
||||
const move: TurnMove | undefined = received.getLastXMoves(-1)[index];
|
||||
const historyMove: TurnMove | undefined = received.getLastXMoves(-1)[index];
|
||||
const pkmName = getPokemonNameWithAffix(received);
|
||||
|
||||
if (move === undefined) {
|
||||
if (historyMove === undefined) {
|
||||
return {
|
||||
pass: this.isNot,
|
||||
message: () => `Expected ${pkmName} to have used ${index + 1} moves, but it didn't!`,
|
||||
@ -40,20 +40,37 @@ export function toHaveUsedMove(
|
||||
};
|
||||
}
|
||||
|
||||
// Coerce to a `TurnMove`
|
||||
if (typeof expectedMove === "number") {
|
||||
expectedMove = { move: expectedMove };
|
||||
}
|
||||
|
||||
const moveIndexStr = index === 0 ? "last move" : `${getOrdinal(index)} most recent move`;
|
||||
|
||||
const pass = this.equals(move, expectedMove, [
|
||||
// Break out early if a move-only comparison was done or if the move ID did not match
|
||||
const expectedId = typeof expectedMove === "number" ? expectedMove : expectedMove.move;
|
||||
const actualId = historyMove.move;
|
||||
const sameId = this.equals(actualId, expectedId, this.customTesters);
|
||||
|
||||
if (typeof expectedMove === "number" || !sameId) {
|
||||
const expectedIdStr = getEnumStr(MoveId, expectedId);
|
||||
const actualIdStr = getEnumStr(MoveId, actualId);
|
||||
return {
|
||||
pass: sameId,
|
||||
// Expected Magikarp' 5th most recent move to be PHOTON_GEYSER, but got METRONOME instead!
|
||||
message: () =>
|
||||
sameId
|
||||
? `Expected ${pkmName}'s ${moveIndexStr} to NOT be ${expectedIdStr}, but it was!`
|
||||
: `Expected ${pkmName}'s ${moveIndexStr} to be ${expectedIdStr}, but got ${actualIdStr} instead!`,
|
||||
expected: expectedMove,
|
||||
actual: historyMove,
|
||||
};
|
||||
}
|
||||
|
||||
// Compare equality with the provided object
|
||||
const pass = this.equals(historyMove, expectedMove, [
|
||||
...this.customTesters,
|
||||
this.utils.subsetEquality,
|
||||
this.utils.iterableEquality,
|
||||
]);
|
||||
|
||||
const expectedStr = getOnelineDiffStr.call(this, expectedMove);
|
||||
|
||||
return {
|
||||
pass,
|
||||
message: () =>
|
||||
@ -61,6 +78,6 @@ export function toHaveUsedMove(
|
||||
? `Expected ${pkmName}'s ${moveIndexStr} to NOT match ${expectedStr}, but it did!`
|
||||
: `Expected ${pkmName}'s ${moveIndexStr} to match ${expectedStr}, but it didn't!`,
|
||||
expected: expectedMove,
|
||||
actual: move,
|
||||
actual: historyMove,
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user