Files
healer-man/src/game/runewakerObjectiveRouteAudit.test.ts
T
2026-09-08 10:40:26 -04:00

62 lines
2.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { BufferGeometry, Float32BufferAttribute } from "three";
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import { buildPartyNavigationGraph } from "./partyNavigation";
import { auditOrderedObjectiveRoutes } from "../../scripts/runewaker-pipeline/lib/objective-route-audit.mjs";
describe("RuneWaker ordered objective route audit", () => {
it("does not substitute the last reachable point for an unreachable predecessor", () => {
const geometry = new BufferGeometry();
geometry.setAttribute("position", new Float32BufferAttribute([
0, 0, 0, 4, 0, 0, 0, 0, 4,
20, 0, 0, 21, 0, 0, 20, 0, 1,
], 3));
const graph = buildPartyNavigationGraph(geometry);
const routes = auditOrderedObjectiveRoutes(graph, [1, 0, 1], [
{ id: "island-boss", name: "Island Boss", position: [20, 0, 0] },
{ id: "home-boss", name: "Home Boss", position: [2, 0, 1] },
]);
expect(routes.map(({ from, to, reachable }) => ({ from, to, reachable }))).toEqual([
{ from: "entrance", to: "Island Boss", reachable: false },
{ from: "Island Boss", to: "Home Boss", reachable: false },
]);
});
it("keeps the reviewed navigation blockers deterministic and fail-closed", () => {
const report = JSON.parse(readFileSync(resolve(
"scripts/runewaker-pipeline/RUNEWAKER_NAVIGATION_GAP_REPORT.json",
), "utf8"));
expect(report.schemaVersion).toBe(2);
expect(report).not.toHaveProperty("generatedAt");
expect(report.unreachableLegs).toBe(19);
expect(report.dungeons).toHaveLength(8);
expect(report.resolutionSummary).toEqual({
sourceAuthoredFixedOrders: 0,
authoredOffMeshLinksAdded: 0,
requirementDungeonCounts: {
"dynamic-navigation-transition": 5,
"encounter-gate-state": 3,
"encounter-teleport-state": 2,
"modular-environment-assembly": 3,
"navigation-geometry-review": 1,
"nonlinear-objectives": 1,
"source-objective-review": 6,
},
});
expect(report.dungeons.every((dungeon: {
objectiveOrdering: { authoritative: boolean };
reviewedFinding: { safeAutomaticLink: boolean; requirements: string[] };
}) => (
dungeon.objectiveOrdering.authoritative === false
&& dungeon.reviewedFinding.safeAutomaticLink === false
&& dungeon.reviewedFinding.requirements.length > 0
))).toBe(true);
expect(report.dungeons.find((dungeon: { id: string }) => (
dungeon.id === "kalins-shrine"
))?.reviewedFinding.objectiveOrderStatus).toBe("source-randomized-not-linear");
});
});