cache = new GeneralCache($cacheDriver, $serializer); $this->clock = new SystemClock(); $this->fileSystemService = new FileSystemService(); // Use a real existing path with future time $basePath = file_exists('/var/www/html/src') ? '/var/www/html/src' : __DIR__ . '/../../../../src'; // Use a future time to avoid stale detection $futureTime = new \DateTimeImmutable('2099-01-01 00:00:00'); $this->testContext = new DiscoveryContext( paths: [$basePath], 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('debugs cache storage and retrieval flow', function () { // Step 1: Store $success = $this->cacheManager->store($this->testContext, $this->testRegistry); expect($success)->toBeTrue('Store should succeed'); // Step 2: Check cache directly $key = $this->testContext->getCacheKey(); $result = $this->cache->get($key); $item = $result->getItem($key); expect($item->isHit)->toBeTrue('Cache item should be hit'); $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'); // Step 3: Test serializer supports $serializer = new CacheEntrySerializer(); $supports = $serializer->supports($cacheData); expect($supports)->toBeTrue('Serializer should support cache data'); // Step 4: Debug cache data structure expect($cacheData['startTime'])->not->toBeNull('startTime should not be null'); expect(is_int($cacheData['startTime']))->toBeTrue('startTime should be int timestamp'); // Step 5: Test deserialization try { $entry = $serializer->deserialize($cacheData); expect($entry)->toBeInstanceOf(CacheEntry::class, 'Deserialization should return CacheEntry'); expect($entry->registry)->toBeInstanceOf(DiscoveryRegistry::class, 'Registry should be DiscoveryRegistry'); } catch (\Throwable $e) { $this->fail("Deserialization failed: {$e->getMessage()}\nCache data keys: " . implode(', ', array_keys($cacheData)) . "\nstartTime type: " . gettype($cacheData['startTime'] ?? 'NOT SET')); } // Step 5: Test validator $validator = new CacheEntryValidator(); $valid = $validator->validate($cacheData); expect($valid)->toBeTrue('Cache data should be valid'); // Step 6: Test staleness checker $stalenessChecker = new StalenessChecker($this->fileSystemService); $stalenessCheck = $stalenessChecker->check($this->testContext, $entry); // Step 7: Finally test retrieval $cached = $this->cacheManager->get($this->testContext); if ($cached === null) { $this->fail("Retrieval returned null. Staleness check: " . ($stalenessCheck->isStale ? 'STALE' : 'FRESH')); } expect($cached)->toBeInstanceOf(DiscoveryRegistry::class); }); });