Introduce adapter injection and migrate test suite
All checks were successful
CI / check (push) Successful in 2m13s
CI / build-image (push) Has been skipped

Replace direct adapter/persistence imports with context-based injection
(AdapterContext + useAdapters) so tests use in-memory implementations
instead of vi.mock. Migrate component tests from context mocking to
AllProviders with real hooks. Extract export/import logic from ActionBar
into useEncounterExportImport hook. Add bestiary-cache and
bestiary-index-adapter test suites. Raise adapter coverage thresholds
(68→80 lines, 56→62 branches).

77 test files, 891 tests, all passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Lukas
2026-04-01 23:55:45 +02:00
parent 228c1c667f
commit 2c643cc98b
42 changed files with 1879 additions and 1190 deletions

View File

@@ -37,14 +37,7 @@ import {
resolveCreatureName,
} from "@initiative/domain";
import { useCallback, useEffect, useReducer, useRef } from "react";
import {
loadEncounter,
saveEncounter,
} from "../persistence/encounter-storage.js";
import {
loadUndoRedoStacks,
saveUndoRedoStacks,
} from "../persistence/undo-redo-storage.js";
import { useAdapters } from "../contexts/adapter-context.js";
// -- Types --
@@ -111,11 +104,14 @@ function deriveNextId(encounter: Encounter): number {
return max;
}
function initializeState(): EncounterState {
const encounter = loadEncounter() ?? EMPTY_ENCOUNTER;
function initializeState(
loadEncounterFn: () => Encounter | null,
loadUndoRedoFn: () => UndoRedoState,
): EncounterState {
const encounter = loadEncounterFn() ?? EMPTY_ENCOUNTER;
return {
encounter,
undoRedoState: loadUndoRedoStacks(),
undoRedoState: loadUndoRedoFn(),
events: [],
nextId: deriveNextId(encounter),
lastCreatureId: null,
@@ -385,7 +381,10 @@ function dispatchEncounterAction(
// -- Hook --
export function useEncounter() {
const [state, dispatch] = useReducer(encounterReducer, null, initializeState);
const { encounterPersistence, undoRedoPersistence } = useAdapters();
const [state, dispatch] = useReducer(encounterReducer, null, () =>
initializeState(encounterPersistence.load, undoRedoPersistence.load),
);
const { encounter, undoRedoState, events } = state;
const encounterRef = useRef(encounter);
@@ -394,12 +393,12 @@ export function useEncounter() {
undoRedoRef.current = undoRedoState;
useEffect(() => {
saveEncounter(encounter);
}, [encounter]);
encounterPersistence.save(encounter);
}, [encounter, encounterPersistence]);
useEffect(() => {
saveUndoRedoStacks(undoRedoState);
}, [undoRedoState]);
undoRedoPersistence.save(undoRedoState);
}, [undoRedoState, undoRedoPersistence]);
// Escape hatches for useInitiativeRolls (needs raw port access)
const makeStore = useCallback((): EncounterStore => {