import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' // Mock dell'I/O su disco: i test non toccano il filesystem reale né dipendono // dal path relativo a src/. vi.mock('fs', () => ({ readFileSync: vi.fn(), writeFileSync: vi.fn(), mkdirSync: vi.fn(), existsSync: vi.fn(), })) import * as fs from 'fs' import { loadState, saveState } from '../../src/persist.js' import { createInitialState } from '../../src/gameState.js' describe('Persistenza stato (persist.js)', () => { beforeEach(() => { vi.clearAllMocks() }) afterEach(() => { vi.restoreAllMocks() }) describe('saveState', () => { it('crea la directory e scrive lo stato serializzato', () => { const state = createInitialState() saveState(state) expect(fs.mkdirSync).toHaveBeenCalledWith(expect.any(String), { recursive: true }) expect(fs.writeFileSync).toHaveBeenCalled() const [, contenuto, encoding] = fs.writeFileSync.mock.calls[0] expect(JSON.parse(contenuto)).toEqual(state) expect(encoding).toBe('utf8') }) it('non lancia eccezioni se la scrittura fallisce', () => { fs.mkdirSync.mockImplementation(() => { throw new Error('EACCES') }) const errSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) expect(() => saveState(createInitialState())).not.toThrow() expect(errSpy).toHaveBeenCalled() }) }) describe('loadState', () => { it('legge e fa il parse di un file valido', () => { const salvato = createInitialState() salvato.sp.nomi.home = 'Squadra X' fs.existsSync.mockReturnValue(true) fs.readFileSync.mockReturnValue(JSON.stringify(salvato)) expect(loadState()).toEqual(salvato) }) it('ritorna lo stato iniziale se il file non esiste', () => { fs.existsSync.mockReturnValue(false) expect(loadState()).toEqual(createInitialState()) }) it('ritorna lo stato iniziale se il JSON è corrotto', () => { fs.existsSync.mockReturnValue(true) fs.readFileSync.mockReturnValue('{ questo non è json') const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}) expect(loadState()).toEqual(createInitialState()) expect(warnSpy).toHaveBeenCalled() }) }) })