Files
michaelschiemer/tests/debug/test-discovery-refactor.php
Michael Schiemer 55a330b223 Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
2025-08-11 20:13:26 +02:00

290 lines
11 KiB
PHP

<?php
declare(strict_types=1);
/**
* Test script for the refactored Discovery module
*/
require_once __DIR__ . '/../../vendor/autoload.php';
use App\Framework\Cache\Driver\InMemoryCache;
use App\Framework\Cache\GeneralCache;
use App\Framework\Core\PathProvider;
use App\Framework\DateTime\SystemClock;
use App\Framework\Discovery\UnifiedDiscoveryService;
use App\Framework\Discovery\ValueObjects\DiscoveryOptions;
use App\Framework\Discovery\ValueObjects\ScanType;
use App\Framework\Filesystem\FileSystemService;
use App\Framework\Logging\DefaultLogger;
use App\Framework\Logging\Handlers\ConsoleHandler;
use App\Framework\Logging\LogLevel;
use App\Framework\Performance\MemoryMonitor;
use App\Framework\Reflection\CachedReflectionProvider;
use App\Framework\Serializer\Php\PhpSerializer;
echo "🔍 Testing Refactored Discovery Module\n";
echo "=====================================\n";
try {
// Setup dependencies
$pathProvider = new PathProvider(__DIR__ . '/../..');
$cacheDriver = new InMemoryCache();
$serializer = new PhpSerializer();
$cache = new GeneralCache($cacheDriver, $serializer);
$clock = new SystemClock();
$reflectionProvider = new CachedReflectionProvider();
$fileSystemService = new FileSystemService();
$memoryMonitor = new MemoryMonitor();
// Setup logger
$consoleHandler = new ConsoleHandler();
$logger = new DefaultLogger(LogLevel::INFO, [$consoleHandler]);
echo "✅ Dependencies initialized\n";
// Create discovery service with new architecture
$discoveryService = new UnifiedDiscoveryService(
pathProvider: $pathProvider,
cache: $cache,
clock: $clock,
reflectionProvider: $reflectionProvider,
attributeMappers: [], // Add specific mappers if needed
targetInterfaces: [], // Add specific interfaces if needed
useCache: false, // Disable cache for testing
contextSuffix: '_test',
logger: $logger,
eventDispatcher: null,
memoryMonitor: $memoryMonitor,
fileSystemService: $fileSystemService
);
// Test single directory to debug
echo "\n🔍 Debug: Let's first check if files are being processed properly\n";
// Test if the Admin directory has PHP files
$adminDir = $pathProvider->getBasePath() . '/src/Application/Admin';
echo "Testing directory: $adminDir\n";
if (is_dir($adminDir)) {
$phpFiles = glob($adminDir . '/*.php');
echo "PHP files found: " . count($phpFiles) . "\n";
if (count($phpFiles) > 0) {
echo "First few files:\n";
foreach (array_slice($phpFiles, 0, 3) as $file) {
echo " - " . basename($file) . "\n";
}
}
} else {
echo "Directory not found!\n";
}
echo "✅ Discovery service created with new architecture\n";
// Quick manual test of class extraction
echo "\n🔍 Manual class extraction test:\n";
$testFile = $adminDir . '/Dashboard.php';
if (file_exists($testFile)) {
echo "Testing class extraction on: " . basename($testFile) . "\n";
// Create a file object
$fileInfo = new \SplFileInfo($testFile);
$file = \App\Framework\Filesystem\File::fromSplFileInfo($fileInfo);
// Test class extraction
$extractor = new \App\Framework\Discovery\Processing\ClassExtractor($fileSystemService);
$classNames = $extractor->extractFromFile($file);
echo "Classes found: " . count($classNames) . "\n";
foreach ($classNames as $className) {
echo " - " . $className->getFullyQualified() . "\n";
}
// Debug: Let's read the file content directly and check patterns
echo "\n🔍 Debug file content:\n";
$content = $fileSystemService->readFile($file);
echo "File size: " . strlen($content) . " characters\n";
// Test if content has class keyword
if (str_contains($content, 'class ')) {
echo "✅ Contains 'class ' keyword\n";
} else {
echo "❌ Does NOT contain 'class ' keyword\n";
}
// Test namespace extraction
if (preg_match('/^\s*namespace\s+([^;]+);/m', $content, $matches)) {
echo "✅ Namespace found: " . $matches[1] . "\n";
} else {
echo "❌ No namespace found\n";
}
// Test class extraction pattern
$pattern = '/^\s*(?:final\s+)?(?:abstract\s+)?(?:readonly\s+)?class\s+([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)/mi';
if (preg_match_all($pattern, $content, $matches)) {
echo "✅ Class pattern matched: " . count($matches[1]) . " classes\n";
foreach ($matches[1] as $className) {
echo " - Class: $className\n";
}
} else {
echo "❌ Class pattern did not match\n";
}
// Test reflection on the class directly
echo "\n🔍 Manual reflection test on Dashboard class:\n";
try {
$dashboardClass = \App\Application\Admin\Dashboard::class;
$reflection = new \ReflectionClass($dashboardClass);
echo "✅ Reflection created for: $dashboardClass\n";
$methods = $reflection->getMethods();
echo "Methods found: " . count($methods) . "\n";
foreach ($methods as $method) {
$attributes = $method->getAttributes();
if (! empty($attributes)) {
echo " Method {$method->getName()} has " . count($attributes) . " attributes:\n";
foreach ($attributes as $attr) {
echo " - " . $attr->getName() . "\n";
if (str_contains($attr->getName(), 'Route')) {
echo " ✅ ROUTE ATTRIBUTE FOUND!\n";
try {
$instance = $attr->newInstance();
echo " - Instance created successfully\n";
if (method_exists($instance, 'path')) {
echo " - Path: " . $instance->path . "\n";
}
if (method_exists($instance, 'method')) {
echo " - Method: " . $instance->method->value . "\n";
}
} catch (\Throwable $e) {
echo " - Failed to create instance: " . $e->getMessage() . "\n";
}
}
}
}
}
} catch (\Throwable $e) {
echo "❌ Reflection failed: " . $e->getMessage() . "\n";
}
}
// Test health status
echo "\n📊 Health Status:\n";
$health = $discoveryService->getHealthStatus();
foreach ($health as $key => $value) {
if (is_array($value)) {
echo " $key:\n";
foreach ($value as $subKey => $subValue) {
echo " $subKey: " . (is_array($subValue) ? json_encode($subValue) : $subValue) . "\n";
}
} else {
echo " $key: $value\n";
}
}
// Test discovery with limited scope for faster testing
echo "\n🔍 Running Discovery (limited scope)...\n";
$startTime = microtime(true);
$startMemory = memory_get_usage(true);
$options = new DiscoveryOptions(
scanType: ScanType::FULL,
paths: [
$pathProvider->getBasePath() . '/src/Application/Admin',
],
useCache: false
);
$registry = $discoveryService->discoverWithOptions($options);
$endTime = microtime(true);
$endMemory = memory_get_usage(true);
echo "✅ Discovery completed!\n";
echo "\n📈 Results:\n";
echo " Total items: " . count($registry) . "\n";
echo " Attributes: " . count($registry->attributes) . "\n";
echo " Interfaces: " . count($registry->interfaces) . "\n";
echo " Routes: " . count($registry->routes) . "\n";
echo " Templates: " . count($registry->templates) . "\n";
echo "\n⏱️ Performance:\n";
echo " Duration: " . round(($endTime - $startTime) * 1000, 2) . "ms\n";
echo " Memory used: " . round(($endMemory - $startMemory) / 1024 / 1024, 2) . "MB\n";
echo " Peak memory: " . round(memory_get_peak_usage(true) / 1024 / 1024, 2) . "MB\n";
// Test registry statistics
echo "\n📊 Memory Statistics:\n";
$stats = $registry->getMemoryStats();
foreach ($stats as $type => $stat) {
if (is_array($stat)) {
echo " $type:\n";
foreach ($stat as $key => $value) {
echo " $key: $value\n";
}
} else {
echo " $type: $stat\n";
}
}
// Show some example discovered items
echo "\n🔍 Sample Discoveries:\n";
// Show attributes
$attributeTypes = $registry->attributes->getAllTypes();
if (! empty($attributeTypes)) {
echo " Attribute Types Found:\n";
foreach (array_slice($attributeTypes, 0, 5) as $type) {
$count = count($registry->attributes->get($type));
echo " - $type ($count instances)\n";
}
// Debug: Look for Route attributes specifically
echo "\n 🔍 Debug - Looking for Route attributes:\n";
foreach ($attributeTypes as $type) {
if (str_contains($type, 'Route')) {
echo " ✅ Route attribute found: $type\n";
$instances = $registry->attributes->get($type);
foreach ($instances as $instance) {
echo " - Method: " . ($instance->method ? $instance->method->toString() : 'class-level') . "\n";
}
}
}
if (! array_filter($attributeTypes, fn ($type) => str_contains($type, 'Route'))) {
echo " ❌ No Route attributes found. Looking for all attribute types:\n";
foreach ($attributeTypes as $type) {
echo " - $type\n";
}
}
}
// Show routes
$routes = $registry->routes->getAll();
if (! empty($routes)) {
echo " Routes Found:\n";
foreach (array_slice($routes, 0, 3) as $route) {
echo " - {$route->method->value} {$route->path} -> {$route->class->getShortName()}::{$route->handler->toString()}\n";
}
}
echo "\n✅ Discovery refactoring test completed successfully!\n";
echo "\n🎯 Key Improvements:\n";
echo " ✅ Separated concerns into focused components\n";
echo " ✅ Shared reflection context (no duplication)\n";
echo " ✅ Stream-based processing for memory efficiency\n";
echo " ✅ Modern value object architecture\n";
echo " ✅ Improved caching strategy\n";
echo " ✅ Better error handling and logging\n";
} catch (Throwable $e) {
echo "\n❌ Error during discovery test:\n";
echo " Message: " . $e->getMessage() . "\n";
echo " File: " . $e->getFile() . ":" . $e->getLine() . "\n";
echo " Stack trace:\n" . $e->getTraceAsString() . "\n";
exit(1);
}