UNPKG

@iservu-inc/adf-cli

Version:

CLI tool for AgentDevFramework - AI-assisted development framework with multi-provider AI support

185 lines (146 loc) 6.51 kB
const fs = require('fs-extra'); const path = require('path'); const storage = require('../lib/learning/storage'); describe('Learning Storage', () => { const tempDir = path.join(__dirname, 'temp-learning-test'); beforeEach(async () => { await fs.ensureDir(tempDir); }); afterEach(async () => { await fs.remove(tempDir); }); describe('ensureLearningDirectory', () => { test('should create learning directory if it does not exist', async () => { await storage.ensureLearningDirectory(tempDir); const learningPath = path.join(tempDir, '.adf', 'learning'); const exists = await fs.pathExists(learningPath); expect(exists).toBe(true); }); }); describe('writeLearningData and readLearningData', () => { test('should write and read learning data', async () => { const data = { version: '1.0', sessions: [ { sessionId: 'test-1', skips: [] } ] }; await storage.writeLearningData(tempDir, 'test-data.json', data); const retrieved = await storage.readLearningData(tempDir, 'test-data.json'); expect(retrieved).toEqual(data); }); test('should return null for non-existent file', async () => { const retrieved = await storage.readLearningData(tempDir, 'non-existent.json'); expect(retrieved).toBeNull(); }); test('should handle corrupted JSON gracefully', async () => { const learningPath = path.join(tempDir, '.adf', 'learning'); await fs.ensureDir(learningPath); await fs.writeFile(path.join(learningPath, 'corrupted.json'), 'invalid json {]'); const retrieved = await storage.readLearningData(tempDir, 'corrupted.json'); expect(retrieved).toBeNull(); }); }); describe('appendToLearningHistory', () => { test('should append to existing history', async () => { const initial = { version: '1.0', sessions: [{ sessionId: 'session-1' }] }; await storage.writeLearningData(tempDir, 'history.json', initial); await storage.appendToLearningHistory(tempDir, 'history.json', { sessionId: 'session-2' }, 'sessions'); const retrieved = await storage.readLearningData(tempDir, 'history.json'); expect(retrieved.sessions.length).toBe(2); expect(retrieved.sessions[1].sessionId).toBe('session-2'); }); test('should create new file if it does not exist', async () => { await storage.appendToLearningHistory(tempDir, 'new-history.json', { sessionId: 'session-1' }, 'sessions'); const retrieved = await storage.readLearningData(tempDir, 'new-history.json'); expect(retrieved.sessions.length).toBe(1); expect(retrieved.sessions[0].sessionId).toBe('session-1'); }); }); describe('getSkipHistory', () => { test('should return empty history if file does not exist', async () => { const history = await storage.getSkipHistory(tempDir); expect(history).toEqual({ version: '1.0', sessions: [] }); }); test('should return existing skip history', async () => { const data = { version: '1.0', sessions: [ { sessionId: 'test', skips: [{ questionId: 'q1' }] } ] }; await storage.writeLearningData(tempDir, 'skip-history.json', data); const history = await storage.getSkipHistory(tempDir); expect(history.sessions.length).toBe(1); expect(history.sessions[0].skips.length).toBe(1); }); }); describe('getLearningConfig', () => { test('should return default config if file does not exist', async () => { const config = await storage.getLearningConfig(tempDir); expect(config.enabled).toBe(true); expect(config.trackSkips).toBe(true); expect(config.minSessionsForPattern).toBe(3); expect(config.minConfidenceForAutoFilter).toBe(75); }); test('should return existing config', async () => { const customConfig = { version: '1.0', enabled: false, minSessionsForPattern: 5 }; await storage.writeLearningData(tempDir, 'config.json', customConfig); const config = await storage.getLearningConfig(tempDir); expect(config.enabled).toBe(false); expect(config.minSessionsForPattern).toBe(5); }); }); describe('clearLearningData', () => { test('should remove all JSON files from learning directory', async () => { await storage.writeLearningData(tempDir, 'file1.json', { test: 1 }); await storage.writeLearningData(tempDir, 'file2.json', { test: 2 }); await storage.clearLearningData(tempDir); const file1 = await storage.readLearningData(tempDir, 'file1.json'); const file2 = await storage.readLearningData(tempDir, 'file2.json'); expect(file1).toBeNull(); expect(file2).toBeNull(); }); test('should not fail if learning directory does not exist', async () => { await expect(storage.clearLearningData(tempDir)).resolves.not.toThrow(); }); }); describe('getLearningDataSize', () => { test('should return 0 if no learning data exists', async () => { const size = await storage.getLearningDataSize(tempDir); expect(size).toBe(0); }); test('should return total size of all JSON files', async () => { await storage.writeLearningData(tempDir, 'file1.json', { test: 'data1' }); await storage.writeLearningData(tempDir, 'file2.json', { test: 'data2' }); const size = await storage.getLearningDataSize(tempDir); expect(size).toBeGreaterThan(0); }); }); describe('updateLearningStats', () => { test('should update statistics', async () => { await storage.updateLearningStats(tempDir, { totalSessions: 5, totalSkips: 20 }); const stats = await storage.getLearningStats(tempDir); expect(stats.totalSessions).toBe(5); expect(stats.totalSkips).toBe(20); expect(stats.lastUpdated).toBeTruthy(); }); test('should preserve existing stats when updating', async () => { await storage.updateLearningStats(tempDir, { totalSessions: 5 }); await storage.updateLearningStats(tempDir, { totalSkips: 20 }); const stats = await storage.getLearningStats(tempDir); expect(stats.totalSessions).toBe(5); expect(stats.totalSkips).toBe(20); }); }); });