62 lines
2.2 KiB
TypeScript
62 lines
2.2 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { buildContent } from '../../content/schema';
|
|
import { createGameState, startAction } from '../../engine/game';
|
|
import { createSave, serializeSave } from '../../engine/save';
|
|
import { createMemoryBackend, loadGame, saveGame } from '../persistence';
|
|
|
|
function testContent() {
|
|
return buildContent({
|
|
resources: [{ id: 'gold', name: 'Gold', startAmount: 0 }],
|
|
actions: [
|
|
{ id: 'forage', name: 'Forage', durationMs: 3000, yields: [{ resourceId: 'gold', amount: 1 }] },
|
|
],
|
|
});
|
|
}
|
|
|
|
describe('loadGame()', () => {
|
|
it('returns a fresh game when no save exists', async () => {
|
|
const content = testContent();
|
|
const result = await loadGame(content, createMemoryBackend(), 1000);
|
|
expect(result.state.resources.gold).toBe(0);
|
|
expect(result.offlineMs).toBe(0);
|
|
});
|
|
|
|
it('round-trips a saved game and credits offline progress', async () => {
|
|
const content = testContent();
|
|
const state = createGameState(content);
|
|
state.resources.gold = 10;
|
|
startAction(state, content, 'forage');
|
|
const backend = createMemoryBackend();
|
|
await saveGame(state, backend, 1000);
|
|
|
|
const result = await loadGame(content, backend, 1000 + 9000); // 9s offline
|
|
expect(result.offlineMs).toBe(9000);
|
|
expect(result.state.resources.gold).toBe(11); // 10 + one completion
|
|
expect(result.state.activeActionId).toBeNull();
|
|
});
|
|
|
|
it('falls back to a fresh game on a corrupt save instead of throwing', async () => {
|
|
const content = testContent();
|
|
const result = await loadGame(content, createMemoryBackend('@@@garbage@@@'), 1000);
|
|
expect(result.state.resources.gold).toBe(0);
|
|
expect(result.offlineMs).toBe(0);
|
|
});
|
|
|
|
it('drops an active action that no longer exists in content', async () => {
|
|
const content = testContent();
|
|
const stale = serializeSave(
|
|
createSave(
|
|
{
|
|
resources: { gold: 1 },
|
|
activeActionId: 'ghost-action',
|
|
actionElapsedMs: 0,
|
|
actionQueue: [],
|
|
},
|
|
1000,
|
|
),
|
|
);
|
|
const result = await loadGame(content, createMemoryBackend(stale), 1000);
|
|
expect(result.state.activeActionId).toBeNull();
|
|
});
|
|
});
|