import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { mkdtempSync, rmSync, readFileSync, writeFileSync } from 'fs'; import { resolve } from 'path'; import { tmpdir } from 'os'; import { loadPreferences, savePreference } from './preferences.js'; describe('preferences', () => { let dataDir: string; beforeEach(() => { dataDir = mkdtempSync(resolve(tmpdir(), 'flynn-prefs-')); }); afterEach(() => { rmSync(dataDir, { recursive: true, force: true }); }); it('returns empty object when file is missing', () => { expect(loadPreferences(dataDir)).toEqual({}); }); it('returns empty object when file is corrupt', () => { writeFileSync(resolve(dataDir, 'preferences.json'), 'not json!!!'); expect(loadPreferences(dataDir)).toEqual({}); }); it('round-trips a saved preference', () => { savePreference(dataDir, 'modelTier', 'local'); const prefs = loadPreferences(dataDir); expect(prefs.modelTier).toBe('local'); }); it('round-trips backend mode preference', () => { savePreference(dataDir, 'backendMode', 'force_native'); const prefs = loadPreferences(dataDir); expect(prefs.backendMode).toBe('force_native'); }); it('merges preferences without overwriting other keys', () => { savePreference(dataDir, 'modelTier', 'fast'); savePreference(dataDir, 'otherKey', 42); const raw = JSON.parse(readFileSync(resolve(dataDir, 'preferences.json'), 'utf-8')); expect(raw.modelTier).toBe('fast'); expect(raw.otherKey).toBe(42); }); it('creates parent directories if needed', () => { const nested = resolve(dataDir, 'sub', 'dir'); savePreference(nested, 'modelTier', 'default'); expect(loadPreferences(nested).modelTier).toBe('default'); }); it('ignores invalid backendMode values in stored preferences', () => { writeFileSync( resolve(dataDir, 'preferences.json'), JSON.stringify({ modelTier: 'default', backendMode: 'invalid-mode' }), ); const prefs = loadPreferences(dataDir); expect(prefs.modelTier).toBe('default'); expect(prefs.backendMode).toBeUndefined(); }); });