import { describe, expect, it } from "vitest"; import { axialNeighbors, isConnected, shortestPath, shortestPathLength, } from "../../src/stages/games/chase/logic/hexGraph"; import type { GameGraph } from "../../src/stages/games/chase/logic/types"; function buildGraph(nodes: GameGraph["nodes"]): GameGraph { return { nodes, edgeList: [], }; } describe("hex graph utilities", () => { it("returns 6 axial neighbors", () => { const neighbors = axialNeighbors(0, 0); expect(neighbors).toEqual([ [1, 0], [1, -1], [0, -1], [-1, 0], [-1, 1], [0, 1], ]); }); it("finds bfs shortest path length", () => { const graph = buildGraph({ A: { id: "A", q: 0, r: 0, neighbors: ["B"] }, B: { id: "B", q: 1, r: 0, neighbors: ["A", "C"] }, C: { id: "C", q: 2, r: 0, neighbors: ["B", "D"] }, D: { id: "D", q: 3, r: 0, neighbors: ["C"] }, }); expect(shortestPathLength(graph, "A", "D")).toBe(3); expect(shortestPathLength(graph, "A", "A")).toBe(0); expect(shortestPath(graph, "A", "D")).toEqual(["A", "B", "C", "D"]); }); it("returns Infinity when target is unreachable", () => { const graph = buildGraph({ A: { id: "A", q: 0, r: 0, neighbors: ["B"] }, B: { id: "B", q: 1, r: 0, neighbors: ["A"] }, C: { id: "C", q: 5, r: 5, neighbors: [] }, }); expect(shortestPathLength(graph, "A", "C")).toBe(Infinity); }); it("returns Infinity for invalid from/to nodes", () => { const graph = buildGraph({ A: { id: "A", q: 0, r: 0, neighbors: ["B"] }, B: { id: "B", q: 1, r: 0, neighbors: ["A"] }, }); expect(shortestPathLength(graph, "X", "X")).toBe(Infinity); expect(shortestPathLength(graph, "X", "A")).toBe(Infinity); expect(shortestPathLength(graph, "A", "X")).toBe(Infinity); }); it("checks graph connectivity", () => { const connectedGraph = buildGraph({ A: { id: "A", q: 0, r: 0, neighbors: ["B"] }, B: { id: "B", q: 1, r: 0, neighbors: ["A", "C"] }, C: { id: "C", q: 2, r: 0, neighbors: ["B"] }, }); const disconnectedGraph = buildGraph({ A: { id: "A", q: 0, r: 0, neighbors: ["B"] }, B: { id: "B", q: 1, r: 0, neighbors: ["A"] }, C: { id: "C", q: 5, r: 5, neighbors: [] }, }); expect(isConnected(connectedGraph)).toBe(true); expect(isConnected(disconnectedGraph)).toBe(false); }); it("treats empty and single-node graph as connected", () => { const emptyGraph = buildGraph({}); const singleNodeGraph = buildGraph({ A: { id: "A", q: 0, r: 0, neighbors: [] }, }); expect(isConnected(emptyGraph)).toBe(true); expect(isConnected(singleNodeGraph)).toBe(true); }); });