Add Pathfinder 2e game system mode
Implements PF2e as an alternative game system alongside D&D 5e/5.5e. Settings modal "Game System" selector switches conditions, bestiary, stat block layout, and initiative calculation between systems. - Valued conditions with increment/decrement UX (Clumsy 2, Frightened 3) - 2,502 PF2e creatures from bundled search index (77 sources) - PF2e stat block: level, traits, Perception, Fort/Ref/Will, ability mods - Perception-based initiative rolling - System-scoped source cache (D&D and PF2e sources don't collide) - Backwards-compatible condition rehydration (ConditionId[] → ConditionEntry[]) - Difficulty indicator hidden in PF2e mode (excluded from MVP) Closes dostulata/initiative#19 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
getAllPf2eSourceCodes,
|
||||
getDefaultPf2eFetchUrl,
|
||||
getPf2eSourceDisplayName,
|
||||
loadPf2eBestiaryIndex,
|
||||
} from "../pf2e-bestiary-index-adapter.js";
|
||||
|
||||
describe("loadPf2eBestiaryIndex", () => {
|
||||
it("returns an object with sources and creatures", () => {
|
||||
const index = loadPf2eBestiaryIndex();
|
||||
expect(index.sources).toBeDefined();
|
||||
expect(index.creatures).toBeDefined();
|
||||
expect(Array.isArray(index.creatures)).toBe(true);
|
||||
});
|
||||
|
||||
it("creatures have the expected PF2e shape", () => {
|
||||
const index = loadPf2eBestiaryIndex();
|
||||
expect(index.creatures.length).toBeGreaterThan(0);
|
||||
const first = index.creatures[0];
|
||||
expect(first).toHaveProperty("name");
|
||||
expect(first).toHaveProperty("source");
|
||||
expect(first).toHaveProperty("level");
|
||||
expect(first).toHaveProperty("ac");
|
||||
expect(first).toHaveProperty("hp");
|
||||
expect(first).toHaveProperty("perception");
|
||||
expect(first).toHaveProperty("size");
|
||||
expect(first).toHaveProperty("type");
|
||||
});
|
||||
|
||||
it("contains a substantial number of creatures", () => {
|
||||
const index = loadPf2eBestiaryIndex();
|
||||
expect(index.creatures.length).toBeGreaterThan(2000);
|
||||
});
|
||||
|
||||
it("returns the same cached instance on subsequent calls", () => {
|
||||
const a = loadPf2eBestiaryIndex();
|
||||
const b = loadPf2eBestiaryIndex();
|
||||
expect(a).toBe(b);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getAllPf2eSourceCodes", () => {
|
||||
it("returns all keys from the index sources", () => {
|
||||
const codes = getAllPf2eSourceCodes();
|
||||
const index = loadPf2eBestiaryIndex();
|
||||
expect(codes).toEqual(Object.keys(index.sources));
|
||||
});
|
||||
});
|
||||
|
||||
describe("getDefaultPf2eFetchUrl", () => {
|
||||
it("returns Pf2eTools GitHub URL with lowercase source code", () => {
|
||||
const url = getDefaultPf2eFetchUrl("B1");
|
||||
expect(url).toBe(
|
||||
"https://raw.githubusercontent.com/Pf2eToolsOrg/Pf2eTools/dev/data/bestiary/creatures-b1.json",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getPf2eSourceDisplayName", () => {
|
||||
it("returns display name for a known source", () => {
|
||||
expect(getPf2eSourceDisplayName("B1")).toBe("Bestiary");
|
||||
});
|
||||
|
||||
it("falls back to source code for unknown source", () => {
|
||||
expect(getPf2eSourceDisplayName("UNKNOWN")).toBe("UNKNOWN");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user