import { createHash } from "node:crypto"; import { readFileSync } from "node:fs"; import { describe, expect, it } from "vitest"; import { DUNGEON_DEFINITIONS, requireDungeonDefinition } from "./dungeonRegistry"; import { dungeonArtworkContains, dungeonArtworkFloorFor, dungeonArtworkHeading, dungeonArtworkMapFor, dungeonArtworkPoint } from "./dungeonArtworkMap"; describe("RuneWaker dungeon maps", () => { it("packages a checksummed, position-aware map with every RuneWaker dungeon", () => { const dungeons = DUNGEON_DEFINITIONS.filter((dungeon) => dungeon.expansion === "runewaker"); expect(dungeons).toHaveLength(33); for (const dungeon of dungeons) { const map = dungeonArtworkMapFor(dungeon); expect(map, dungeon.id).not.toBeNull(); expect(map?.kind, dungeon.id).toBe("runewaker"); if (!map) continue; const floor = dungeonArtworkFloorFor(map, dungeon.entrance.footPosition); const image = readFileSync(`public${floor.image}`); expect(image.toString("ascii", 1, 4), dungeon.id).toBe("PNG"); expect([image.readUInt32BE(16), image.readUInt32BE(20)]).toEqual([1002, 668]); expect(createHash("sha256").update(image).digest("hex")).toBe(floor.checksum); expect(dungeonArtworkContains(map, floor, dungeon.entrance.footPosition), dungeon.id).toBe(true); expect(dungeonArtworkPoint(map, floor, dungeon.entrance.footPosition).every(Number.isFinite)).toBe(true); expect(Math.hypot(...dungeonArtworkHeading(map, floor, dungeon.entrance.footPosition, 0.7))).toBeCloseTo(23, 5); } }); it("rejects stale maps when a dungeon environment changes", () => { const dungeon = requireDungeonDefinition("forsaken-abbey"); expect(dungeonArtworkMapFor({ ...dungeon, provenance: { ...dungeon.provenance, coordinateTransform: "changed" } })).toBeNull(); expect(dungeonArtworkMapFor({ ...dungeon, assets: { ...dungeon.assets, visual: [] } })).toBeNull(); }); });