startTime = microtime(true); echo "πŸ” Enhanced Discovery System Test Starting...\n\n"; } public function runAllTests(): void { echo "πŸ“‹ Running enhanced discovery system tests...\n\n"; // Test Value Objects $this->testDiscoveryPlan(); $this->testPlanStrategy(); $this->testDiscoveryMetrics(); $this->testComponentType(); $this->testDependencyGraph(); // Generate final report $this->generateReport(); } private function testDiscoveryPlan(): void { echo "πŸ“‹ Testing Discovery Plan...\n"; try { // Test optimized plan creation $optimizedPlan = DiscoveryPlan::optimized( ['/src/Framework', '/src/Application'], ['Route', 'Command'] ); $this->assert($optimizedPlan->getStrategy() === PlanStrategy::PERFORMANCE_OPTIMIZED, 'Should use performance optimized strategy'); $this->assert($optimizedPlan->hasOptimization('memory_efficient'), 'Should have memory efficient optimization'); $this->assert(count($optimizedPlan->getPaths()) === 2, 'Should have correct path count'); // Test comprehensive plan $comprehensivePlan = DiscoveryPlan::comprehensive( ['/src'], ['Route', 'Command', 'Event'] ); $this->assert($comprehensivePlan->getStrategy() === PlanStrategy::COMPREHENSIVE, 'Should use comprehensive strategy'); $this->assert($comprehensivePlan->hasOptimization('deep_analysis'), 'Should have deep analysis'); // Test minimal plan $minimalPlan = DiscoveryPlan::minimal(['/src/small']); $this->assert($minimalPlan->getStrategy() === PlanStrategy::MINIMAL, 'Should use minimal strategy'); $this->assert($minimalPlan->hasOptimization('cache_only'), 'Should be cache only'); // Test plan modifications $modifiedPlan = $optimizedPlan->withOptimizations(['custom_optimization' => true]); $this->assert($modifiedPlan->hasOptimization('custom_optimization'), 'Should have custom optimization'); echo " βœ… Discovery Plan tests passed\n"; $this->results['discovery_plan'] = ['status' => 'PASSED', 'details' => 'All plan creation and modification tests passed']; } catch (\Throwable $e) { $this->results['discovery_plan'] = ['status' => 'FAILED', 'error' => $e->getMessage()]; echo " ❌ Discovery Plan test failed: " . $e->getMessage() . "\n"; } } private function testPlanStrategy(): void { echo "🎯 Testing Plan Strategy...\n"; try { // Test strategy descriptions $performance = PlanStrategy::PERFORMANCE_OPTIMIZED; $this->assert(! empty($performance->getDescription()), 'Should have description'); $this->assert(! empty($performance->getDefaultOptimizations()), 'Should have default optimizations'); // Test strategy features $this->assert($performance->supports('caching'), 'Performance strategy should support caching'); $this->assert($performance->supports('parallel_processing'), 'Performance strategy should support parallel processing'); // Test strategy recommendation $context = ['path_count' => 100, 'accuracy' => 'high', 'time_limit' => 10]; $recommended = PlanStrategy::recommendFor($context); $this->assert($recommended !== null, 'Should recommend a strategy'); // Test memory efficient strategy $memoryContext = ['path_count' => 2000, 'memory_limit' => 32 * 1024 * 1024]; $memoryStrategy = PlanStrategy::recommendFor($memoryContext); $this->assert($memoryStrategy === PlanStrategy::MEMORY_EFFICIENT, 'Should recommend memory efficient for large projects'); echo " βœ… Plan Strategy tests passed\n"; $this->results['plan_strategy'] = ['status' => 'PASSED', 'details' => 'All strategy tests passed']; } catch (\Throwable $e) { $this->results['plan_strategy'] = ['status' => 'FAILED', 'error' => $e->getMessage()]; echo " ❌ Plan Strategy test failed: " . $e->getMessage() . "\n"; } } private function testDiscoveryMetrics(): void { echo "πŸ“Š Testing Discovery Metrics...\n"; try { // Test metrics creation $metrics = new DiscoveryMetrics( cacheHitRate: 0.85, averageDiscoveryTime: 2.5, componentsDiscovered: 150, patternMatchRate: 0.75, predictionAccuracy: 0.8, memoryEfficiency: 0.9, optimizationImpact: 0.6 ); // Test efficiency score calculation $score = $metrics->getEfficiencyScore(); $this->assert($score > 0.7, 'Efficiency score should be above 0.7'); // Test performance rating $rating = $metrics->getPerformanceRating(); $this->assert(in_array($rating, ['excellent', 'very_good', 'good', 'average', 'below_average', 'poor']), 'Should have valid rating'); // Test components per second $cps = $metrics->getComponentsPerSecond(); $this->assert($cps > 0, 'Components per second should be positive'); // Test improvement suggestions $suggestions = $metrics->getImprovementSuggestions(); $this->assert(is_array($suggestions), 'Should return suggestions array'); // Test array conversion $array = $metrics->toArray(); $this->assert(isset($array['efficiency_score']), 'Array should contain efficiency score'); $this->assert(isset($array['performance_rating']), 'Array should contain performance rating'); // Test empty metrics $emptyMetrics = DiscoveryMetrics::empty(); $this->assert($emptyMetrics->getEfficiencyScore() === 0.0, 'Empty metrics should have zero efficiency'); echo " βœ… Discovery Metrics tests passed\n"; $this->results['discovery_metrics'] = ['status' => 'PASSED', 'details' => 'All metrics tests passed']; } catch (\Throwable $e) { $this->results['discovery_metrics'] = ['status' => 'FAILED', 'error' => $e->getMessage()]; echo " ❌ Discovery Metrics test failed: " . $e->getMessage() . "\n"; } } private function testComponentType(): void { echo "🧩 Testing Component Type...\n"; try { // Test component type properties $controller = ComponentType::CONTROLLER; $this->assert($controller->getDescription() !== '', 'Should have description'); $this->assert($controller->getWeight() > 1.0, 'Controller should have high weight'); $this->assert($controller->hasDependencies(), 'Controller should typically have dependencies'); $this->assert($controller->getPerformanceImpact() === 'high', 'Controller should have high performance impact'); // Test service type $service = ComponentType::SERVICE; $this->assert($service->getWeight() > 1.0, 'Service should have above-average weight'); $this->assert($service->hasDependencies(), 'Service should typically have dependencies'); // Test value object type $valueObject = ComponentType::VALUE_OBJECT; $this->assert($valueObject->getWeight() < 1.0, 'Value object should have low weight'); $this->assert(! $valueObject->hasDependencies(), 'Value object should not typically have dependencies'); // Test typical dependencies $controllerDeps = $controller->getTypicalDependencies(); $this->assert(in_array('service', $controllerDeps), 'Controller should typically depend on services'); echo " βœ… Component Type tests passed\n"; $this->results['component_type'] = ['status' => 'PASSED', 'details' => 'All component type tests passed']; } catch (\Throwable $e) { $this->results['component_type'] = ['status' => 'FAILED', 'error' => $e->getMessage()]; echo " ❌ Component Type test failed: " . $e->getMessage() . "\n"; } } private function testDependencyGraph(): void { echo "πŸ•ΈοΈ Testing Dependency Graph...\n"; try { // Create test nodes $nodeA = DependencyNode::simple('A', 'ComponentA', ComponentType::CONTROLLER); $nodeB = DependencyNode::simple('B', 'ComponentB', ComponentType::SERVICE); $nodeC = DependencyNode::simple('C', 'ComponentC', ComponentType::REPOSITORY); // Create test edges $edgeAB = DependencyEdge::constructor('A', 'B'); $edgeBC = DependencyEdge::method('B', 'C', 0.8); // Create graph $graph = new DependencyGraph([$nodeA, $nodeB, $nodeC], [$edgeAB, $edgeBC]); // Test basic operations $this->assert(count($graph->getNodes()) === 3, 'Should have 3 nodes'); $this->assert(count($graph->getEdges()) === 2, 'Should have 2 edges'); // Test node retrieval $retrievedNode = $graph->getNode('A'); $this->assert($retrievedNode !== null, 'Should find node A'); $this->assert($retrievedNode->name === 'ComponentA', 'Should have correct name'); // Test edge operations $edgesFromA = $graph->getEdgesFrom('A'); $this->assert(count($edgesFromA) === 1, 'A should have 1 outgoing edge'); $this->assert($edgesFromA[0]->to === 'B', 'A should connect to B'); $edgesToB = $graph->getEdgesTo('B'); $this->assert(count($edgesToB) === 1, 'B should have 1 incoming edge'); // Test dependencies $depsA = $graph->getDependencies('A'); $this->assert(in_array('B', $depsA), 'A should depend on B'); $dependentsB = $graph->getDependents('B'); $this->assert(in_array('A', $dependentsB), 'A should be dependent on B'); // Test path finding $hasPath = $graph->hasPath('A', 'C'); $this->assert($hasPath, 'Should have path from A to C'); $shortestPath = $graph->getShortestPath('A', 'C'); $this->assert($shortestPath === ['A', 'B', 'C'], 'Should find correct shortest path'); // Test statistics $stats = $graph->getStatistics(); $this->assert($stats['node_count'] === 3, 'Stats should show 3 nodes'); $this->assert($stats['edge_count'] === 2, 'Stats should show 2 edges'); // Test array conversion $graphArray = $graph->toArray(); $this->assert(isset($graphArray['nodes']), 'Should have nodes in array'); $this->assert(isset($graphArray['edges']), 'Should have edges in array'); $this->assert(isset($graphArray['statistics']), 'Should have statistics in array'); echo " βœ… Dependency Graph tests passed\n"; $this->results['dependency_graph'] = ['status' => 'PASSED', 'details' => 'All dependency graph tests passed']; } catch (\Throwable $e) { $this->results['dependency_graph'] = ['status' => 'FAILED', 'error' => $e->getMessage()]; echo " ❌ Dependency Graph test failed: " . $e->getMessage() . "\n"; } } private function generateReport(): void { $totalTime = microtime(true) - $this->startTime; echo "\nπŸ“Š ENHANCED DISCOVERY TEST REPORT\n"; echo "═══════════════════════════════════════════════════════\n\n"; $passed = 0; $failed = 0; foreach ($this->results as $testName => $result) { $status = $result['status'] === 'PASSED' ? 'βœ…' : '❌'; $statusText = $result['status']; echo "{$status} {$testName}: {$statusText}\n"; if ($result['status'] === 'PASSED') { $passed++; if (isset($result['details'])) { echo " πŸ“ {$result['details']}\n"; } } else { $failed++; echo " ❌ Error: {$result['error']}\n"; } echo "\n"; } echo "═══════════════════════════════════════════════════════\n"; echo "πŸ“ˆ SUMMARY:\n"; echo " βœ… Passed: {$passed}\n"; echo " ❌ Failed: {$failed}\n"; echo " ⏱️ Total time: " . round($totalTime, 3) . "s\n"; echo " 🧠 Memory usage: " . $this->formatBytes(memory_get_usage(true)) . "\n"; if ($failed === 0) { echo "\nπŸŽ‰ ALL ENHANCED DISCOVERY TESTS PASSED!\n"; echo "✨ Phase 4: Enhanced Auto-Discovery System is complete!\n"; } else { echo "\n⚠️ Some tests failed. Please check the errors above.\n"; } } private function assert(bool $condition, string $message): void { if (! $condition) { throw new \AssertionError("Assertion failed: {$message}"); } } private function formatBytes(int $bytes): string { if ($bytes === 0) { return '0 B'; } $units = ['B', 'KB', 'MB', 'GB']; $unitIndex = 0; $value = $bytes; while ($value >= 1024 && $unitIndex < count($units) - 1) { $value /= 1024; $unitIndex++; } return round($value, 2) . ' ' . $units[$unitIndex]; } } // Run the tests $tester = new EnhancedDiscoveryTester(); $tester->runAllTests();