import { afterEach, describe, expect, it } from "vitest"; import { combatHasLineOfSight, isPositionInFacingArc, isSourceBehindTarget, projectCombatGroundPoint, registerCombatSpatialProvider, resetCombatSpatialProvider, } from "./combatSpatial"; describe("renderer-independent combat spatial queries", () => { afterEach(resetCombatSpatialProvider); it("validates facing and behind arcs", () => { const actor = { id: "actor", position: [0, 0, 0] as const, yaw: 0 }; expect(isPositionInFacingArc(actor, [0, 0, 5])).toBe(true); expect(isPositionInFacingArc(actor, [0, 0, -5])).toBe(false); expect(isSourceBehindTarget([0, 0, -2], actor)).toBe(true); expect(isSourceBehindTarget([0, 0, 2], actor)).toBe(false); }); it("delegates line of sight and collision-safe ground projection", () => { registerCombatSpatialProvider({ actor: () => null, hasLineOfSight: (_source, target) => target[0] >= 0, projectGroundPoint: (requested) => requested[1] > 5 ? null : [requested[0], 0, requested[2]], }); expect(combatHasLineOfSight([0, 0, 0], [2, 0, 0])).toBe(true); expect(combatHasLineOfSight([0, 0, 0], [-2, 0, 0])).toBe(false); expect(projectCombatGroundPoint([2, 3, 4], 10)).toEqual([2, 0, 4]); expect(projectCombatGroundPoint([2, 8, 4], 10)).toBeNull(); }); });