forked from phenom/healer-man
51 lines
2.0 KiB
TypeScript
51 lines
2.0 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
dungeonWorldObjectState,
|
|
nearestDungeonWorldInteraction,
|
|
validateDungeonWorldObject,
|
|
type DungeonWorldObjectDefinition,
|
|
} from "./dungeonWorldObjects";
|
|
|
|
const door: DungeonWorldObjectDefinition = {
|
|
id: "test-door",
|
|
name: "Test Door",
|
|
kind: "door",
|
|
position: [3, 0, 0],
|
|
halfExtents: [1, 2, 0.25],
|
|
initialState: "closed",
|
|
states: [
|
|
{ id: "closed", label: "Closed", visible: true, blocksMovement: true, interactionEnabled: true },
|
|
{ id: "open", label: "Open", visible: false, blocksMovement: false, interactionEnabled: false },
|
|
],
|
|
interaction: {
|
|
prompt: "Open door",
|
|
range: 4,
|
|
signalId: "open-test-door",
|
|
allowedStates: ["closed"],
|
|
},
|
|
};
|
|
|
|
describe("dungeon world objects", () => {
|
|
it("resolves authored and fallback object states", () => {
|
|
expect(dungeonWorldObjectState(door, "open").blocksMovement).toBe(false);
|
|
expect(dungeonWorldObjectState(door, "missing").id).toBe("closed");
|
|
});
|
|
|
|
it("selects the nearest enabled visible interaction in range and line of sight", () => {
|
|
const farther = { ...door, id: "far-door", position: [3.5, 0, 0] as const };
|
|
expect(nearestDungeonWorldInteraction([farther, door], {}, [0, 0, 0])?.object.id).toBe("test-door");
|
|
expect(nearestDungeonWorldInteraction([door], { "test-door": "open" }, [0, 0, 0])).toBeNull();
|
|
expect(nearestDungeonWorldInteraction([door], {}, [0, 0, 0], () => false)).toBeNull();
|
|
});
|
|
|
|
it("rejects malformed geometry, state, and interaction contracts", () => {
|
|
expect(() => validateDungeonWorldObject(door)).not.toThrow();
|
|
expect(() => validateDungeonWorldObject({ ...door, halfExtents: [0, 2, 1] })).toThrow("invalid geometry");
|
|
expect(() => validateDungeonWorldObject({ ...door, initialState: "missing" })).toThrow("does not define");
|
|
expect(() => validateDungeonWorldObject({
|
|
...door,
|
|
interaction: { ...door.interaction!, range: 0 },
|
|
})).toThrow("invalid interaction");
|
|
});
|
|
});
|