Files
initiative/packages/domain/src/__tests__/toggle-condition.test.ts
Lukas 36768d3aa1 Upgrade Biome to 2.4.7 and enable 54 additional lint rules
Add rules covering bug prevention (noLeakedRender, noFloatingPromises,
noImportCycles, noReactForwardRef), security (noScriptUrl, noAlert),
performance (noAwaitInLoops, useTopLevelRegex), and code style
(noNestedTernary, useGlobalThis, useNullishCoalescing, useSortedClasses,
plus ~40 more). Fix all violations: extract top-level regex constants,
guard React && renders with boolean coercion, refactor nested ternaries,
replace window with globalThis, sort Tailwind classes, and introduce
expectDomainError test helper to eliminate conditional expects.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 14:25:09 +01:00

116 lines
3.4 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { ConditionId } from "../conditions.js";
import { CONDITION_DEFINITIONS } from "../conditions.js";
import { toggleCondition } from "../toggle-condition.js";
import type { Combatant, Encounter } from "../types.js";
import { combatantId, isDomainError } from "../types.js";
import { expectDomainError } from "./test-helpers.js";
function makeCombatant(
name: string,
conditions?: readonly ConditionId[],
): Combatant {
return conditions
? { id: combatantId(name), name, conditions }
: { id: combatantId(name), name };
}
function enc(combatants: Combatant[]): Encounter {
return { combatants, activeIndex: 0, roundNumber: 1 };
}
function success(encounter: Encounter, id: string, condition: ConditionId) {
const result = toggleCondition(encounter, combatantId(id), condition);
if (isDomainError(result)) {
throw new Error(`Expected success, got error: ${result.message}`);
}
return result;
}
describe("toggleCondition", () => {
it("adds a condition when not present", () => {
const e = enc([makeCombatant("A")]);
const { encounter, events } = success(e, "A", "blinded");
expect(encounter.combatants[0].conditions).toEqual(["blinded"]);
expect(events).toEqual([
{
type: "ConditionAdded",
combatantId: combatantId("A"),
condition: "blinded",
},
]);
});
it("removes a condition when already present", () => {
const e = enc([makeCombatant("A", ["blinded"])]);
const { encounter, events } = success(e, "A", "blinded");
expect(encounter.combatants[0].conditions).toBeUndefined();
expect(events).toEqual([
{
type: "ConditionRemoved",
combatantId: combatantId("A"),
condition: "blinded",
},
]);
});
it("maintains definition order when adding conditions", () => {
const e = enc([makeCombatant("A", ["poisoned"])]);
const { encounter } = success(e, "A", "blinded");
expect(encounter.combatants[0].conditions).toEqual(["blinded", "poisoned"]);
});
it("prevents duplicate conditions", () => {
const e = enc([makeCombatant("A", ["blinded"])]);
// Toggling blinded again removes it, not duplicates
const { encounter } = success(e, "A", "blinded");
expect(encounter.combatants[0].conditions).toBeUndefined();
});
it("rejects unknown condition", () => {
const e = enc([makeCombatant("A")]);
const result = toggleCondition(
e,
combatantId("A"),
"flying" as ConditionId,
);
expectDomainError(result, "unknown-condition");
});
it("returns error for nonexistent combatant", () => {
const e = enc([makeCombatant("A")]);
const result = toggleCondition(e, combatantId("missing"), "blinded");
expectDomainError(result, "combatant-not-found");
});
it("does not mutate input encounter", () => {
const e = enc([makeCombatant("A")]);
const original = JSON.parse(JSON.stringify(e));
toggleCondition(e, combatantId("A"), "blinded");
expect(e).toEqual(original);
});
it("normalizes empty array to undefined on removal", () => {
const e = enc([makeCombatant("A", ["charmed"])]);
const { encounter } = success(e, "A", "charmed");
expect(encounter.combatants[0].conditions).toBeUndefined();
});
it("preserves order across all conditions", () => {
const order = CONDITION_DEFINITIONS.map((d) => d.id);
// Add in reverse order
let e = enc([makeCombatant("A")]);
for (const cond of [...order].reverse()) {
const result = success(e, "A", cond);
e = result.encounter;
}
expect(e.combatants[0].conditions).toEqual(order);
});
});