- Move 12 markdown files from root to docs/ subdirectories - Organize documentation by category: • docs/troubleshooting/ (1 file) - Technical troubleshooting guides • docs/deployment/ (4 files) - Deployment and security documentation • docs/guides/ (3 files) - Feature-specific guides • docs/planning/ (4 files) - Planning and improvement proposals Root directory cleanup: - Reduced from 16 to 4 markdown files in root - Only essential project files remain: • CLAUDE.md (AI instructions) • README.md (Main project readme) • CLEANUP_PLAN.md (Current cleanup plan) • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements) This improves: ✅ Documentation discoverability ✅ Logical organization by purpose ✅ Clean root directory ✅ Better maintainability
195 lines
6.9 KiB
PHP
195 lines
6.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Framework\Discovery;
|
|
|
|
use App\Framework\Cache\Cache;
|
|
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\Results\DiscoveryRegistry;
|
|
use App\Framework\Discovery\UnifiedDiscoveryService;
|
|
use App\Framework\Discovery\ValueObjects\DiscoveryConfiguration;
|
|
use App\Framework\Reflection\CachedReflectionProvider;
|
|
use App\Framework\Serializer\Php\PhpSerializer;
|
|
use App\Framework\Serializer\Php\PhpSerializerConfig;
|
|
|
|
describe('UnifiedDiscoveryService', function () {
|
|
beforeEach(function () {
|
|
$cacheDriver = new InMemoryCache();
|
|
$serializer = new PhpSerializer(PhpSerializerConfig::safe());
|
|
$this->cache = new GeneralCache($cacheDriver, $serializer);
|
|
$this->clock = new SystemClock();
|
|
$this->pathProvider = new PathProvider('/home/michael/dev/michaelschiemer');
|
|
$this->reflectionProvider = new CachedReflectionProvider();
|
|
|
|
$this->configuration = new DiscoveryConfiguration(
|
|
paths: ['/home/michael/dev/michaelschiemer/tests/fixtures'],
|
|
useCache: false, // Disable cache for tests
|
|
enableMemoryMonitoring: false,
|
|
memoryLimitMB: 64,
|
|
maxFilesPerBatch: 100
|
|
);
|
|
|
|
// Clear cache between tests
|
|
$this->cache->clear();
|
|
});
|
|
|
|
it('can be instantiated with required dependencies', function () {
|
|
$service = new UnifiedDiscoveryService(
|
|
pathProvider: $this->pathProvider,
|
|
cache: $this->cache,
|
|
clock: $this->clock,
|
|
reflectionProvider: $this->reflectionProvider,
|
|
configuration: $this->configuration
|
|
);
|
|
|
|
expect($service)->toBeInstanceOf(UnifiedDiscoveryService::class);
|
|
});
|
|
|
|
it('performs discovery and returns DiscoveryRegistry', function () {
|
|
$service = new UnifiedDiscoveryService(
|
|
pathProvider: $this->pathProvider,
|
|
cache: $this->cache,
|
|
clock: $this->clock,
|
|
reflectionProvider: $this->reflectionProvider,
|
|
configuration: $this->configuration
|
|
);
|
|
|
|
$registry = $service->discover();
|
|
|
|
expect($registry)->toBeInstanceOf(DiscoveryRegistry::class);
|
|
expect($registry->attributes)->toBeInstanceOf(\App\Framework\Discovery\Results\AttributeRegistry::class);
|
|
expect($registry->interfaces)->toBeInstanceOf(\App\Framework\Discovery\Results\InterfaceRegistry::class);
|
|
});
|
|
|
|
it('handles empty scan paths gracefully', function () {
|
|
$emptyConfig = new DiscoveryConfiguration(
|
|
paths: [],
|
|
useCache: false,
|
|
enableMemoryMonitoring: false,
|
|
memoryLimitMB: 64,
|
|
maxFilesPerBatch: 100
|
|
);
|
|
|
|
$service = new UnifiedDiscoveryService(
|
|
pathProvider: $this->pathProvider,
|
|
cache: $this->cache,
|
|
clock: $this->clock,
|
|
reflectionProvider: $this->reflectionProvider,
|
|
configuration: $emptyConfig
|
|
);
|
|
|
|
$registry = $service->discover();
|
|
|
|
expect($registry)->toBeInstanceOf(DiscoveryRegistry::class);
|
|
// Empty paths should still return a valid registry, just empty
|
|
expect($registry->attributes->getAll())->toBeArray();
|
|
});
|
|
|
|
it('supports incremental discovery', function () {
|
|
$service = new UnifiedDiscoveryService(
|
|
pathProvider: $this->pathProvider,
|
|
cache: $this->cache,
|
|
clock: $this->clock,
|
|
reflectionProvider: $this->reflectionProvider,
|
|
configuration: $this->configuration
|
|
);
|
|
|
|
$registry = $service->incrementalDiscover();
|
|
|
|
expect($registry)->toBeInstanceOf(DiscoveryRegistry::class);
|
|
});
|
|
|
|
it('validates configuration on instantiation', function () {
|
|
$invalidConfig = new DiscoveryConfiguration(
|
|
paths: ['/nonexistent/path'],
|
|
useCache: false,
|
|
enableMemoryMonitoring: false,
|
|
memoryLimitMB: -1, // Invalid memory limit
|
|
maxFilesPerBatch: 0 // Invalid batch size
|
|
);
|
|
|
|
expect(function () {
|
|
new UnifiedDiscoveryService(
|
|
pathProvider: $this->pathProvider,
|
|
cache: $this->cache,
|
|
clock: $this->clock,
|
|
reflectionProvider: $this->reflectionProvider,
|
|
configuration: $invalidConfig
|
|
);
|
|
})->toThrow(\InvalidArgumentException::class);
|
|
});
|
|
|
|
it('handles memory management configuration', function () {
|
|
$memoryConfig = new DiscoveryConfiguration(
|
|
paths: ['/home/michael/dev/michaelschiemer/src'],
|
|
useCache: false,
|
|
enableMemoryMonitoring: true,
|
|
memoryLimitMB: 32, // 32MB limit
|
|
maxFilesPerBatch: 50
|
|
);
|
|
|
|
$service = new UnifiedDiscoveryService(
|
|
pathProvider: $this->pathProvider,
|
|
cache: $this->cache,
|
|
clock: $this->clock,
|
|
reflectionProvider: $this->reflectionProvider,
|
|
configuration: $memoryConfig
|
|
);
|
|
|
|
expect($service)->toBeInstanceOf(UnifiedDiscoveryService::class);
|
|
|
|
// Should not throw memory errors with management enabled
|
|
$registry = $service->discover();
|
|
expect($registry)->toBeInstanceOf(DiscoveryRegistry::class);
|
|
});
|
|
|
|
it('respects chunk size in configuration', function () {
|
|
$smallChunkConfig = new DiscoveryConfiguration(
|
|
paths: ['/home/michael/dev/michaelschiemer/tests'],
|
|
useCache: false,
|
|
enableMemoryMonitoring: false,
|
|
memoryLimitMB: 64,
|
|
maxFilesPerBatch: 5 // Very small batches
|
|
);
|
|
|
|
$service = new UnifiedDiscoveryService(
|
|
pathProvider: $this->pathProvider,
|
|
cache: $this->cache,
|
|
clock: $this->clock,
|
|
reflectionProvider: $this->reflectionProvider,
|
|
configuration: $smallChunkConfig
|
|
);
|
|
|
|
$registry = $service->discover();
|
|
|
|
expect($registry)->toBeInstanceOf(DiscoveryRegistry::class);
|
|
// Should handle small chunks without issues
|
|
});
|
|
|
|
it('handles file system errors gracefully', function () {
|
|
$invalidPathConfig = new DiscoveryConfiguration(
|
|
paths: ['/completely/nonexistent/path'],
|
|
useCache: false,
|
|
enableMemoryMonitoring: false,
|
|
memoryLimitMB: 64,
|
|
maxFilesPerBatch: 100
|
|
);
|
|
|
|
$service = new UnifiedDiscoveryService(
|
|
pathProvider: $this->pathProvider,
|
|
cache: $this->cache,
|
|
clock: $this->clock,
|
|
reflectionProvider: $this->reflectionProvider,
|
|
configuration: $invalidPathConfig
|
|
);
|
|
|
|
// Should not throw but return empty registry
|
|
$registry = $service->discover();
|
|
expect($registry)->toBeInstanceOf(DiscoveryRegistry::class);
|
|
});
|
|
});
|