Added util to make it.each test cases from a bunch of enums

This commit is contained in:
Bertie690 2025-09-09 19:04:36 -04:00
parent b0a46efb68
commit f2198e60bf
2 changed files with 43 additions and 8 deletions

View File

@ -6,7 +6,7 @@ import { BattleType } from "#enums/battle-type";
import { MoveId } from "#enums/move-id";
import { SpeciesId } from "#enums/species-id";
import { GameManager } from "#test/test-utils/game-manager";
import { getEnumValues } from "#utils/enums";
import { getEnumTestCases } from "#test/test-utils/string-utils";
import { toTitleCase } from "#utils/strings";
import i18next from "i18next";
import Phaser from "phaser";
@ -47,7 +47,7 @@ describe("Arena Tags", () => {
vi.spyOn(game.scene.phaseManager, "queueMessage").mockImplementation((text, callbackDelay, prompt, promptDelay) =>
game.scene.ui.showText(text, null, null, callbackDelay, prompt, promptDelay),
);
game.textInterceptor.logs = [];
game.textInterceptor.clearLogs();
});
// These tags are either ineligible or just jaaaaaaaaaaank
@ -60,9 +60,9 @@ describe("Arena Tags", () => {
name: toTitleCase(t),
}));
describe.each(arenaTags)("$name", ({ tagType }) => {
it.each(getEnumValues(ArenaTagSide))(
"should display a message on addition, and a separate one on removal",
side => {
it.each(getEnumTestCases(ArenaTagSide))(
"should display a message on addition, and a separate one on removal - ArenaTagSide.$name",
({ value: side }) => {
game.scene.arena.addTag(tagType, 0, undefined, playerId, side);
expect(game).toHaveArenaTag(tagType, side);
@ -79,7 +79,7 @@ describe("Arena Tags", () => {
expect(game.textInterceptor.logs).toHaveLength(0);
}
game.textInterceptor.logs = [];
game.textInterceptor.clearLogs();
game.scene.arena.removeTagOnSide(tagType, side, false);
if (tag["onRemoveMessageKey"]) {

View File

@ -1,10 +1,12 @@
import { getStatKey, type Stat } from "#enums/stat";
import type { EnumOrObject, NormalEnum, TSNumericEnum } from "#types/enum-types";
import type { ObjectValues } from "#types/type-helpers";
import { enumValueToKey } from "#utils/enums";
import { enumValueToKey, getEnumValues } from "#utils/enums";
import { toTitleCase } from "#utils/strings";
import type { MatcherState } from "@vitest/expect";
import i18next from "i18next";
// biome-ignore lint/correctness/noUnusedImports: TSDoc
import type { describe, it } from "vitest";
type Casing = "Preserve" | "Title";
@ -87,7 +89,7 @@ export function getEnumStr<E extends EnumOrObject>(
* ```
*/
export function stringifyEnumArray<E extends EnumOrObject>(obj: E, enums: E[keyof E][]): string {
if (obj.length === 0) {
if (enums.length === 0) {
return "[]";
}
@ -185,3 +187,36 @@ export function getOnelineDiffStr(this: MatcherState, obj: unknown): string {
.replace(/\n/g, " ") // Replace newlines with spaces
.replace(/,(\s*)\}$/g, "$1}"); // Trim trailing commas
}
/**
* Convert an enum or `const object` into an array of object literals
* suitable for use inside {@linkcode describe.each} or {@linkcode it.each}.
* @param obj - The {@linkcode EnumOrObject} to source reverse mappings from
* @param values - An array containing one or more of `obj`'s values to convert.
* Defaults to all the enum's values.
* @param options - Options to pass to {@linkcode getEnumStr}
* @returns An array of objects containing the enum's name and value.
* @example
* ```ts
* enum fakeEnum {
* ONE: 1,
* TWO: 2,
* THREE: 3,
* }
* describe.each(getEnumTestCases(fakeEnum))("should do XYZ - $name", ({value}) => {});
* ```
*/
export function getEnumTestCases<E extends EnumOrObject>(
obj: E,
values: E[keyof E][] = isTSNumericEnum(obj) ? getEnumValues(obj) : (Object.values(obj) as E[keyof E][]),
options: getEnumStrOptions = {},
): { value: E[keyof E]; name: string }[] {
return values.map(e => ({
value: e,
name: getEnumStr(obj, e, options),
}));
}
function isTSNumericEnum<E extends EnumOrObject>(obj: E): obj is TSNumericEnum<E> {
return Object.keys(obj).some(k => typeof k === "number");
}