Display Recall Knowledge line below trait tags showing DC (from level via standard DC-by-level table, adjusted for rarity) and associated skill derived from creature type trait. Omitted for D&D creatures and creatures with no recognized type trait. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
100 lines
3.0 KiB
TypeScript
100 lines
3.0 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { recallKnowledge } from "../recall-knowledge.js";
|
|
|
|
describe("recallKnowledge", () => {
|
|
it("returns null when no type trait is recognized", () => {
|
|
expect(recallKnowledge(5, ["small", "goblin"])).toBeNull();
|
|
});
|
|
|
|
it("calculates DC for a common creature from the DC-by-level table", () => {
|
|
const result = recallKnowledge(5, ["humanoid"]);
|
|
expect(result).toEqual({ dc: 20, type: "humanoid", skills: ["Society"] });
|
|
});
|
|
|
|
it("calculates DC for level -1", () => {
|
|
const result = recallKnowledge(-1, ["humanoid"]);
|
|
expect(result).toEqual({ dc: 13, type: "humanoid", skills: ["Society"] });
|
|
});
|
|
|
|
it("calculates DC for level 0", () => {
|
|
const result = recallKnowledge(0, ["animal"]);
|
|
expect(result).toEqual({ dc: 14, type: "animal", skills: ["Nature"] });
|
|
});
|
|
|
|
it("calculates DC for level 25 (max table entry)", () => {
|
|
const result = recallKnowledge(25, ["dragon"]);
|
|
expect(result).toEqual({ dc: 50, type: "dragon", skills: ["Arcana"] });
|
|
});
|
|
|
|
it("clamps DC for levels beyond the table", () => {
|
|
const result = recallKnowledge(30, ["dragon"]);
|
|
expect(result).toEqual({ dc: 50, type: "dragon", skills: ["Arcana"] });
|
|
});
|
|
|
|
it("adjusts DC for uncommon rarity (+2)", () => {
|
|
const result = recallKnowledge(5, ["uncommon", "medium", "undead"]);
|
|
expect(result).toEqual({
|
|
dc: 22,
|
|
type: "undead",
|
|
skills: ["Religion"],
|
|
});
|
|
});
|
|
|
|
it("adjusts DC for rare rarity (+5)", () => {
|
|
const result = recallKnowledge(5, ["rare", "large", "dragon"]);
|
|
expect(result).toEqual({ dc: 25, type: "dragon", skills: ["Arcana"] });
|
|
});
|
|
|
|
it("adjusts DC for unique rarity (+10)", () => {
|
|
const result = recallKnowledge(5, ["unique", "medium", "humanoid"]);
|
|
expect(result).toEqual({
|
|
dc: 30,
|
|
type: "humanoid",
|
|
skills: ["Society"],
|
|
});
|
|
});
|
|
|
|
it("returns multiple skills for beast type", () => {
|
|
const result = recallKnowledge(3, ["beast"]);
|
|
expect(result).toEqual({
|
|
dc: 18,
|
|
type: "beast",
|
|
skills: ["Arcana", "Nature"],
|
|
});
|
|
});
|
|
|
|
it("returns multiple skills for construct type", () => {
|
|
const result = recallKnowledge(1, ["construct"]);
|
|
expect(result).toEqual({
|
|
dc: 15,
|
|
type: "construct",
|
|
skills: ["Arcana", "Crafting"],
|
|
});
|
|
});
|
|
|
|
it("matches type traits case-insensitively", () => {
|
|
const result = recallKnowledge(5, ["Humanoid"]);
|
|
expect(result).toEqual({ dc: 20, type: "Humanoid", skills: ["Society"] });
|
|
});
|
|
|
|
it("uses the first matching type trait when multiple are present", () => {
|
|
const result = recallKnowledge(7, ["large", "monitor", "protean"]);
|
|
expect(result).toEqual({
|
|
dc: 23,
|
|
type: "monitor",
|
|
skills: ["Religion"],
|
|
});
|
|
});
|
|
|
|
it("preserves original trait casing in the returned type", () => {
|
|
const result = recallKnowledge(1, ["Fey"]);
|
|
expect(result?.type).toBe("Fey");
|
|
});
|
|
|
|
it("ignores common rarity (no adjustment)", () => {
|
|
// "common" is not included in traits by the normalization pipeline
|
|
const result = recallKnowledge(5, ["medium", "humanoid"]);
|
|
expect(result?.dc).toBe(20);
|
|
});
|
|
});
|