From 1c89a0280b20fbb259c38480ffad075a44973165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gamez?= Date: Sat, 2 Mar 2024 00:41:27 +0100 Subject: [PATCH] Allow using the library without providing a PSR-20 clock implementation --- CHANGELOG.md | 3 +++ README.md | 25 +++++++++++++++++++++---- composer.json | 6 ++++-- src/InMemoryCache.php | 15 +++++++++++++-- tests/InMemoryCacheTest.php | 14 ++++++++++++++ 5 files changed, 55 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a33f87..9e1e45a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## [Unreleased] +* The Cache can now be instantiated without providing a [PSR-20](https://www.php-fig.org/psr/psr-20/) clock implementation. +* The library doesn't depend on the [`beste/clock` library](https://github.com/beste/clock) anymore. + ## [1.0.0] - 2023-12-09 Initial Release diff --git a/README.md b/README.md index 95f5519..10d9237 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,8 @@ composer require beste/in-memory-cache beste/clock ```php use Beste\Cache\InMemoryCache; -use Beste\Clock\SystemClock; -$clock = SystemClock::create(); -$cache = new InMemoryCache($clock); +$cache = new InMemoryCache(); $item = $cache->getItem('key'); @@ -42,7 +40,26 @@ assert($item->isHit() === true); assert($item->get() === 'value'); ``` -The test suite +You can also provide your own [PSR-20](https://www.php-fig.org/psr/psr-20/) clock implementation, for example a frozen +clock for testing, for example from the [`beste/clock` library](https://github.com/beste/clock). + +```php +use Beste\Clock\FrozenClock; +use Beste\Cache\InMemoryCache; + +$clock = FrozenClock::fromUTC() +$cache = new InMemoryCache(); + +$item = $cache->getItem('key'); +$item->set('value')->expiresAfter(new DateInterval('PT5M')); +$cache->save($item); + +$clock->setTo($clock->now()->add(new DateInterval('PT2M'))); +assert($cache->getItem('key')->isHit() === true); + +$clock->setTo($clock->now()->add(new DateInterval('PT5M'))); +assert($cache->getItem('key')->isHit() === false); +``` ## Running tests diff --git a/composer.json b/composer.json index a1622ec..4ca9255 100644 --- a/composer.json +++ b/composer.json @@ -13,8 +13,7 @@ "require": { "php": "~8.1.0 || ~8.2.0 || ~8.3.0", "psr/cache": "^2.0 || ^3.0", - "psr/clock": "^1.0", - "psr/clock-implementation": "^1.0" + "psr/clock": "^1.0" }, "require-dev": { "beste/clock": "^3.0", @@ -30,6 +29,9 @@ "provide": { "psr/cache-implementation": "2.0 || 3.0" }, + "suggest": { + "psr/clock-implementation": "Allows injecting a Clock, for example a frozen clock for testing" + }, "autoload": { "psr-4": { "Beste\\Cache\\": "src" diff --git a/src/InMemoryCache.php b/src/InMemoryCache.php index 1035093..9ed1dc6 100644 --- a/src/InMemoryCache.php +++ b/src/InMemoryCache.php @@ -2,19 +2,30 @@ namespace Beste\Cache; +use DateTimeImmutable; use Psr\Cache\CacheItemInterface; use Psr\Cache\CacheItemPoolInterface; use Psr\Clock\ClockInterface; final class InMemoryCache implements CacheItemPoolInterface { + private readonly ClockInterface $clock; + /** @var array */ private array $items; /** @var array */ private array $deferredItems; - public function __construct(private readonly ClockInterface $clock) - { + public function __construct( + ClockInterface $clock = null + ) { + $this->clock = $clock ?? new class () implements ClockInterface { + public function now(): DateTimeImmutable + { + return new DateTimeImmutable(); + } + + }; $this->items = []; $this->deferredItems = []; } diff --git a/tests/InMemoryCacheTest.php b/tests/InMemoryCacheTest.php index d7f3609..81e7db3 100644 --- a/tests/InMemoryCacheTest.php +++ b/tests/InMemoryCacheTest.php @@ -20,6 +20,20 @@ protected function setUp(): void $this->pool = new InMemoryCache($this->clock); } + public function testItWorksWithouProvidingAClock(): void + { + $pool = new InMemoryCache(); + $item = $pool->getItem('item'); + + self::assertFalse($item->isHit()); + + $item->set('value'); + $pool->save($item); + + $item = $pool->getItem('item'); + self::assertTrue($item->isHit()); + } + public function testItReturnsANewItem(): void { $item = $this->pool->getItem('item');