import { describe, it, expect } from 'vitest';
import { SaveManager, type StorageLike } from '../saveManager';
/** Хранилище-заглушка (как localStorage, без DOM). */
function makeStorage(): StorageLike & { map: Map<string, string> } {
const map = new Map<string, string>();
return {
map,
getItem: (k) => map.get(k) ?? null,
setItem: (k, v) => void map.set(k, v),
removeItem: (k) => void map.delete(k),
key: (i) => [...map.keys()][i] ?? null,
get length() { return map.size; },
};
}
describe('SaveManager', () => {
it('сохраняет и загружает по слотам', () => {
const sm = new SaveManager(makeStorage());
expect(sm.has('a')).toBe(false);
sm.save('a', { pos: [1, 2, 3] });
expect(sm.has('a')).toBe(true);
expect(sm.load('a')).toEqual({ pos: [1, 2, 3] });
expect(sm.load('b')).toBeNull();
});
it('битый JSON → null', () => {
const storage = makeStorage();
const sm = new SaveManager(storage);
storage.setItem('save:x', '{oops');
expect(sm.load('x')).toBeNull();
});
it('listSlots и delete', () => {
const sm = new SaveManager(makeStorage());
sm.save('a', 1);
sm.save('b', 2);
expect(sm.listSlots()).toEqual(['a', 'b']);
sm.delete('a');
expect(sm.listSlots()).toEqual(['b']);
expect(sm.has('a')).toBe(false);
});
it('мета пишется в параллельный ключ и читается без сейва', () => {
const storage = makeStorage();
const sm = new SaveManager(storage);
sm.save('slot', { hp: 5 }, { title: 'Луга', savedAt: 123, version: 1 });
expect(storage.map.has('save:meta:slot')).toBe(true);
expect(sm.slotMeta('slot')).toEqual({ title: 'Луга', savedAt: 123, version: 1 });
// мета-ключи не попадают в список слотов
expect(sm.listSlots()).toEqual(['slot']);
});
it('сейв без меты и битая мета → slotMeta null, сейв читается', () => {
const storage = makeStorage();
const sm = new SaveManager(storage);
sm.save('old', 7);
expect(sm.slotMeta('old')).toBeNull();
storage.setItem('save:meta:bad', '{oops');
expect(sm.slotMeta('bad')).toBeNull();
storage.setItem('save:bad', '3');
expect(sm.load('bad')).toBe(3);
});
it('delete чистит и сейв, и мету; кастомный префикс', () => {
const sm = new SaveManager(makeStorage(), 'auto:');
sm.save('s', 1, { title: 'Т' });
expect(sm.listSlots()).toEqual(['s']);
sm.delete('s');
expect(sm.listSlots()).toEqual([]);
expect(sm.slotMeta('s')).toBeNull();
expect(sm.has('s')).toBe(false);
});
it('list возвращает слоты с метой', () => {
const sm = new SaveManager(makeStorage());
sm.save('a', 1, { title: 'А' });
sm.save('b', 2);
expect(sm.list()).toEqual([
{ slot: 'a', meta: { title: 'А' } },
{ slot: 'b', meta: null },
]);
});
});