UNPKG

yoda-mcp

Version:

Intelligent Planning MCP with Optional Dependencies and Graceful Fallbacks - wise planning through the Force of lean excellence

283 lines (246 loc) 10.3 kB
/** * SmartTDDInjector Tests * * RED PHASE: Write failing tests that define expected behavior * These tests MUST fail initially - they define what we want to build */ import { SmartTDDInjector } from '../src/smart/smart-tdd-injector'; import { Task, Plan, TDDEnhancedPlan } from '../src/types'; describe('SmartTDDInjector', () => { let injector: SmartTDDInjector; beforeEach(() => { injector = new SmartTDDInjector(); }); // RED: This test MUST fail - SmartTDDInjector doesn't exist yet describe('Domain Detection', () => { test('should detect authentication domain from task content', () => { const task: Task = { id: 'auth_login', title: 'Implement user login functionality', description: 'Create secure user authentication with email and password', estimatedHours: 8, skills: ['backend', 'security'], dependencies: [], deliverable: 'Working login system' }; const domain = injector.detectDomain(task); expect(domain).toBe('auth'); }); test('should detect API domain from task content', () => { const task: Task = { id: 'api_endpoint', title: 'Create REST API endpoint for user data', description: 'Build API endpoint to handle user CRUD operations', estimatedHours: 6, skills: ['backend', 'api'], dependencies: [], deliverable: 'REST API endpoint' }; const domain = injector.detectDomain(task); expect(domain).toBe('api'); }); test('should detect UI domain from task content', () => { const task: Task = { id: 'ui_component', title: 'Build user profile component', description: 'Create React component for displaying user profile information', estimatedHours: 4, skills: ['frontend', 'react'], dependencies: [], deliverable: 'Profile component' }; const domain = injector.detectDomain(task); expect(domain).toBe('ui'); }); }); // RED: This test MUST fail - generateTestExample doesn't exist yet describe('Test Example Generation', () => { test('should generate working auth test example', () => { const task: Task = { id: 'auth_login', title: 'Implement user login', description: 'User authentication with email/password', estimatedHours: 8, skills: ['auth'], dependencies: [], deliverable: 'Login function' }; const testExample = injector.generateTestExample(task, 'auth'); // Test must be syntactically valid JavaScript/TypeScript expect(testExample).toContain('describe('); expect(testExample).toContain('test('); expect(testExample).toContain('expect('); // Must test authentication failure case (TDD best practice) expect(testExample).toContain('Invalid credentials'); // Must be specific to the task, not generic expect(testExample).toContain('authenticateUser'); }); test('should generate working API test example', () => { const task: Task = { id: 'api_users', title: 'Create users API endpoint', description: 'CRUD operations for user management', estimatedHours: 6, skills: ['api'], dependencies: [], deliverable: 'Users API' }; const testExample = injector.generateTestExample(task, 'api'); expect(testExample).toContain('describe('); expect(testExample).toContain('test('); expect(testExample).toContain('request(app)'); expect(testExample).toContain('400'); // Should test error cases first expect(testExample).toContain('required'); // Validation testing }); test('should generate working UI test example', () => { const task: Task = { id: 'ui_form', title: 'Build user registration form', description: 'Form component with validation', estimatedHours: 5, skills: ['ui', 'react'], dependencies: [], deliverable: 'Registration form' }; const testExample = injector.generateTestExample(task, 'ui'); expect(testExample).toContain('describe('); expect(testExample).toContain('test('); expect(testExample).toContain('render('); expect(testExample).toContain('fireEvent'); expect(testExample).toContain('screen.getByRole'); // Should test error states first (TDD best practice) expect(testExample).toContain('error'); }); }); // RED: This test MUST fail - injectTDD doesn't exist yet describe('TDD Workflow Creation', () => { test('should create complete TDD workflow for a task', () => { const task: Task = { id: 'feature_payment', title: 'Implement payment processing', description: 'Process credit card payments securely', estimatedHours: 12, skills: ['backend', 'payment'], dependencies: [], deliverable: 'Payment system' }; const tddTask = injector.createTDDWorkflow(task); // Must have all three TDD phases expect(tddTask.tddCycle.red).toBeDefined(); expect(tddTask.tddCycle.green).toBeDefined(); expect(tddTask.tddCycle.refactor).toBeDefined(); // Red phase must emphasize test-first approach expect(tddTask.tddCycle.red.description).toContain('failing test'); expect(tddTask.tddCycle.red.concreteExample).toContain('describe('); expect(tddTask.tddCycle.red.successCriteria).toContain('Test fails for right reason'); // Time estimates should sum to original estimate const totalTime = tddTask.tddCycle.red.estimatedTime + tddTask.tddCycle.green.estimatedTime + tddTask.tddCycle.refactor.estimatedTime; expect(totalTime).toBe(task.estimatedHours); // Green phase should be about minimal implementation expect(tddTask.tddCycle.green.description).toContain('minimal code'); expect(tddTask.tddCycle.green.successCriteria).toContain('Test passes'); // Refactor phase should focus on quality improvement expect(tddTask.tddCycle.refactor.description).toContain('quality'); expect(tddTask.tddCycle.refactor.successCriteria).toContain('All tests green'); }); }); // RED: This test MUST fail - injectTDD doesn't exist yet describe('Plan Enhancement', () => { test('should enhance plan with TDD methodology', () => { const originalPlan: Plan = { requirements: [ { id: 'req_1', description: 'User authentication system', priority: 'must-have', acceptanceCriteria: ['Users can log in', 'Passwords are secure'] } ], tasks: [ { id: 'task_auth', title: 'Build login system', description: 'Implement user authentication', estimatedHours: 8, skills: ['backend'], dependencies: [], deliverable: 'Login functionality' } ], timeline: { totalEstimate: '1 week', phases: [], criticalPath: ['task_auth'] }, risks: [], metadata: { planId: 'test_plan', generatedAt: new Date(), estimatedReadTime: '5 minutes', complexity: 'moderate' } }; const enhancedPlan: TDDEnhancedPlan = injector.injectTDD(originalPlan); // Must preserve original plan structure expect(enhancedPlan.requirements).toEqual(originalPlan.requirements); expect(enhancedPlan.timeline).toEqual(originalPlan.timeline); expect(enhancedPlan.risks).toEqual(originalPlan.risks); expect(enhancedPlan.metadata).toEqual(originalPlan.metadata); // Must add TDD enhancements expect(enhancedPlan.tddGuidance).toBeDefined(); expect(enhancedPlan.tddGuidance.enabled).toBe(true); expect(enhancedPlan.tddGuidance.redGreenRefactor).toBeDefined(); expect(enhancedPlan.tddGuidance.testingStrategy).toBeDefined(); expect(enhancedPlan.tddGuidance.testingStrategy.testCoverage).toBeGreaterThanOrEqual(90); // Tasks must be enhanced with TDD workflows expect(enhancedPlan.tasks).toHaveLength(originalPlan.tasks.length); enhancedPlan.tasks.forEach(task => { expect(task.tddCycle).toBeDefined(); expect(task.tddCycle.red).toBeDefined(); expect(task.tddCycle.green).toBeDefined(); expect(task.tddCycle.refactor).toBeDefined(); }); }); test('should only apply TDD to high-value tasks when optimized', () => { const planWithManyTasks: Plan = { requirements: [], tasks: [ { id: 'vital_task', title: 'Core payment processing', description: 'Critical payment functionality', estimatedHours: 16, skills: ['backend'], dependencies: [], deliverable: 'Payment system', businessValue: 95, // High value priority: 'vital' }, { id: 'trivial_task', title: 'Update footer text', description: 'Change copyright year', estimatedHours: 1, skills: ['frontend'], dependencies: [], deliverable: 'Updated footer', businessValue: 5, // Low value priority: 'trivial' } ], timeline: { totalEstimate: '3 weeks', phases: [], criticalPath: [] }, risks: [], metadata: { planId: 'multi_task', generatedAt: new Date(), estimatedReadTime: '10 minutes', complexity: 'moderate' } }; const vitalTasks = [planWithManyTasks.tasks[0]]; // Only high-value task const enhancedPlan = injector.injectTDD(planWithManyTasks, vitalTasks); // Only vital task should have TDD workflow const vitalTask = enhancedPlan.tasks.find(t => t.id === 'vital_task'); const trivialTask = enhancedPlan.tasks.find(t => t.id === 'trivial_task'); expect(vitalTask.tddCycle).toBeDefined(); expect(trivialTask.tddCycle).toBeUndefined(); // Should not have TDD overhead }); }); });