cache = new GeneralCache($cacheDriver, $serializer); $this->clock = new SystemClock(); $this->fileSystemService = new FileSystemService(); // Use a real existing path but with future time to avoid stale detection // This prevents the test from triggering actual discovery while allowing staleness checks $basePath = file_exists('/var/www/html/src') ? '/var/www/html/src' : __DIR__ . '/../../../../src'; $testPath = $basePath; // Use a future time to avoid stale detection issues $futureTime = new \DateTimeImmutable('2099-01-01 00:00:00'); $this->testContext = new DiscoveryContext( paths: [$testPath], scanType: ScanType::FULL, options: new DiscoveryOptions(), startTime: $futureTime ); $this->testRegistry = new DiscoveryRegistry( attributes: new AttributeRegistry(), interfaces: new InterfaceRegistry(), templates: new TemplateRegistry() ); // Create cache manager with new services $this->cacheManager = new DiscoveryCacheManager( cache: $this->cache, clock: $this->clock, fileSystemService: $this->fileSystemService, serializer: new CacheEntrySerializer(), stalenessChecker: new StalenessChecker($this->fileSystemService), validator: new CacheEntryValidator(), upgrader: new CacheEntryUpgrader() ); }); it('stores registry using new CacheEntry structure', function () { $success = $this->cacheManager->store($this->testContext, $this->testRegistry); expect($success)->toBeTrue(); // Debug: Check what's in cache $key = $this->testContext->getCacheKey(); $result = $this->cache->get($key); $item = $result->getItem($key); expect($item->isHit)->toBeTrue('Cache item should be hit'); // Verify cache structure $cacheData = $item->value; expect(is_array($cacheData))->toBeTrue('Cache data should be array'); expect(isset($cacheData['registry']))->toBeTrue('Cache should have registry'); expect(isset($cacheData['startTime']))->toBeTrue('Cache should have startTime'); expect(isset($cacheData['version']))->toBeTrue('Cache should have version'); // Verify cache contains the data $cached = $this->cacheManager->get($this->testContext); expect($cached)->not->toBeNull('Cached registry should not be null'); expect($cached)->toBeInstanceOf(DiscoveryRegistry::class); expect($cached->isEmpty())->toBe($this->testRegistry->isEmpty()); }); it('retrieves cached registry using new services', function () { // Store first $this->cacheManager->store($this->testContext, $this->testRegistry); // Retrieve $cached = $this->cacheManager->get($this->testContext); expect($cached)->toBeInstanceOf(DiscoveryRegistry::class); expect($cached->isEmpty())->toBe($this->testRegistry->isEmpty()); }); it('handles cache miss correctly', function () { // Don't store anything $cached = $this->cacheManager->get($this->testContext); expect($cached)->toBeNull(); }); it('stores and retrieves with version information', function () { $success = $this->cacheManager->store($this->testContext, $this->testRegistry); expect($success)->toBeTrue(); // Retrieve should work $cached = $this->cacheManager->get($this->testContext); expect($cached)->toBeInstanceOf(DiscoveryRegistry::class); }); it('handles cache invalidation', function () { // Store $this->cacheManager->store($this->testContext, $this->testRegistry); // Invalidate $invalidated = $this->cacheManager->invalidate($this->testContext); expect($invalidated)->toBeTrue(); // Should not be retrievable $cached = $this->cacheManager->get($this->testContext); expect($cached)->toBeNull(); }); it('uses CacheEntrySerializer for serialization', function () { $success = $this->cacheManager->store($this->testContext, $this->testRegistry); expect($success)->toBeTrue(); // Verify cache contains serialized CacheEntry structure $key = $this->testContext->getCacheKey(); $result = $this->cache->get($key); $item = $result->getItem($key); expect($item->isHit)->toBeTrue(); // Data should be an array (serialized CacheEntry) $data = $item->value; expect(is_array($data))->toBeTrue(); expect(isset($data['registry']))->toBeTrue(); expect(isset($data['version']))->toBeTrue(); }); it('uses StalenessChecker for staleness detection', function () { // Store with future time $this->cacheManager->store($this->testContext, $this->testRegistry); // Retrieve should work (cache is fresh) $cached = $this->cacheManager->get($this->testContext); expect($cached)->toBeInstanceOf(DiscoveryRegistry::class); }); it('handles incremental scans as stale', function () { // Store first $this->cacheManager->store($this->testContext, $this->testRegistry); // Create incremental context $incrementalContext = new DiscoveryContext( paths: $this->testContext->paths, scanType: ScanType::INCREMENTAL, options: new DiscoveryOptions(), startTime: $this->testContext->startTime ); // Should return null (stale) $cached = $this->cacheManager->get($incrementalContext); expect($cached)->toBeNull(); }); it('uses CacheEntryValidator for validation', function () { // Store valid data $this->cacheManager->store($this->testContext, $this->testRegistry); // Should retrieve successfully $cached = $this->cacheManager->get($this->testContext); expect($cached)->toBeInstanceOf(DiscoveryRegistry::class); }); it('uses CacheEntryUpgrader for old format migration', function () { // Store old format directly (just DiscoveryRegistry) $key = $this->testContext->getCacheKey(); $oldFormatItem = CacheItem::forSet($key, $this->testRegistry); $this->cache->set($oldFormatItem); // Retrieve should upgrade automatically $cached = $this->cacheManager->get($this->testContext); // Should work (upgraded) expect($cached)->toBeInstanceOf(DiscoveryRegistry::class); }); });