UNPKG

mnemos-coder

Version:

CLI-based coding agent with graph-based execution loop and terminal UI

181 lines (162 loc) 5.28 kB
/** * Test-First Verification System * Based on qwen-code's emphasis on self-verification through tests * Ensures code changes are validated before completion */ export class TestFirstVerification { /** * Determine verification strategy based on project type */ static async determineStrategy(projectRoot) { const strategy = { writeTestsFirst: false, runExistingTests: true, useDebugStatements: false, verificationCommands: [] }; // Check for test frameworks and commands const patterns = { node: { files: ['package.json'], testCommands: ['npm test', 'npm run test', 'yarn test'], lintCommands: ['npm run lint', 'yarn lint'], typeCommands: ['npm run typecheck', 'tsc --noEmit'] }, python: { files: ['requirements.txt', 'setup.py', 'pyproject.toml'], testCommands: ['pytest', 'python -m pytest', 'python -m unittest'], lintCommands: ['ruff check', 'flake8', 'pylint'], typeCommands: ['mypy'] }, rust: { files: ['Cargo.toml'], testCommands: ['cargo test'], lintCommands: ['cargo clippy'], typeCommands: ['cargo check'] }, go: { files: ['go.mod'], testCommands: ['go test ./...'], lintCommands: ['golangci-lint run'], typeCommands: ['go build'] } }; // Detect project type and add appropriate commands for (const [lang, config] of Object.entries(patterns)) { const hasProjectFile = await this.checkFilesExist(projectRoot, config.files); if (hasProjectFile) { strategy.verificationCommands.push(...config.testCommands); strategy.verificationCommands.push(...config.lintCommands); strategy.verificationCommands.push(...config.typeCommands); break; } } return strategy; } /** * Generate test template based on the code being modified */ static generateTestTemplate(functionName, language, testFramework) { const templates = { javascript: (fn) => ` describe('${fn}', () => { it('should handle normal cases', () => { // Arrange const input = {}; // Act const result = ${fn}(input); // Assert expect(result).toBeDefined(); }); it('should handle edge cases', () => { // Test null/undefined inputs expect(() => ${fn}(null)).not.toThrow(); }); it('should handle error cases', () => { // Test invalid inputs const invalidInput = {}; expect(() => ${fn}(invalidInput)).toThrow(); }); });`, python: (fn) => ` import pytest from module import ${fn} class Test${fn.charAt(0).toUpperCase() + fn.slice(1)}: def test_normal_case(self): """Test normal operation""" # Arrange input_data = {} # Act result = ${fn}(input_data) # Assert assert result is not None def test_edge_case(self): """Test edge cases""" # Test with None with pytest.raises(TypeError): ${fn}(None) def test_error_case(self): """Test error handling""" invalid_input = {} with pytest.raises(ValueError): ${fn}(invalid_input) `, typescript: (fn) => ` describe('${fn}', () => { it('should handle normal cases', () => { // Arrange const input = {} as InputType; // Act const result = ${fn}(input); // Assert expect(result).toBeDefined(); expect(result).toMatchObject({}); }); it('should handle edge cases', () => { // Test null/undefined inputs expect(() => ${fn}(null as any)).not.toThrow(); }); it('should handle error cases', () => { // Test invalid inputs const invalidInput = {} as InputType; expect(() => ${fn}(invalidInput)).toThrow(Error); }); });` }; return templates[language]?.(functionName) || '// Test template not available for this language'; } /** * Create verification loop for code changes */ static createVerificationLoop() { return ` ## Verification Loop Process 1. **Write Test First** - Define expected behavior - Create test cases for success, edge, and error cases 2. **Implement Solution** - Write minimal code to pass tests - Focus on correctness first 3. **Run Tests** - Execute test suite - Verify all tests pass 4. **Add Debug Output** - Insert console.log/print statements - Verify logic flow 5. **Run Linting & Type Checking** - Execute project linters - Run type checkers - Fix any issues 6. **Clean Up** - Remove debug statements - Refactor if needed - Ensure tests still pass `; } static async checkFilesExist(projectRoot, files) { // This would use fs.existsSync in real implementation // Simplified for demonstration return true; } } //# sourceMappingURL=TestFirstVerification.js.map