UNPKG

@iservu-inc/adf-cli

Version:

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

298 lines (243 loc) 9 kB
const { filterQuestions, scoreQuestionRelevance } = require('../lib/filters/question-filter'); const { PROJECT_TYPES } = require('../lib/analyzers/project-analyzer'); describe('Question Filter', () => { const sampleQuestions = [ { id: 'q1', text: 'What is the user interface design approach?', guidance: 'Describe your UI design', category: 'frontend', phase: 'design' }, { id: 'q2', text: 'What API endpoints will you need?', guidance: 'List your REST/GraphQL endpoints', category: 'api', phase: 'architecture' }, { id: 'q3', text: 'What command-line arguments will your CLI accept?', guidance: 'Define CLI interface', category: 'cli', phase: 'design' }, { id: 'q4', text: 'What database will you use?', guidance: 'Choose your database', category: 'backend', phase: 'architecture' } ]; describe('filterQuestions', () => { test('should skip UI questions for CLI tools', () => { const projectContext = { type: PROJECT_TYPES.CLI_TOOL, frameworks: [], languages: ['JavaScript/TypeScript'], confidence: 80 }; const result = filterQuestions(sampleQuestions, projectContext, { enableSmartFiltering: true, minRelevanceScore: 50 }); // UI question should be skipped const uiQuestion = result.questions.find(q => q.id === 'q1'); expect(uiQuestion).toBeUndefined(); // CLI question should be kept const cliQuestion = result.questions.find(q => q.id === 'q3'); expect(cliQuestion).toBeDefined(); expect(result.summary.skipped).toBeGreaterThan(0); }); test('should skip frontend questions for API servers', () => { const projectContext = { type: PROJECT_TYPES.API_SERVER, frameworks: ['Express'], languages: ['JavaScript/TypeScript'], confidence: 85 }; const result = filterQuestions(sampleQuestions, projectContext, { enableSmartFiltering: true, minRelevanceScore: 50 }); // UI question should be skipped const uiQuestion = result.questions.find(q => q.id === 'q1'); expect(uiQuestion).toBeUndefined(); // API question should be kept const apiQuestion = result.questions.find(q => q.id === 'q2'); expect(apiQuestion).toBeDefined(); }); test('should keep all questions when smart filtering disabled', () => { const projectContext = { type: PROJECT_TYPES.CLI_TOOL, frameworks: [], languages: ['JavaScript/TypeScript'], confidence: 80 }; const result = filterQuestions(sampleQuestions, projectContext, { enableSmartFiltering: false }); expect(result.questions.length).toBe(sampleQuestions.length); expect(result.summary.skipped).toBe(0); }); test('should estimate time saved correctly', () => { const projectContext = { type: PROJECT_TYPES.CLI_TOOL, frameworks: [], languages: ['JavaScript/TypeScript'], confidence: 80 }; const result = filterQuestions(sampleQuestions, projectContext, { enableSmartFiltering: true, minRelevanceScore: 50 }); expect(result.summary.timeSaved).toBeGreaterThan(0); // 2 minutes per skipped question expect(result.summary.timeSaved).toBe(result.summary.skipped * 2); }); }); describe('scoreQuestionRelevance', () => { test('should score UI question low for CLI projects', () => { const question = { text: 'What is your responsive design approach?', guidance: 'Describe mobile/desktop layouts' }; const projectContext = { type: PROJECT_TYPES.CLI_TOOL, frameworks: [], languages: ['JavaScript/TypeScript'] }; const relevance = scoreQuestionRelevance(question, projectContext); expect(relevance.score).toBeLessThan(70); expect(relevance.skipReason).toBeTruthy(); }); test('should score API question high for API servers', () => { const question = { text: 'What REST API endpoints will you need?', guidance: 'Define your API routes' }; const projectContext = { type: PROJECT_TYPES.API_SERVER, frameworks: ['Express'], languages: ['JavaScript/TypeScript'] }; const relevance = scoreQuestionRelevance(question, projectContext); expect(relevance.score).toBeGreaterThanOrEqual(50); }); test('should boost relevance for framework-specific questions', () => { const question = { text: 'How will you structure your React components?', guidance: 'Describe component architecture' }; const projectContext = { type: PROJECT_TYPES.WEB_APP, frameworks: ['React'], languages: ['JavaScript/TypeScript'] }; const relevance = scoreQuestionRelevance(question, projectContext); expect(relevance.score).toBeGreaterThan(80); }); test('should reduce relevance for competing framework questions', () => { const question = { text: 'How will you set up Angular modules?', guidance: 'Configure Angular app' }; const projectContext = { type: PROJECT_TYPES.WEB_APP, frameworks: ['React'], languages: ['JavaScript/TypeScript'] }; const relevance = scoreQuestionRelevance(question, projectContext); expect(relevance.score).toBeLessThanOrEqual(70); }); test('should handle projects with no framework gracefully', () => { const question = { text: 'What is your project goal?', guidance: 'Describe main objective' }; const projectContext = { type: PROJECT_TYPES.UNKNOWN, frameworks: [], languages: [] }; const relevance = scoreQuestionRelevance(question, projectContext); expect(relevance.score).toBeGreaterThanOrEqual(0); expect(relevance.score).toBeLessThanOrEqual(100); }); test('should provide helpful reasons for kept questions', () => { const question = { text: 'What CLI commands will you support?', guidance: 'Define command structure' }; const projectContext = { type: PROJECT_TYPES.CLI_TOOL, frameworks: [], languages: ['JavaScript/TypeScript'] }; const relevance = scoreQuestionRelevance(question, projectContext); expect(relevance.reason).toBeTruthy(); expect(relevance.reason.toLowerCase()).toContain('cli'); }); test('should provide helpful reasons for skipped questions', () => { const question = { text: 'What browser compatibility do you need?', guidance: 'List supported browsers' }; const projectContext = { type: PROJECT_TYPES.CLI_TOOL, frameworks: [], languages: ['JavaScript/TypeScript'] }; const relevance = scoreQuestionRelevance(question, projectContext); if (relevance.score < 50) { expect(relevance.skipReason).toBeTruthy(); } }); }); describe('Edge cases', () => { test('should handle empty question list', () => { const projectContext = { type: PROJECT_TYPES.WEB_APP, frameworks: ['React'], languages: ['JavaScript/TypeScript'], confidence: 80 }; const result = filterQuestions([], projectContext); expect(result.questions).toEqual([]); expect(result.summary.total).toBe(0); expect(result.summary.skipped).toBe(0); }); test('should handle unknown project type gracefully', () => { const projectContext = { type: PROJECT_TYPES.UNKNOWN, frameworks: [], languages: [], confidence: 20 }; const result = filterQuestions(sampleQuestions, projectContext, { enableSmartFiltering: true, minRelevanceScore: 50 }); // Should keep most questions when uncertain expect(result.questions.length).toBeGreaterThan(0); }); test('should handle missing category in question', () => { const questionWithoutCategory = { id: 'q5', text: 'General question', guidance: 'Answer this' }; const projectContext = { type: PROJECT_TYPES.WEB_APP, frameworks: [], languages: [], confidence: 80 }; const relevance = scoreQuestionRelevance(questionWithoutCategory, projectContext); expect(relevance.score).toBeGreaterThanOrEqual(0); expect(relevance.score).toBeLessThanOrEqual(100); }); }); });