Files

63 lines
2.5 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { deserialize, loadGame, saveGame, SaveStorage, serialize } from '../../src/sim/save';
import { createNewGame } from '../../src/sim/state';
import { issueCard } from '../../src/sim/loyalty';
import { STARTING_CASH_CENTS } from '../../src/sim/economy';
function memoryStorage(): SaveStorage {
const data = new Map<string, string>();
return { getItem: (k) => data.get(k) ?? null, setItem: (k, v) => void data.set(k, v) };
}
describe('save', () => {
it('round-trips the full state', () => {
const s = createNewGame(7);
issueCard(s.loyalty);
s.prices['tetris|new'] = 2500;
expect(deserialize(serialize(s))).toEqual(s);
});
it('rejects unknown save versions', () => {
const s = { ...createNewGame(1), saveVersion: 99 };
expect(() => deserialize(JSON.stringify(s))).toThrow('Unsupported save version: 99');
});
it('rejects malformed saves', () => {
expect(() => deserialize('{"saveVersion":1}')).toThrow('Corrupted save');
});
it('rejects invalid JSON and non-object saves', () => {
expect(() => deserialize('{not json')).toThrow('Corrupted save');
expect(() => deserialize('null')).toThrow('Corrupted save');
expect(() => deserialize('[]')).toThrow('Corrupted save');
expect(() => deserialize('42')).toThrow('Corrupted save');
});
it('rejects saves with a missing field', () => {
const { day: _day, ...rest } = createNewGame(1);
expect(() => deserialize(JSON.stringify(rest))).toThrow('Corrupted save');
});
it('rejects saves missing bankruptcy fields', () => {
const { negativeMonthEnds: _n, ...noMonths } = createNewGame(1);
expect(() => deserialize(JSON.stringify(noMonths))).toThrow('Corrupted save');
const { bankrupt: _b, ...noBankrupt } = createNewGame(1);
expect(() => deserialize(JSON.stringify(noBankrupt))).toThrow('Corrupted save');
expect(() => deserialize(JSON.stringify({ ...createNewGame(1), bankrupt: 'no' }))).toThrow('Corrupted save');
});
it('keeps the current and monthly saves apart', () => {
const storage = memoryStorage();
const s = createNewGame(1);
saveGame(storage, s, { monthly: true });
s.cash = 1;
saveGame(storage, s, { monthly: false });
expect(loadGame(storage, 'current')!.cash).toBe(1);
expect(loadGame(storage, 'monthly')!.cash).toBe(STARTING_CASH_CENTS);
});
it('returns null when nothing is saved', () => {
expect(loadGame(memoryStorage(), 'current')).toBeNull();
});
});