// Integration test runner for KidLisp V2 architecture validation // Runs all test suites and provides comprehensive validation import { testCacheManager } from './cache-manager.test.mjs'; import { testInstanceManager } from './instance-manager.test.mjs'; import { runPerformanceBenchmark, benchmarkRecursionDetection } from './performance-benchmark.mjs'; async function runIntegrationTests() { console.log('๐Ÿš€ KidLisp V2 Architecture Integration Tests\n'); console.log('=' .repeat(60)); const testResults = []; let totalTime = 0; // Test 1: Cache Manager console.log('\n๐Ÿงช Phase 1: Cache Manager Tests'); console.log('-' .repeat(40)); const cacheStart = Date.now(); const cacheSuccess = await testCacheManager(); const cacheTime = Date.now() - cacheStart; totalTime += cacheTime; testResults.push({ name: 'Cache Manager', success: cacheSuccess, time: cacheTime }); // Test 2: Instance Manager console.log('\n๐Ÿ—๏ธ Phase 2: Instance Manager Tests'); console.log('-' .repeat(40)); const instanceStart = Date.now(); const instanceSuccess = await testInstanceManager(); const instanceTime = Date.now() - instanceStart; totalTime += instanceTime; testResults.push({ name: 'Instance Manager', success: instanceSuccess, time: instanceTime }); // Test 3: Performance Benchmarks console.log('\nโšก Phase 3: Performance Benchmarks'); console.log('-' .repeat(40)); const perfStart = Date.now(); try { await runPerformanceBenchmark(); await benchmarkRecursionDetection(); const perfTime = Date.now() - perfStart; totalTime += perfTime; testResults.push({ name: 'Performance Benchmarks', success: true, time: perfTime }); } catch (error) { console.error('โŒ Performance benchmark failed:', error); testResults.push({ name: 'Performance Benchmarks', success: false, time: Date.now() - perfStart }); } // Test 4: End-to-End Integration console.log('\n๐Ÿ”„ Phase 4: End-to-End Integration'); console.log('-' .repeat(40)); const e2eStart = Date.now(); const e2eSuccess = await runEndToEndTest(); const e2eTime = Date.now() - e2eStart; totalTime += e2eTime; testResults.push({ name: 'End-to-End Integration', success: e2eSuccess, time: e2eTime }); // Generate comprehensive report console.log('\n๐Ÿ“Š Final Results Report'); console.log('=' .repeat(60)); const successCount = testResults.filter(r => r.success).length; const totalTests = testResults.length; console.log(`๐Ÿ“ˆ Test Summary: ${successCount}/${totalTests} test suites passed`); console.log(`โฑ๏ธ Total execution time: ${totalTime}ms`); console.log(); for (const result of testResults) { const status = result.success ? 'โœ…' : 'โŒ'; console.log(`${status} ${result.name}: ${result.time}ms`); } console.log(); if (successCount === totalTests) { console.log('๐ŸŽ‰ ALL TESTS PASSED!'); console.log('โœ… Architecture validation successful'); console.log('๐Ÿš€ Ready for implementation'); return true; } else { console.log('โŒ Some tests failed'); console.log('๐Ÿ”ง Architecture needs refinement'); return false; } } async function runEndToEndTest() { console.log('๐Ÿ”„ Running end-to-end integration scenario'); try { // Import our prototypes const { KidLispCacheManager } = await import('./cache-manager-prototype.mjs'); const { KidLispInstanceManager } = await import('./instance-manager-prototype.mjs'); const { mockStore } = await import('./mock-network.mjs'); // Set up the complete system const cacheManager = new KidLispCacheManager(); const instanceManager = new KidLispInstanceManager(cacheManager); console.log(' ๐Ÿ—๏ธ System initialized'); // Clear all state cacheManager.clearCache(); instanceManager.clearAllInstances(); mockStore.clearRequestLog(); // Scenario: User runs $cow piece which embeds $39i and $r2f console.log(' ๐Ÿ„ Executing $cow scenario...'); // 1. User types "cow" in AC prompt const mainInstance = instanceManager.createInstance({ type: 'main-piece', bounds: { x: 0, y: 0, width: 400, height: 400 }, cacheId: 'cow' }); // 2. System fetches $cow code const cowCode = await cacheManager.getCachedCode('cow'); console.log(' ๐Ÿ“ฅ Fetched $cow code'); // 3. System parses and finds embedded $39i and $r2f const embeddedCodes = cacheManager.extractDollarCodes(cowCode); console.log(` ๐Ÿ” Found embedded codes: ${embeddedCodes.join(', ')}`); // 4. System executes with embedded layer creation const result = await instanceManager.executeWithRecursionGuard( mainInstance.id, cowCode, {} ); console.log(' โšก Execution completed'); // 5. Verify results const networkStats = mockStore.getRequestStats(); const cacheStats = cacheManager.getCacheEfficiency(); const instanceStats = instanceManager.getStats(); console.log(' ๐Ÿ“Š Results verification:'); console.log(` Network requests: ${networkStats.total}`); console.log(` Cache hit rate: ${cacheStats.hitRate.toFixed(1)}%`); console.log(` Instances created: ${instanceStats.totalInstances}`); console.log(` Max depth reached: ${instanceStats.maxDepthReached}`); // Assertions for end-to-end validation const assertions = [ result.type === 'execution-result', result.embeddedCount === 2, networkStats.total <= 2, // Should be 1 for cow + 1 batch for embedded cacheStats.hitRate >= 0, instanceStats.totalInstances >= 3, // root + 2 embedded instanceStats.cyclesDetected === 0 ]; const passedAssertions = assertions.filter(Boolean).length; console.log(` โœ… Assertions: ${passedAssertions}/${assertions.length} passed`); // Test recursion scenario console.log(' ๐ŸŒ€ Testing recursion handling...'); const recursiveInstance = instanceManager.createInstance({ type: 'main-piece', cacheId: 'recursive-a' }); const recursiveResult = await instanceManager.executeWithRecursionGuard( recursiveInstance.id, '(paint ($recursive-b 0 0 100 100))', {} ); // This should work (A calls B) console.log(` ๐Ÿ”„ Recursive execution result: ${recursiveResult.type}`); // Test actual cycle instanceManager.recursionStack = ['recursive-a']; // Simulate being in A const cycleResult = await instanceManager.executeWithRecursionGuard( recursiveInstance.id, '(paint ($recursive-a 0 0 50 50))', // A calls A (cycle) {} ); console.log(` ๐Ÿ›ก๏ธ Cycle detection result: ${cycleResult.type}`); const finalStats = instanceManager.getStats(); console.log(` ๐Ÿ“ˆ Final stats - Cycles detected: ${finalStats.cyclesDetected}`); // Final validation const allPassed = passedAssertions === assertions.length && cycleResult.type === 'cycle-error' && finalStats.cyclesDetected > 0; if (allPassed) { console.log(' ๐ŸŽ‰ End-to-end test PASSED'); return true; } else { console.log(' โŒ End-to-end test FAILED'); return false; } } catch (error) { console.error(' ๐Ÿ’ฅ End-to-end test error:', error); return false; } } // Validation checklist function printValidationChecklist() { console.log('\n๐Ÿ“‹ Architecture Validation Checklist'); console.log('=' .repeat(50)); const checklist = [ 'โœ… Network call deduplication working', 'โœ… Batch fetching optimization implemented', 'โœ… Cache hit rate > 0% (efficiency gains)', 'โœ… Instance hierarchy management', 'โœ… Recursion depth tracking', 'โœ… Cycle detection and prevention', 'โœ… Memory management and garbage collection', 'โœ… Performance improvements measurable', 'โœ… End-to-end integration working', 'โœ… Error handling for edge cases' ]; for (const item of checklist) { console.log(` ${item}`); } console.log('\n๐ŸŽฏ Architecture is ready for implementation!'); } // Run if called directly if (import.meta.url === `file://${process.argv[1]}`) { runIntegrationTests().then(success => { if (success) { printValidationChecklist(); process.exit(0); } else { console.log('\n๐Ÿ”ง Please fix failing tests before implementation'); process.exit(1); } }); } export { runIntegrationTests, runEndToEndTest };