diablo2-web/tests/drlg-alias-guard.test.ts

82 lines
4.0 KiB
TypeScript

import { describe, expect, test } from "vitest"
import { readFileSync } from "node:fs"
import { resolve } from "node:path"
import * as wilderness from "../src/game/wilderness.ts"
import * as maze from "../src/game/maze.ts"
import * as levelLinks from "../src/game/level-links.ts"
describe("DRLG Export and Alias Guard (Issue #81)", () => {
const getDrlgExports = (mod: Record<string, unknown>): string[] => {
return Object.keys(mod).filter((name) => name.startsWith("DRLG"))
}
test("src/game/wilderness.ts does not export fake Blizzard aliases", () => {
const exports = getDrlgExports(wilderness as Record<string, unknown>)
expect(exports).not.toContain("DRLGROOMTILE_ComputeNeighborMask")
expect(exports).not.toContain("DRLGROOMTILE_ApplyTransitions")
// The invented 8-neighbour ground-transition pass (computeNeighborMask /
// applyGroundTransitions) was removed with the Act I DRLG port: Act I
// outdoor maps now come from the 1:1 D2MOO port in src/game/drlg.
expect((wilderness as Record<string, unknown>).computeNeighborMask).toBeUndefined()
expect((wilderness as Record<string, unknown>).applyGroundTransitions).toBeUndefined()
})
test("src/game/wilderness.ts keeps single export of DRLGOUTDOORS_SpawnAct12Waypoint", () => {
const exports = getDrlgExports(wilderness as Record<string, unknown>)
expect(exports).toContain("DRLGOUTDOORS_SpawnAct12Waypoint")
expect(typeof wilderness.DRLGOUTDOORS_SpawnAct12Waypoint).toBe("function")
})
test("src/game/level-links.ts does not export duplicate DRLGOUTDOORS_SpawnAct12Waypoint", () => {
const exports = getDrlgExports(levelLinks as Record<string, unknown>)
expect(exports).not.toContain("DRLGOUTDOORS_SpawnAct12Waypoint")
expect(exports).not.toContain("DRLGROOMTILE_ComputeNeighborMask")
expect(exports).not.toContain("DRLGROOMTILE_ApplyTransitions")
// findWaypointSpot remains exported as a local helper
expect(typeof levelLinks.findWaypointSpot).toBe("function")
})
test("src/game/maze.ts does not export fake Blizzard DRLG aliases", () => {
const exports = getDrlgExports(maze as Record<string, unknown>)
expect(exports).not.toContain("DRLGROOMTILE_ComputeNeighborMask")
expect(exports).not.toContain("DRLGROOMTILE_ApplyTransitions")
expect(exports).not.toContain("DRLGOUTDOORS_SpawnAct12Waypoint")
})
test("DRLGOUTDOORS_SpawnAct12Waypoint has at most ONE export across wilderness, maze, and level-links", () => {
const allDrlgExports = [
...getDrlgExports(wilderness as Record<string, unknown>),
...getDrlgExports(maze as Record<string, unknown>),
...getDrlgExports(levelLinks as Record<string, unknown>),
]
const waypointExports = allDrlgExports.filter((name) => name === "DRLGOUTDOORS_SpawnAct12Waypoint")
expect(waypointExports).toHaveLength(1)
})
test("Static source check: no fake DRLG export statements in source files", () => {
const files = [
resolve(__dirname, "../src/game/wilderness.ts"),
resolve(__dirname, "../src/game/maze.ts"),
resolve(__dirname, "../src/game/level-links.ts"),
]
for (const filePath of files) {
const source = readFileSync(filePath, "utf-8")
expect(source).not.toMatch(/export\s+(?:const|function|let|var)\s+DRLGROOMTILE_ComputeNeighborMask\b/)
expect(source).not.toMatch(/export\s+(?:const|function|let|var)\s+DRLGROOMTILE_ApplyTransitions\b/)
}
// Ensure level-links.ts does not export DRLGOUTDOORS_SpawnAct12Waypoint
const levelLinksSource = readFileSync(resolve(__dirname, "../src/game/level-links.ts"), "utf-8")
expect(levelLinksSource).not.toMatch(/export\s+(?:const|function|let|var)\s+DRLGOUTDOORS_SpawnAct12Waypoint\b/)
// The invented (non-Blizzard) ground-transition helpers must not come back.
const wildernessSource = readFileSync(resolve(__dirname, "../src/game/wilderness.ts"), "utf-8")
expect(wildernessSource).not.toMatch(/function computeNeighborMask\b/)
expect(wildernessSource).not.toMatch(/function applyGroundTransitions\b/)
})
})