fileSystemService = new FileSystemService(); $this->checker = new StalenessChecker($this->fileSystemService); }); it('returns stale for incremental scan', function () { $registry = new DiscoveryRegistry( attributes: new AttributeRegistry(), interfaces: new InterfaceRegistry(), templates: new TemplateRegistry() ); $entry = new CacheEntry( registry: $registry, createdAt: Timestamp::fromDateTime(new \DateTimeImmutable()), version: 'v1-abc12345', cacheLevel: CacheLevel::NORMAL, cacheTier: CacheTier::HOT ); $context = new DiscoveryContext( paths: ['/test/path'], scanType: ScanType::INCREMENTAL, options: new DiscoveryOptions(), startTime: new \DateTimeImmutable() ); $result = $this->checker->check($context, $entry); expect($result->isStale)->toBeTrue(); expect($result->reason)->toBe('incremental_scan'); }); it('checks staleness with real filesystem', function () { $registry = new DiscoveryRegistry( attributes: new AttributeRegistry(), interfaces: new InterfaceRegistry(), templates: new TemplateRegistry() ); // Use a past time to ensure cache is stale (directory was modified after cache creation) $createdAt = Timestamp::fromDateTime(new \DateTimeImmutable('2020-01-01 12:00:00')); $entry = new CacheEntry( registry: $registry, createdAt: $createdAt, version: 'v1-abc12345', cacheLevel: CacheLevel::NORMAL, cacheTier: CacheTier::HOT ); // Use real existing path $basePath = file_exists('/var/www/html/src') ? '/var/www/html/src' : __DIR__ . '/../../../../src'; $context = new DiscoveryContext( paths: [$basePath], scanType: ScanType::FULL, options: new DiscoveryOptions(), startTime: new \DateTimeImmutable('2020-01-01 13:00:00') ); $result = $this->checker->check($context, $entry); // Should be stale (directory modified after cache creation) expect($result)->toBeInstanceOf(StalenessCheckResult::class); expect($result->isStale)->toBeTrue(); }); it('handles non-existent paths gracefully', function () { $registry = new DiscoveryRegistry( attributes: new AttributeRegistry(), interfaces: new InterfaceRegistry(), templates: new TemplateRegistry() ); $entry = new CacheEntry( registry: $registry, createdAt: Timestamp::fromDateTime(new \DateTimeImmutable()), version: 'v1-abc12345', cacheLevel: CacheLevel::NORMAL, cacheTier: CacheTier::HOT ); $context = new DiscoveryContext( paths: ['/non/existent/path'], scanType: ScanType::FULL, options: new DiscoveryOptions(), startTime: new \DateTimeImmutable() ); $result = $this->checker->check($context, $entry); // Should assume stale on error (conservative) expect($result->isStale)->toBeTrue(); }); });