import { describe, expect, it } from "vitest"; import type { PartyRole } from "../partyRoles"; import { BENCHMARK_SCENARIOS, benchmarkScenarioById } from "./benchmarkScenarios"; const EXPECTED_DURATIONS_MS: Readonly> = Object.freeze({ "damage-single-burst": 30_000, "damage-single-sustained": 180_000, "damage-cleave-three": 90_000, "damage-aoe-eight": 60_000, "tank-mixed-boss": 180_000, "tank-multi-target": 120_000, "heal-single-target": 90_000, "heal-spread-party": 180_000, "heal-stacked-party": 90_000, "heal-resource-endurance": 600_000, "mechanic-movement-boss": 180_000, "mechanic-stack-boss": 180_000, }); describe("benchmark scenario catalog", () => { it("uses unique stable ids and positive integer versions", () => { const ids = BENCHMARK_SCENARIOS.map((scenario) => scenario.id); expect(ids).toHaveLength(Object.keys(EXPECTED_DURATIONS_MS).length); expect(new Set(ids).size).toBe(ids.length); expect([...ids].sort()).toEqual(Object.keys(EXPECTED_DURATIONS_MS).sort()); expect(BENCHMARK_SCENARIOS.every( (scenario) => Number.isInteger(scenario.version) && scenario.version >= 1, )).toBe(true); expect(BENCHMARK_SCENARIOS.every((scenario) => scenario.version === 1)).toBe(true); for (const scenario of BENCHMARK_SCENARIOS) { expect(benchmarkScenarioById(scenario.id)).toBe(scenario); } expect(benchmarkScenarioById("missing-scenario")).toBeNull(); }); it("covers every combat role and keeps role-specific families scoped", () => { const expectedRoles: readonly PartyRole[] = ["tank", "healer", "damage"]; const coveredRoles = new Set(BENCHMARK_SCENARIOS.flatMap((scenario) => scenario.roles)); expect([...coveredRoles].sort()).toEqual([...expectedRoles].sort()); expect(BENCHMARK_SCENARIOS.every((scenario) => ( scenario.roles.length > 0 && scenario.roles.every((role) => expectedRoles.includes(role)) ))).toBe(true); expect(BENCHMARK_SCENARIOS.filter((scenario) => scenario.family === "damage") .every((scenario) => scenario.roles.length === 1 && scenario.roles[0] === "damage")) .toBe(true); expect(BENCHMARK_SCENARIOS.filter((scenario) => scenario.family === "tanking") .every((scenario) => scenario.roles.length === 1 && scenario.roles[0] === "tank")) .toBe(true); expect(BENCHMARK_SCENARIOS.filter((scenario) => ( scenario.family === "healing" || scenario.family === "endurance" )).every((scenario) => scenario.roles.length === 1 && scenario.roles[0] === "healer")) .toBe(true); expect(BENCHMARK_SCENARIOS.filter((scenario) => scenario.family === "mechanics") .every((scenario) => expectedRoles.every((role) => scenario.roles.includes(role)))) .toBe(true); }); it("preserves exact durations on an integral fixed-step timeline", () => { for (const scenario of BENCHMARK_SCENARIOS) { expect(scenario.durationMs).toBe(EXPECTED_DURATIONS_MS[scenario.id]); expect(Number.isInteger(scenario.durationMs)).toBe(true); expect(Number.isInteger(scenario.tickMs)).toBe(true); expect(scenario.durationMs).toBeGreaterThan(0); expect(scenario.tickMs).toBeGreaterThan(0); expect(scenario.durationMs % scenario.tickMs).toBe(0); } }); });