Implement the 021-bestiary-statblock feature that adds a searchable D&D 2024 Monster Manual creature library with inline autocomplete suggestions, full stat block display in a fixed side panel, auto-numbering of duplicate creature names, HP/AC pre-fill from bestiary data, and automatic stat block display on turn change for wide viewports

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Lukas
2026-03-09 11:01:07 +01:00
parent 04a4f18f98
commit fa078be2f9
30 changed files with 66221 additions and 56 deletions

View File

@@ -0,0 +1,49 @@
import { describe, expect, it } from "vitest";
import { resolveCreatureName } from "../auto-number.js";
describe("resolveCreatureName", () => {
it("returns name as-is when no conflict exists", () => {
const result = resolveCreatureName("Goblin", ["Orc", "Dragon"]);
expect(result).toEqual({ newName: "Goblin", renames: [] });
});
it("returns name as-is when existing list is empty", () => {
const result = resolveCreatureName("Goblin", []);
expect(result).toEqual({ newName: "Goblin", renames: [] });
});
it("renames existing to 'Name 1' and new to 'Name 2' on first conflict", () => {
const result = resolveCreatureName("Goblin", ["Orc", "Goblin", "Dragon"]);
expect(result).toEqual({
newName: "Goblin 2",
renames: [{ from: "Goblin", to: "Goblin 1" }],
});
});
it("appends next number when numbered variants already exist", () => {
const result = resolveCreatureName("Goblin", ["Goblin 1", "Goblin 2"]);
expect(result).toEqual({ newName: "Goblin 3", renames: [] });
});
it("handles mixed exact and numbered matches", () => {
const result = resolveCreatureName("Goblin", [
"Goblin",
"Goblin 1",
"Goblin 2",
]);
expect(result).toEqual({ newName: "Goblin 3", renames: [] });
});
it("handles names with special regex characters", () => {
const result = resolveCreatureName("Goblin (Boss)", ["Goblin (Boss)"]);
expect(result).toEqual({
newName: "Goblin (Boss) 2",
renames: [{ from: "Goblin (Boss)", to: "Goblin (Boss) 1" }],
});
});
it("does not match partial name overlaps", () => {
const result = resolveCreatureName("Goblin", ["Goblin Boss"]);
expect(result).toEqual({ newName: "Goblin", renames: [] });
});
});