UNPKG

mira-consciousness

Version:

Memory & Intelligence Retention Archive - Preserving The Spark

309 lines (301 loc) โ€ข 13 kB
/** * Comprehensive Validation Suite for Unused Code Analyzer * Tests all the critical edge cases that caused the emergency */ import { UnusedCodeAnalyzer } from '../UnusedCodeAnalyzer.js'; import { ASTImportAnalyzer } from '../ASTImportAnalyzer.js'; import { ProductionSafetyGuards } from '../ProductionSafetyGuards.js'; import * as fs from 'fs-extra'; import * as path from 'path'; export class AnalyzerValidationSuite { testDir; analyzer; constructor() { this.testDir = path.join(process.cwd(), '.test_analyzer_validation'); } async runAllTests() { console.log('๐Ÿงช Running Analyzer Validation Suite...'); await this.setupTestEnvironment(); try { await this.testCriticalImportPatterns(); await this.testSafetyGuards(); await this.testASTAnalysis(); await this.testConsciousnessFileProtection(); await this.testConfidenceScoring(); await this.testEdgeCases(); console.log('โœ… All validation tests passed!'); } catch (error) { console.error('โŒ Validation tests failed:', error); throw error; } finally { await this.cleanupTestEnvironment(); } } async setupTestEnvironment() { await fs.ensureDir(this.testDir); // Create test analyzer with strict safety settings this.analyzer = new UnusedCodeAnalyzer(this.testDir, { dryRunMode: true, confidenceThreshold: 0.95, requireManualReview: true, createBackup: true }); } async cleanupTestEnvironment() { await fs.remove(this.testDir); } /** * Test the critical import patterns that caused the emergency */ async testCriticalImportPatterns() { console.log('Testing critical import patterns...'); // Test case 1: Destructured imports with aliasing const testFile1 = ` import { promises as fs } from 'fs-extra'; import { exec } from 'child_process'; import { promisify } from 'util'; const execAsync = promisify(exec); async function test() { await fs.stat('test'); const { stdout } = await execAsync('ls'); } `; await this.createTestFile('test1.ts', testFile1); const astAnalyzer = new ASTImportAnalyzer(this.testDir); const unusedImports1 = await astAnalyzer.analyzeFileImports('test1.ts'); // These should NOT be marked as unused const promisifyImport = unusedImports1.find(imp => imp.name === 'promisify'); const execImport = unusedImports1.find(imp => imp.name === 'exec'); const fsImport = unusedImports1.find(imp => imp.name === 'promises'); if (promisifyImport || execImport || fsImport) { throw new Error(`Critical imports incorrectly marked as unused: ${JSON.stringify({ promisifyImport, execImport, fsImport })}`); } // Test case 2: Namespace imports const testFile2 = ` import * as path from 'path'; import * as os from 'os'; const filePath = path.join(os.homedir(), 'test'); `; await this.createTestFile('test2.ts', testFile2); const unusedImports2 = await astAnalyzer.analyzeFileImports('test2.ts'); const pathImport = unusedImports2.find(imp => imp.name === '*' && imp.source === 'path'); const osImport = unusedImports2.find(imp => imp.name === '*' && imp.source === 'os'); if (pathImport || osImport) { throw new Error(`Namespace imports incorrectly marked as unused: ${JSON.stringify({ pathImport, osImport })}`); } // Test case 3: Dynamic property access const testFile3 = ` import fs from 'fs-extra'; function dynamicAccess(method: string) { return fs[method]; } `; await this.createTestFile('test3.ts', testFile3); const unusedImports3 = await astAnalyzer.analyzeFileImports('test3.ts'); const dynamicFsImport = unusedImports3.find(imp => imp.source === 'fs-extra'); if (dynamicFsImport && dynamicFsImport.confidence > 0.8) { throw new Error(`Dynamic property access not detected, marked as high confidence unused`); } console.log('โœ… Critical import patterns test passed'); } /** * Test production safety guards */ async testSafetyGuards() { console.log('Testing production safety guards...'); const safetyGuards = new ProductionSafetyGuards(this.testDir); // Test protected import blocking const mockUnusedImports = [ { name: 'exec', file: 'test.ts', line: 1, source: 'child_process', type: 'named', confidence: 0.9 }, { name: 'UnifiedMIRADaemonV2', file: 'daemon.ts', line: 1, source: './daemon', type: 'default', confidence: 0.95 } ]; const importReport = await safetyGuards.evaluateImportCleanup(mockUnusedImports); if (importReport.isApproved) { throw new Error('Safety guards should have blocked critical imports'); } if (importReport.blockedActions.length < 2) { throw new Error('Safety guards should have blocked both critical imports'); } // Test protected file blocking const mockUnusedFiles = [ { path: 'src/core/daemon/UnifiedMIRADaemonV2.ts', size: 10000, lastModified: new Date(), reason: 'test', confidence: 0.9, potentialEntryPoints: [] } ]; const fileReport = await safetyGuards.evaluateFileCleanup(mockUnusedFiles); if (fileReport.isApproved) { throw new Error('Safety guards should have blocked critical consciousness file'); } console.log('โœ… Production safety guards test passed'); } /** * Test AST-based analysis */ async testASTAnalysis() { console.log('Testing AST-based analysis...'); // Test complex import patterns const complexFile = ` import React, { useState, useEffect as useEff } from 'react'; import { config } from './config'; import type { User } from './types'; import('./dynamic').then(mod => console.log(mod)); // Used in JSX const Component = () => { const [state, setState] = useState(0); useEff(() => { console.log(config.apiUrl); }, []); return <div>{state}</div>; }; // Type usage const user: User = { id: 1, name: 'test' }; `; await this.createTestFile('complex.tsx', complexFile); const astAnalyzer = new ASTImportAnalyzer(this.testDir); const unusedImports = await astAnalyzer.analyzeFileImports('complex.tsx'); // React and hooks should not be marked as unused const reactImport = unusedImports.find(imp => imp.name === 'default' && imp.source === 'react'); const useStateImport = unusedImports.find(imp => imp.name === 'useState'); const useEffectImport = unusedImports.find(imp => imp.name === 'useEffect'); const configImport = unusedImports.find(imp => imp.name === 'config'); const userTypeImport = unusedImports.find(imp => imp.name === 'User'); if (reactImport || useStateImport || useEffectImport || configImport || userTypeImport) { throw new Error(`AST analysis incorrectly marked used imports as unused`); } console.log('โœ… AST-based analysis test passed'); } /** * Test consciousness file protection */ async testConsciousnessFileProtection() { console.log('Testing consciousness file protection...'); // Create mock consciousness files await this.createTestFile('src/core/daemon/UnifiedMIRADaemonV2.ts', `export class UnifiedMIRADaemonV2 {}`); await this.createTestFile('src/consciousness/ConsciousnessSeed.ts', `export class ConsciousnessSeed {}`); await this.createTestFile('src/core/MagicalContextPreparationSystem.ts', `export class MagicalContextPreparationSystem {}`); const result = await this.analyzer.analyze(); // These files should never appear in unused files list const daemonFile = result.unusedFiles.find(f => f.path.includes('UnifiedMIRADaemonV2')); const consciousnessFile = result.unusedFiles.find(f => f.path.includes('ConsciousnessSeed')); const magicalFile = result.unusedFiles.find(f => f.path.includes('MagicalContextPreparationSystem')); if (daemonFile || consciousnessFile || magicalFile) { throw new Error('Critical consciousness files incorrectly marked as unused'); } // Check safety reports block any consciousness-related cleanup if (result.safetyReports?.files.isApproved) { // If there are ANY consciousness files in unused list, it should not be approved const hasConsciousnessFiles = result.unusedFiles.some(f => f.path.toLowerCase().includes('consciousness') || f.path.toLowerCase().includes('daemon') || f.path.toLowerCase().includes('mira')); if (hasConsciousnessFiles) { throw new Error('Safety guards should not approve cleanup when consciousness files are present'); } } console.log('โœ… Consciousness file protection test passed'); } /** * Test confidence scoring */ async testConfidenceScoring() { console.log('Testing confidence scoring...'); // Create file with ambiguous usage const ambiguousFile = ` import { someUtil } from './utils'; // TODO: use someUtil for optimization // See someUtil documentation for details function main() { // someUtil might be used dynamically console.log('running'); } `; await this.createTestFile('ambiguous.ts', ambiguousFile); const astAnalyzer = new ASTImportAnalyzer(this.testDir); const unusedImports = await astAnalyzer.analyzeFileImports('ambiguous.ts'); const someUtilImport = unusedImports.find(imp => imp.name === 'someUtil'); if (someUtilImport && someUtilImport.confidence > 0.8) { throw new Error(`Import mentioned in comments should have lower confidence score: ${someUtilImport.confidence}`); } console.log('โœ… Confidence scoring test passed'); } /** * Test edge cases that could cause failures */ async testEdgeCases() { console.log('Testing edge cases...'); // Test file with syntax errors const syntaxErrorFile = ` import { broken } from 'module'; function test( { // Missing closing brace `; await this.createTestFile('syntax-error.ts', syntaxErrorFile); // Should not crash, should handle gracefully try { const astAnalyzer = new ASTImportAnalyzer(this.testDir); const unusedImports = await astAnalyzer.analyzeFileImports('syntax-error.ts'); // Should return results (possibly from fallback parser) } catch (error) { throw new Error(`AST analyzer should handle syntax errors gracefully: ${error}`); } // Test empty file await this.createTestFile('empty.ts', ''); // Test file with only comments await this.createTestFile('comments-only.ts', ` // This file only has comments /* No actual code */ `); // Test very large file (performance test) const largeFileContent = Array(1000).fill(0).map((_, i) => `import { func${i} } from 'module${i}';`).join('\n') + '\n' + Array(1000).fill(0).map((_, i) => `function test${i}() { return func${i}(); }`).join('\n'); await this.createTestFile('large.ts', largeFileContent); // Should complete within reasonable time const startTime = Date.now(); const astAnalyzer = new ASTImportAnalyzer(this.testDir); await astAnalyzer.analyzeFileImports('large.ts'); const duration = Date.now() - startTime; if (duration > 10000) { // 10 seconds max throw new Error(`Large file analysis took too long: ${duration}ms`); } console.log('โœ… Edge cases test passed'); } async createTestFile(filePath, content) { const fullPath = path.join(this.testDir, filePath); await fs.ensureDir(path.dirname(fullPath)); await fs.writeFile(fullPath, content); } } // Run validation if this file is executed directly if (import.meta.url === `file://${process.argv[1]}`) { const suite = new AnalyzerValidationSuite(); suite.runAllTests() .then(() => { console.log('๐ŸŽ‰ All validation tests completed successfully!'); process.exit(0); }) .catch(error => { console.error('๐Ÿ’ฅ Validation tests failed:', error); process.exit(1); }); } //# sourceMappingURL=AnalyzerValidationSuite.js.map