11<?php
22namespace Mvc \Cache ;
33
4+ use Neuron \Core \System \FrozenClock ;
45use Neuron \Mvc \Cache \Exceptions \CacheException ;
56use Neuron \Mvc \Cache \Storage \FileCacheStorage ;
67use PHPUnit \Framework \TestCase ;
78use org \bovigo \vfs \vfsStream ;
89
910/**
1011 * Tests FileCacheStorage using vfsStream for isolation and speed.
12+ * Uses FrozenClock for instant time-based tests without sleep().
1113 * Note: Some operations like clear() don't work with vfsStream due to its limitations.
1214 * See FileCacheStorageRealTest for tests using real filesystem.
1315 */
1416class FileCacheStorageTest extends TestCase
1517{
1618 private $ Root ;
1719 private FileCacheStorage $ Storage ;
20+ private FrozenClock $ Clock ;
1821
1922 protected function setUp (): void
2023 {
2124 $ this ->Root = vfsStream::setup ( 'cache ' );
22- $ this ->Storage = new FileCacheStorage ( vfsStream::url ( 'cache ' ) );
25+ $ this ->Clock = new FrozenClock ( 1000000 ); // Start at a fixed time
26+ $ this ->Storage = new FileCacheStorage ( vfsStream::url ( 'cache ' ), null , $ this ->Clock );
2327 }
2428
2529 public function testWriteAndRead ()
@@ -71,12 +75,13 @@ public function testIsExpired()
7175 {
7276 $ Key = 'test_expired ' ;
7377 $ Content = 'Test content ' ;
74-
78+
7579 $ this ->Storage ->write ( $ Key , $ Content , 1 );
7680 $ this ->assertFalse ( $ this ->Storage ->isExpired ( $ Key ) );
77-
78- sleep ( 2 );
79-
81+
82+ // Advance time by 2 seconds (instant, no actual sleeping)
83+ $ this ->Clock ->advance ( 2 );
84+
8085 $ this ->assertTrue ( $ this ->Storage ->isExpired ( $ Key ) );
8186 $ this ->assertNull ( $ this ->Storage ->read ( $ Key ) );
8287 }
@@ -181,20 +186,20 @@ public function testGarbageCollection()
181186 $ this ->Storage ->write ( 'keep2 ' , 'content2 ' , 3600 ); // Keep for 1 hour
182187 $ this ->Storage ->write ( 'expire1 ' , 'content3 ' , 1 ); // Expire in 1 second
183188 $ this ->Storage ->write ( 'expire2 ' , 'content4 ' , 1 ); // Expire in 1 second
184-
189+
185190 // All should exist initially
186191 $ this ->assertTrue ( $ this ->Storage ->exists ( 'keep1 ' ) );
187192 $ this ->assertTrue ( $ this ->Storage ->exists ( 'keep2 ' ) );
188193 $ this ->assertTrue ( $ this ->Storage ->exists ( 'expire1 ' ) );
189194 $ this ->assertTrue ( $ this ->Storage ->exists ( 'expire2 ' ) );
190-
191- // Wait for some entries to expire
192- sleep ( 2 );
193-
195+
196+ // Advance time by 2 seconds (instant, no actual sleeping)
197+ $ this -> Clock -> advance ( 2 );
198+
194199 // Run garbage collection
195200 $ Removed = $ this ->Storage ->gc ();
196201 $ this ->assertEquals ( 2 , $ Removed );
197-
202+
198203 // Check that only non-expired entries remain
199204 $ this ->assertTrue ( $ this ->Storage ->exists ( 'keep1 ' ) );
200205 $ this ->assertTrue ( $ this ->Storage ->exists ( 'keep2 ' ) );
@@ -212,9 +217,10 @@ public function testReadExpiredEntry()
212217 {
213218 $ Key = 'test_read_expired ' ;
214219 $ this ->Storage ->write ( $ Key , 'content ' , 1 );
215-
216- sleep ( 2 );
217-
220+
221+ // Advance time by 2 seconds (instant, no actual sleeping)
222+ $ this ->Clock ->advance ( 2 );
223+
218224 // Reading expired entry should return null and delete it
219225 $ this ->assertNull ( $ this ->Storage ->read ( $ Key ) );
220226 $ this ->assertFalse ( $ this ->Storage ->exists ( $ Key ) );
@@ -277,7 +283,7 @@ public function testIsExpiredWithIncompleteMetaData()
277283 ->withContent ( 'content ' );
278284 vfsStream::newFile ( $ Hash . '.meta ' )
279285 ->at ( $ Dir )
280- ->withContent ( json_encode ( [ 'created ' => time () ] ) );
286+ ->withContent ( json_encode ( [ 'created ' => $ this -> Clock -> time () ] ) );
281287
282288 // Should be considered expired if meta data is incomplete
283289 $ this ->assertTrue ( $ this ->Storage ->isExpired ( $ Key ) );
0 commit comments