mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-06 07:29:30 +02:00
Grabbed matchers from other branch
This commit is contained in:
parent
0bc78cb715
commit
ba48f16500
26
test/@types/vitest.d.ts
vendored
26
test/@types/vitest.d.ts
vendored
@ -1,20 +1,27 @@
|
||||
import type { TerrainType } from "#app/data/terrain";
|
||||
import type { ArenaTag, ArenaTagTypeMap } from "#data/arena-tag";
|
||||
import type { AbilityId } from "#enums/ability-id";
|
||||
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 { BattleStat, EffectiveStat, Stat } from "#enums/stat";
|
||||
import type { StatusEffect } from "#enums/status-effect";
|
||||
import type { WeatherType } from "#enums/weather-type";
|
||||
import type { Arena } from "#field/arena";
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
import type { ToHaveEffectiveStatMatcherOptions } from "#test/test-utils/matchers/to-have-effective-stat";
|
||||
import type { expectedStatusType } from "#test/test-utils/matchers/to-have-status-effect";
|
||||
import type { toHaveTypesOptions } from "#test/test-utils/matchers/to-have-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";
|
||||
import "vitest";
|
||||
import type Overrides from "#app/overrides";
|
||||
import type { ArenaTagSide } from "#enums/arena-tag-side";
|
||||
import type { PokemonMove } from "#moves/pokemon-move";
|
||||
import type { OneOther } from "#test/@types/test-helpers";
|
||||
|
||||
declare module "vitest" {
|
||||
interface Assertion {
|
||||
@ -35,6 +42,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;
|
||||
|
||||
/**
|
||||
@ -79,6 +87,24 @@ declare module "vitest" {
|
||||
*/
|
||||
toHaveTerrain(expectedTerrainType: TerrainType): void;
|
||||
|
||||
/**
|
||||
* Check whether the current {@linkcode Arena} contains the given {@linkcode ArenaTag}.
|
||||
*
|
||||
* @param expectedType - A partially-filled {@linkcode ArenaTag} containing the desired properties
|
||||
*/
|
||||
toHaveArenaTag<T extends ArenaTagType>(
|
||||
expectedType: OneOther<ArenaTagTypeMap[T], "tagType" | "side"> & { tagType: T }, // intersection required bc this doesn't preserve T
|
||||
): void;
|
||||
/**
|
||||
* Check whether the current {@linkcode Arena} contains the given {@linkcode ArenaTag}.
|
||||
*
|
||||
* @param expectedType - The {@linkcode ArenaTagType} of the desired tag
|
||||
* @param side - The {@linkcode ArenaTagSide | side of the field} the tag should affect, or
|
||||
* {@linkcode ArenaTagSide.BOTH} to check both sides;
|
||||
* default `ArenaTagSide.BOTH`
|
||||
*/
|
||||
toHaveArenaTag(expectedType: ArenaTagType, side?: ArenaTagSide): void;
|
||||
|
||||
/**
|
||||
* Check whether a {@linkcode Pokemon} is at full HP.
|
||||
*/
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { toEqualArrayUnsorted } from "#test/test-utils/matchers/to-equal-array-unsorted";
|
||||
import { toHaveAbilityApplied } from "#test/test-utils/matchers/to-have-ability-applied";
|
||||
import { toHaveArenaTag } from "#test/test-utils/matchers/to-have-arena-tag";
|
||||
import { toHaveBattlerTag } from "#test/test-utils/matchers/to-have-battler-tag";
|
||||
import { toHaveEffectiveStat } from "#test/test-utils/matchers/to-have-effective-stat";
|
||||
import { toHaveFainted } from "#test/test-utils/matchers/to-have-fainted";
|
||||
@ -28,6 +29,7 @@ expect.extend({
|
||||
toHaveTakenDamage,
|
||||
toHaveWeather,
|
||||
toHaveTerrain,
|
||||
toHaveArenaTag,
|
||||
toHaveFullHp,
|
||||
toHaveStatusEffect,
|
||||
toHaveStatStage,
|
||||
|
80
test/test-utils/matchers/to-have-arena-tag.ts
Normal file
80
test/test-utils/matchers/to-have-arena-tag.ts
Normal file
@ -0,0 +1,80 @@
|
||||
import type { ArenaTag, ArenaTagTypeMap } from "#data/arena-tag";
|
||||
import type { ArenaTagSide } from "#enums/arena-tag-side";
|
||||
import { ArenaTagType } from "#enums/arena-tag-type";
|
||||
import type { OneOther } from "#test/@types/test-helpers";
|
||||
// biome-ignore lint/correctness/noUnusedImports: TSDoc
|
||||
import type { GameManager } from "#test/test-utils/game-manager";
|
||||
import { getEnumStr, getOnelineDiffStr, stringifyEnumArray } from "#test/test-utils/string-utils";
|
||||
import { isGameManagerInstance, receivedStr } from "#test/test-utils/test-utils";
|
||||
import type { NonFunctionPropertiesRecursive } from "#types/type-helpers";
|
||||
import type { MatcherState, SyncExpectationResult } from "@vitest/expect";
|
||||
|
||||
export type toHaveArenaTagOptions<T extends ArenaTagType> = OneOther<ArenaTagTypeMap[T], "tagType">;
|
||||
|
||||
/**
|
||||
* Matcher to check if the {@linkcode Arena} has a given {@linkcode ArenaTag} active.
|
||||
* @param received - The object to check. Should be the current {@linkcode GameManager}.
|
||||
* @param expectedType - The {@linkcode ArenaTagType} of the desired tag, or a partially-filled object
|
||||
* containing the desired properties
|
||||
* @param side - The {@linkcode ArenaTagSide | side of the field} the tag should affect, or
|
||||
* {@linkcode ArenaTagSide.BOTH} to check both sides
|
||||
* @returns The result of the matching
|
||||
*/
|
||||
export function toHaveArenaTag<T extends ArenaTagType>(
|
||||
this: MatcherState,
|
||||
received: unknown,
|
||||
// simplified types used for brevity; full overloads are in `vitest.d.ts`
|
||||
expectedType: T | (Partial<NonFunctionPropertiesRecursive<ArenaTag>> & { tagType: T; side: ArenaTagSide }),
|
||||
side?: ArenaTagSide,
|
||||
): SyncExpectationResult {
|
||||
if (!isGameManagerInstance(received)) {
|
||||
return {
|
||||
pass: this.isNot,
|
||||
message: () => `Expected to recieve a GameManager, but got ${receivedStr(received)}!`,
|
||||
};
|
||||
}
|
||||
|
||||
if (!received.scene?.arena) {
|
||||
return {
|
||||
pass: false,
|
||||
message: () => `Expected GameManager.${received.scene ? "scene" : "scene.arena"} to be defined!`,
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof expectedType === "string") {
|
||||
// Coerce lone `tagType`s into objects
|
||||
// Bangs are ok as we enforce safety via overloads
|
||||
expectedType = { tagType: expectedType, side: side! };
|
||||
}
|
||||
|
||||
// We need to get all tags for the case of checking properties of a tag present on both sides of the arena
|
||||
const tags = received.scene.arena.findTagsOnSide(t => t.tagType === expectedType.tagType, expectedType.side);
|
||||
if (!tags.length) {
|
||||
const expectedStr = getEnumStr(ArenaTagType, expectedType.tagType);
|
||||
return {
|
||||
pass: false,
|
||||
message: () => `Expected the arena to have a tag matching ${expectedStr}, but it didn't!`,
|
||||
expected: getEnumStr(ArenaTagType, expectedType.tagType),
|
||||
actual: stringifyEnumArray(
|
||||
ArenaTagType,
|
||||
received.scene.arena.tags.map(t => t.tagType),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
// Pass if any of the matching tags meet our criteria
|
||||
const pass = tags.some(tag =>
|
||||
this.equals(tag, expectedType, [...this.customTesters, this.utils.subsetEquality, this.utils.iterableEquality]),
|
||||
);
|
||||
|
||||
const expectedStr = getOnelineDiffStr.call(this, expectedType);
|
||||
return {
|
||||
pass,
|
||||
message: () =>
|
||||
pass
|
||||
? `Expected the arena to NOT have a tag matching ${expectedStr}, but it did!`
|
||||
: `Expected the arena to have a tag matching ${expectedStr}, but it didn't!`,
|
||||
expected: expectedType,
|
||||
actual: tags,
|
||||
};
|
||||
}
|
@ -37,10 +37,8 @@ export function toHaveStatusEffect(
|
||||
const actualEffect = received.status?.effect ?? StatusEffect.NONE;
|
||||
|
||||
// Check exclusively effect equality first, coercing non-matching status effects to numbers.
|
||||
if (actualEffect !== (expectedStatus as Exclude<typeof expectedStatus, StatusEffect>)?.effect) {
|
||||
// This is actually 100% safe as `expectedStatus?.effect` will evaluate to `undefined` if a StatusEffect was passed,
|
||||
// which will never match actualEffect by definition
|
||||
expectedStatus = (expectedStatus as Exclude<typeof expectedStatus, StatusEffect>).effect;
|
||||
if (typeof expectedStatus === "object" && actualEffect !== expectedStatus.effect) {
|
||||
expectedStatus = expectedStatus.effect;
|
||||
}
|
||||
|
||||
if (typeof expectedStatus === "number") {
|
||||
|
Loading…
Reference in New Issue
Block a user