✨Feature: implement dungeon state management with room expansion and exit handling
This commit is contained in:
87
src/rules/dungeon.test.ts
Normal file
87
src/rules/dungeon.test.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { sampleContentPack } from "@/data/sampleContentPack";
|
||||
|
||||
import {
|
||||
expandLevelFromExit,
|
||||
getUnresolvedExits,
|
||||
initializeDungeonLevel,
|
||||
} from "./dungeon";
|
||||
|
||||
function createSequenceRoller(values: number[]) {
|
||||
let index = 0;
|
||||
|
||||
return () => {
|
||||
const next = values[index];
|
||||
index += 1;
|
||||
return next;
|
||||
};
|
||||
}
|
||||
|
||||
describe("dungeon state", () => {
|
||||
it("initializes level 1 with a generated start room", () => {
|
||||
const levelState = initializeDungeonLevel({ content: sampleContentPack });
|
||||
|
||||
expect(levelState.level).toBe(1);
|
||||
expect(levelState.discoveredRoomOrder).toEqual(["room.level1.start"]);
|
||||
expect(levelState.rooms["room.level1.start"]?.roomClass).toBe("start");
|
||||
});
|
||||
|
||||
it("lists unresolved traversable exits in discovery order", () => {
|
||||
const levelState = initializeDungeonLevel({ content: sampleContentPack });
|
||||
|
||||
expect(getUnresolvedExits(levelState)).toEqual([
|
||||
expect.objectContaining({
|
||||
roomId: "room.level1.start",
|
||||
direction: "north",
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
it("expands the dungeon from a chosen exit and links both rooms", () => {
|
||||
const levelState = initializeDungeonLevel({ content: sampleContentPack });
|
||||
const result = expandLevelFromExit({
|
||||
content: sampleContentPack,
|
||||
levelState,
|
||||
fromRoomId: "room.level1.start",
|
||||
exitDirection: "north",
|
||||
roomTableCode: "L1SR",
|
||||
roller: createSequenceRoller([3, 3]),
|
||||
});
|
||||
|
||||
expect(result.createdRoom.position).toEqual({ x: 0, y: -1 });
|
||||
expect(result.levelState.discoveredRoomOrder).toEqual([
|
||||
"room.level1.start",
|
||||
"room.level1.small.002",
|
||||
]);
|
||||
expect(result.fromRoom.exits[0]?.leadsToRoomId).toBe("room.level1.small.002");
|
||||
expect(result.createdRoom.exits.some((exit) => exit.leadsToRoomId === "room.level1.start")).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects placement into an occupied coordinate", () => {
|
||||
const levelState = initializeDungeonLevel({ content: sampleContentPack });
|
||||
const expanded = expandLevelFromExit({
|
||||
content: sampleContentPack,
|
||||
levelState,
|
||||
fromRoomId: "room.level1.start",
|
||||
exitDirection: "north",
|
||||
roomTableCode: "L1SR",
|
||||
roomId: "room.level1.small.a",
|
||||
roller: createSequenceRoller([3, 3]),
|
||||
});
|
||||
|
||||
expect(() =>
|
||||
expandLevelFromExit({
|
||||
content: sampleContentPack,
|
||||
levelState: expanded.levelState,
|
||||
fromRoomId: "room.level1.start",
|
||||
exitDirection: "north",
|
||||
roomTableCode: "L1SR",
|
||||
roomId: "room.level1.small.b",
|
||||
roller: createSequenceRoller([4, 4]),
|
||||
}),
|
||||
).toThrow("already connected");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user