forked from phenom/healer-man
73 lines
3.2 KiB
TypeScript
73 lines
3.2 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import type { PartyRole } from "../partyRoles";
|
|
import { BENCHMARK_SCENARIOS, benchmarkScenarioById } from "./benchmarkScenarios";
|
|
|
|
const EXPECTED_DURATIONS_MS: Readonly<Record<string, number>> = 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);
|
|
}
|
|
});
|
|
});
|