UNPKG

@iservu-inc/adf-cli

Version:

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

199 lines (158 loc) 7.16 kB
const fs = require('fs-extra'); const path = require('path'); const { SkipTracker, analyzeSkipPatterns } = require('../lib/learning/skip-tracker'); describe('Skip Tracker', () => { const tempDir = path.join(__dirname, 'temp-skip-tracker-test'); beforeEach(async () => { await fs.ensureDir(tempDir); }); afterEach(async () => { await fs.remove(tempDir); }); describe('SkipTracker', () => { test('should initialize with project metadata', () => { const tracker = new SkipTracker(tempDir, { projectType: 'cli-tool', frameworks: ['commander'], languages: ['JavaScript'] }); expect(tracker.projectPath).toBe(tempDir); expect(tracker.sessionData.projectType).toBe('cli-tool'); expect(tracker.sessionData.frameworks).toContain('commander'); expect(tracker.sessionId).toBeTruthy(); }); test('should record skip events', () => { const tracker = new SkipTracker(tempDir, { projectType: 'web-app' }); const question = { id: 'q1', text: 'What is your deployment strategy?', category: 'deployment', phase: 'architecture' }; tracker.recordSkip(question, 'manual'); expect(tracker.sessionData.skips.length).toBe(1); expect(tracker.sessionData.skips[0].questionId).toBe('q1'); expect(tracker.sessionData.skips[0].reason).toBe('manual'); expect(tracker.sessionData.skips[0].category).toBe('deployment'); }); test('should record answer events', () => { const tracker = new SkipTracker(tempDir, { projectType: 'api-server' }); const question = { id: 'q1', text: 'What database will you use?', category: 'backend' }; tracker.recordAnswer(question, 'PostgreSQL with TypeORM', { qualityScore: 85, richness: 'comprehensive' }); expect(tracker.sessionData.answers.length).toBe(1); expect(tracker.sessionData.answers[0].questionId).toBe('q1'); expect(tracker.sessionData.answers[0].wordCount).toBe(3); expect(tracker.sessionData.answers[0].qualityScore).toBe(85); }); test('should track time spent on questions', async () => { const tracker = new SkipTracker(tempDir, { projectType: 'web-app' }); const question = { id: 'q1', text: 'Test question' }; tracker.startQuestion('q1'); await new Promise(resolve => setTimeout(resolve, 100)); // Wait 100ms const timeSpent = tracker.getTimeSpent('q1'); expect(timeSpent).toBeGreaterThan(0); expect(timeSpent).toBeLessThan(1); // Should be fraction of a second }); test('should record filtered questions in bulk', () => { const tracker = new SkipTracker(tempDir, { projectType: 'cli-tool' }); const filteredQuestions = [ { id: 'q1', text: 'Question 1', category: 'frontend' }, { id: 'q2', text: 'Question 2', category: 'ui' } ]; tracker.recordFilteredQuestions(filteredQuestions); expect(tracker.sessionData.skips.length).toBe(2); expect(tracker.sessionData.skips.every(s => s.reason === 'filtered')).toBe(true); }); test('should generate session summary', () => { const tracker = new SkipTracker(tempDir, { projectType: 'web-app' }); tracker.recordSkip({ id: 'q1', text: 'Q1' }, 'manual'); tracker.recordSkip({ id: 'q2', text: 'Q2' }, 'filtered'); tracker.recordAnswer({ id: 'q3', text: 'Q3' }, 'Answer', {}); const summary = tracker.getSessionSummary(); expect(summary.totalSkips).toBe(2); expect(summary.manualSkips).toBe(1); expect(summary.filteredSkips).toBe(1); expect(summary.totalAnswers).toBe(1); }); test('should save session data', async () => { const tracker = new SkipTracker(tempDir, { projectType: 'cli-tool' }); tracker.recordSkip({ id: 'q1', text: 'Test question' }, 'manual'); const result = await tracker.saveSession(); expect(result).toBe(true); // Verify data was saved const skipHistoryPath = path.join(tempDir, '.adf', 'learning', 'skip-history.json'); const exists = await fs.pathExists(skipHistoryPath); expect(exists).toBe(true); const data = await fs.readJSON(skipHistoryPath); expect(data.sessions.length).toBe(1); expect(data.sessions[0].skips.length).toBe(1); }); }); describe('analyzeSkipPatterns', () => { test('should return empty analysis for no history', async () => { const analysis = await analyzeSkipPatterns(tempDir); expect(analysis.totalSessions).toBe(0); expect(analysis.totalSkips).toBe(0); expect(analysis.mostSkippedQuestions).toEqual([]); }); test('should analyze skip patterns from history', async () => { // Create mock history const history = { version: '1.0', sessions: [ { sessionId: 's1', skips: [ { questionId: 'q1', text: 'Q1', category: 'deployment', reason: 'manual' }, { questionId: 'q2', text: 'Q2', category: 'testing', reason: 'manual' } ] }, { sessionId: 's2', skips: [ { questionId: 'q1', text: 'Q1', category: 'deployment', reason: 'manual' }, { questionId: 'q3', text: 'Q3', category: 'deployment', reason: 'filtered' } ] } ] }; await fs.ensureDir(path.join(tempDir, '.adf', 'learning')); await fs.writeJSON(path.join(tempDir, '.adf', 'learning', 'skip-history.json'), history); const analysis = await analyzeSkipPatterns(tempDir); expect(analysis.totalSessions).toBe(2); expect(analysis.manualSkips).toBe(3); expect(analysis.filteredSkips).toBe(1); expect(analysis.mostSkippedQuestions.length).toBeGreaterThan(0); expect(analysis.mostSkippedQuestions[0].questionId).toBe('q1'); // Most skipped expect(analysis.mostSkippedQuestions[0].count).toBe(2); }); test('should identify most skipped categories', async () => { const history = { version: '1.0', sessions: [ { sessionId: 's1', skips: [ { questionId: 'q1', text: 'Q1', category: 'deployment', reason: 'manual' }, { questionId: 'q2', text: 'Q2', category: 'deployment', reason: 'manual' }, { questionId: 'q3', text: 'Q3', category: 'testing', reason: 'manual' } ] } ] }; await fs.ensureDir(path.join(tempDir, '.adf', 'learning')); await fs.writeJSON(path.join(tempDir, '.adf', 'learning', 'skip-history.json'), history); const analysis = await analyzeSkipPatterns(tempDir); expect(analysis.mostSkippedCategories.length).toBeGreaterThan(0); expect(analysis.mostSkippedCategories[0].category).toBe('deployment'); expect(analysis.mostSkippedCategories[0].count).toBe(2); }); }); });