@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
JavaScript
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);
});
});
});