Files
ttrpg-initiative-tracker/shared/tests/_helpers.js
T

74 lines
2.5 KiB
JavaScript
Raw Normal View History

// Test helper: in-memory mock storage. Records all writes (addDoc/updateDoc).
// Captures encounter patches + log entries so tests assert persistence.
function createMockStorage() {
const docs = new Map(); // path -> data
const calls = []; // ordered {fn, path, data}
return {
calls,
docs,
async getDoc(path) { return docs.has(path) ? { ...docs.get(path) } : null; },
async setDoc(path, data) {
calls.push({ fn: 'setDoc', path, data });
docs.set(path, { ...data });
},
async addDoc(path, data) {
calls.push({ fn: 'addDoc', path, data });
},
async updateDoc(path, patch) {
calls.push({ fn: 'updateDoc', path, data: patch });
if (!docs.has(path)) docs.set(path, {});
docs.set(path, { ...docs.get(path), ...patch });
},
async deleteDoc(path) {
calls.push({ fn: 'deleteDoc', path });
docs.delete(path);
},
async getCollection() { return []; },
async batchWrite(ops) {
for (const op of ops) {
if (op.type === 'delete') await this.deleteDoc(op.path);
else await this.updateDoc(op.path, op.data);
}
},
async undo() {},
// filters
updatesFor(prefix) { return calls.filter(c => c.fn === 'updateDoc' && c.path.startsWith(prefix)); },
logs() { return calls.filter(c => c.fn === 'addDoc').map(c => c.data); },
getLogs() { return calls.filter(c => c.fn === 'addDoc').map(c => c.data); },
};
}
// Standard ctx for tests. encPath + logPath + displayPath preset.
// Returns { storage, ctx } so tests destructure both in one call:
// const { storage, ctx } = mockCtx();
function mockCtx(storage) {
storage = storage || createMockStorage();
const ctx = {
storage,
encPath: 'encounters/e1',
logPath: 'logs',
displayPath: 'activeDisplay/status',
};
return { storage, ctx };
}
// Standard 2-participant ready encounter.
function readyEnc(opts = {}) {
return {
id: 'e1',
name: opts.name || 'TestEnc',
round: 0,
isStarted: false,
isPaused: false,
currentTurnParticipantId: null,
turnOrderIds: [],
participants: opts.participants || [
{ id: 'p1', name: 'Bob', type: 'character', initiative: 10, maxHp: 10, currentHp: 10, isActive: true, conditions: [], status: 'conscious', deathSaveSuccesses: 0, deathSaveFailures: 0 },
{ id: 'p2', name: 'Mob', type: 'monster', initiative: 5, maxHp: 10, currentHp: 10, isActive: true, conditions: [], status: 'conscious', deathSaveSuccesses: 0, deathSaveFailures: 0 },
],
};
}
module.exports = { createMockStorage, mockCtx, readyEnc };