From bedda644ae54c2b56e05263a7ab86bc1371b2109 Mon Sep 17 00:00:00 2001 From: Michael Dyrynda Date: Wed, 26 Mar 2025 16:57:05 +1030 Subject: [PATCH 1/3] wip: update phpdoc, implement enum key resolution on APC --- src/Illuminate/Cache/ApcStore.php | 22 +++++++++++++++++----- src/Illuminate/Contracts/Cache/Store.php | 12 ++++++------ tests/Cache/CacheApcStoreTest.php | 20 ++++++++++++++++++++ 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/Illuminate/Cache/ApcStore.php b/src/Illuminate/Cache/ApcStore.php index 89c31a3f7f0c..db03d40a9ed6 100755 --- a/src/Illuminate/Cache/ApcStore.php +++ b/src/Illuminate/Cache/ApcStore.php @@ -2,6 +2,8 @@ namespace Illuminate\Cache; +use function Illuminate\Support\enum_value; + class ApcStore extends TaggableStore { use RetrievesMultipleKeys; @@ -35,48 +37,56 @@ public function __construct(ApcWrapper $apc, $prefix = '') /** * Retrieve an item from the cache by key. * - * @param string $key + * @param \BackedEnum|\UnitEnum|string $key * @return mixed */ public function get($key) { + $key = enum_value($key); + return $this->apc->get($this->prefix.$key); } /** * Store an item in the cache for a given number of seconds. * - * @param string $key + * @param \BackedEnum|\UnitEnum|string $key * @param mixed $value * @param int $seconds * @return bool */ public function put($key, $value, $seconds) { + $key = enum_value($key); + return $this->apc->put($this->prefix.$key, $value, $seconds); } /** * Increment the value of an item in the cache. * - * @param string $key + * @param \BackedEnum|\UnitEnum|string $key * @param mixed $value * @return int|bool */ public function increment($key, $value = 1) { + $key = enum_value($key); + return $this->apc->increment($this->prefix.$key, $value); } /** * Decrement the value of an item in the cache. * - * @param string $key + * @param \BackedEnum|\UnitEnum|string $key * @param mixed $value * @return int|bool */ public function decrement($key, $value = 1) { + $key = enum_value($key); + return $this->apc->decrement($this->prefix.$key, $value); } @@ -95,11 +105,13 @@ public function forever($key, $value) /** * Remove an item from the cache. * - * @param string $key + * @param \BackedEnum|\UnitEnum|string $key * @return bool */ public function forget($key) { + $key = enum_value($key); + return $this->apc->delete($this->prefix.$key); } diff --git a/src/Illuminate/Contracts/Cache/Store.php b/src/Illuminate/Contracts/Cache/Store.php index 4ededd4efbc8..bd098b3139e2 100644 --- a/src/Illuminate/Contracts/Cache/Store.php +++ b/src/Illuminate/Contracts/Cache/Store.php @@ -7,7 +7,7 @@ interface Store /** * Retrieve an item from the cache by key. * - * @param string $key + * @param \BackedEnum|\UnitEnum|string $key * @return mixed */ public function get($key); @@ -25,7 +25,7 @@ public function many(array $keys); /** * Store an item in the cache for a given number of seconds. * - * @param string $key + * @param \BackedEnum|\UnitEnum|string $key * @param mixed $value * @param int $seconds * @return bool @@ -44,7 +44,7 @@ public function putMany(array $values, $seconds); /** * Increment the value of an item in the cache. * - * @param string $key + * @param \BackedEnum|\UnitEnum|string $key * @param mixed $value * @return int|bool */ @@ -53,7 +53,7 @@ public function increment($key, $value = 1); /** * Decrement the value of an item in the cache. * - * @param string $key + * @param \BackedEnum|\UnitEnum|string $key * @param mixed $value * @return int|bool */ @@ -62,7 +62,7 @@ public function decrement($key, $value = 1); /** * Store an item in the cache indefinitely. * - * @param string $key + * @param \BackedEnum|\UnitEnum|string $key * @param mixed $value * @return bool */ @@ -71,7 +71,7 @@ public function forever($key, $value); /** * Remove an item from the cache. * - * @param string $key + * @param \BackedEnum|\UnitEnum|string $key * @return bool */ public function forget($key); diff --git a/tests/Cache/CacheApcStoreTest.php b/tests/Cache/CacheApcStoreTest.php index e13d2adf63ec..2ad798ea9a1d 100755 --- a/tests/Cache/CacheApcStoreTest.php +++ b/tests/Cache/CacheApcStoreTest.php @@ -5,10 +5,21 @@ use Illuminate\Cache\ApcStore; use Illuminate\Cache\ApcWrapper; use Mockery; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; class CacheApcStoreTest extends TestCase { + public static function resolveKeyNameDataProvider(): array + { + return [ + 'uses BackedEnum' => [BackedCacheKey::Foo, 'foo'], + 'uses UnitEnum' => [UnitCacheKey::Foo, 'Foo'], + 'uses normal string' => ['foo', 'foo'], + 'uses int' => [100, '100'], + ]; + } + public function testGetReturnsNullWhenNotFound() { $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['get'])->getMock(); @@ -132,4 +143,13 @@ public function testFlushesCached() $result = $store->flush(); $this->assertTrue($result); } + +enum UnitCacheKey +{ + case Foo; +} + +enum BackedCacheKey: string +{ + case Foo = 'foo'; } From 732c85f3654c68e2ba18e32b03bb5fbd7e7ba8f2 Mon Sep 17 00:00:00 2001 From: Michael Dyrynda Date: Wed, 26 Mar 2025 16:58:38 +1030 Subject: [PATCH 2/3] wip: test option 1 - update existing tests with data provider --- tests/Cache/CacheApcStoreTest.php | 49 ++++++++++++++++++------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/tests/Cache/CacheApcStoreTest.php b/tests/Cache/CacheApcStoreTest.php index 2ad798ea9a1d..8833b0ab8e6d 100755 --- a/tests/Cache/CacheApcStoreTest.php +++ b/tests/Cache/CacheApcStoreTest.php @@ -28,20 +28,22 @@ public function testGetReturnsNullWhenNotFound() $this->assertNull($store->get('bar')); } - public function testAPCValueIsReturned() + #[DataProvider('resolveKeyNameDataProvider')] + public function testAPCValueIsReturned(mixed $key, string $expected) { $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['get'])->getMock(); - $apc->expects($this->once())->method('get')->willReturn('bar'); + $apc->expects($this->once())->method('get')->with($this->equalTo($expected))->willReturn('bar'); $store = new ApcStore($apc); - $this->assertSame('bar', $store->get('foo')); + $this->assertSame('bar', $store->get($key)); } - public function testAPCFalseValueIsReturned() + #[DataProvider('resolveKeyNameDataProvider')] + public function testAPCFalseValueIsReturned(mixed $key, string $expected) { $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['get'])->getMock(); - $apc->expects($this->once())->method('get')->willReturn(false); + $apc->expects($this->once())->method('get')->with($this->equalTo($expected))->willReturn(false); $store = new ApcStore($apc); - $this->assertFalse($store->get('foo')); + $this->assertFalse($store->get($key)); } public function testGetMultipleReturnsNullWhenNotFoundAndValueWhenFound() @@ -60,14 +62,15 @@ public function testGetMultipleReturnsNullWhenNotFoundAndValueWhenFound() ], $store->many(['foo', 'bar', 'baz'])); } - public function testSetMethodProperlyCallsAPC() + #[DataProvider('resolveKeyNameDataProvider')] + public function testSetMethodProperlyCallsAPC(mixed $key, string $expected) { $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['put'])->getMock(); $apc->expects($this->once()) - ->method('put')->with($this->equalTo('foo'), $this->equalTo('bar'), $this->equalTo(60)) + ->method('put')->with($this->equalTo($expected), $this->equalTo('bar'), $this->equalTo(60)) ->willReturn(true); $store = new ApcStore($apc); - $result = $store->put('foo', 'bar', 60); + $result = $store->put($key, 'bar', 60); $this->assertTrue($result); } @@ -99,39 +102,43 @@ public function testSetMultipleMethodProperlyCallsAPC() $this->assertTrue($result); } - public function testIncrementMethodProperlyCallsAPC() + #[DataProvider('resolveKeyNameDataProvider')] + public function testIncrementMethodProperlyCallsAPC(mixed $key, string $expected) { $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['increment'])->getMock(); - $apc->expects($this->once())->method('increment')->with($this->equalTo('foo'), $this->equalTo(5)); + $apc->expects($this->once())->method('increment')->with($this->equalTo($expected), $this->equalTo(5)); $store = new ApcStore($apc); - $store->increment('foo', 5); + $store->increment($key, 5); } - public function testDecrementMethodProperlyCallsAPC() + #[DataProvider('resolveKeyNameDataProvider')] + public function testDecrementMethodProperlyCallsAPC(mixed $key, string $expected) { $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['decrement'])->getMock(); - $apc->expects($this->once())->method('decrement')->with($this->equalTo('foo'), $this->equalTo(5)); + $apc->expects($this->once())->method('decrement')->with($this->equalTo($expected), $this->equalTo(5)); $store = new ApcStore($apc); - $store->decrement('foo', 5); + $store->decrement($key, 5); } - public function testStoreItemForeverProperlyCallsAPC() + #[DataProvider('resolveKeyNameDataProvider')] + public function testStoreItemForeverProperlyCallsAPC(mixed $key, string $expected) { $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['put'])->getMock(); $apc->expects($this->once()) - ->method('put')->with($this->equalTo('foo'), $this->equalTo('bar'), $this->equalTo(0)) + ->method('put')->with($this->equalTo($expected), $this->equalTo('bar'), $this->equalTo(0)) ->willReturn(true); $store = new ApcStore($apc); - $result = $store->forever('foo', 'bar'); + $result = $store->forever($key, 'bar'); $this->assertTrue($result); } - public function testForgetMethodProperlyCallsAPC() + #[DataProvider('resolveKeyNameDataProvider')] + public function testForgetMethodProperlyCallsAPC(mixed $key, string $expected) { $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['delete'])->getMock(); - $apc->expects($this->once())->method('delete')->with($this->equalTo('foo'))->willReturn(true); + $apc->expects($this->once())->method('delete')->with($this->equalTo($expected))->willReturn(true); $store = new ApcStore($apc); - $result = $store->forget('foo'); + $result = $store->forget($key); $this->assertTrue($result); } From 5073b37763aa5ef4ffb23aa2a5ec86087c1e2e39 Mon Sep 17 00:00:00 2001 From: Michael Dyrynda Date: Wed, 26 Mar 2025 17:00:25 +1030 Subject: [PATCH 3/3] wip: test option 2 - effectively duplicate the tests with data provider --- tests/Cache/CacheApcStoreTest.php | 62 +++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/tests/Cache/CacheApcStoreTest.php b/tests/Cache/CacheApcStoreTest.php index 8833b0ab8e6d..439bb9d93f5f 100755 --- a/tests/Cache/CacheApcStoreTest.php +++ b/tests/Cache/CacheApcStoreTest.php @@ -151,6 +151,68 @@ public function testFlushesCached() $this->assertTrue($result); } + #[DataProvider('resolveKeyNameDataProvider')] + public function testCanGetWithEnum(mixed $key, string $expected) + { + $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['get'])->getMock(); + $apc->expects($this->once())->method('get')->with($this->equalTo($expected))->willReturn('bar'); + $store = new ApcStore($apc); + $this->assertSame('bar', $store->get($key)); + } + + #[DataProvider('resolveKeyNameDataProvider')] + public function testCanPutWithEnum(mixed $key, string $expected) + { + $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['put'])->getMock(); + $apc->expects($this->once()) + ->method('put')->with($this->equalTo($expected), $this->equalTo('bar'), $this->equalTo(60)) + ->willReturn(true); + $store = new ApcStore($apc); + $result = $store->put($key, 'bar', 60); + $this->assertTrue($result); + } + + #[DataProvider('resolveKeyNameDataProvider')] + public function testCanIncrementWithEnum(mixed $key, string $expected) + { + $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['increment'])->getMock(); + $apc->expects($this->once())->method('increment')->with($this->equalTo($expected), $this->equalTo(5)); + $store = new ApcStore($apc); + $store->increment($key, 5); + } + + #[DataProvider('resolveKeyNameDataProvider')] + public function testCanDecrementWithEnum(mixed $key, string $expected) + { + $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['decrement'])->getMock(); + $apc->expects($this->once())->method('decrement')->with($this->equalTo($expected), $this->equalTo(5)); + $store = new ApcStore($apc); + $store->decrement($key, 5); + } + + #[DataProvider('resolveKeyNameDataProvider')] + public function testCanStoreItemForeverWithEnum(mixed $key, string $expected) + { + $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['put'])->getMock(); + $apc->expects($this->once()) + ->method('put')->with($this->equalTo($expected), $this->equalTo('bar'), $this->equalTo(0)) + ->willReturn(true); + $store = new ApcStore($apc); + $result = $store->forever($key, 'bar'); + $this->assertTrue($result); + } + + #[DataProvider('resolveKeyNameDataProvider')] + public function testCanForgetItemWithEnum(mixed $key, string $expected) + { + $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['delete'])->getMock(); + $apc->expects($this->once())->method('delete')->with($this->equalTo($expected))->willReturn(true); + $store = new ApcStore($apc); + $result = $store->forget($key); + $this->assertTrue($result); + } +} + enum UnitCacheKey { case Foo;