diff --git a/composer.json b/composer.json index e2d93974..300f6674 100644 --- a/composer.json +++ b/composer.json @@ -49,8 +49,8 @@ "laminas/laminas-config-aggregator": "^1.13", "laminas/laminas-serializer": "^3.0", "phpunit/phpunit": "^9.5.27", - "psalm/plugin-phpunit": "^0.18.4", - "vimeo/psalm": "^5.4" + "psalm/plugin-phpunit": "^0.19.0", + "vimeo/psalm": "^5.24" }, "conflict": { "laminas/laminas-serializer": "<3.0", diff --git a/composer.lock b/composer.lock index cdb9f9c6..9dfc5f29 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "417b160225343a49a6aafa33663f098f", + "content-hash": "2e5a0cf0f8f672b8f99d278b13b742cc", "packages": [ { "name": "brick/varexporter", @@ -2563,24 +2563,24 @@ }, { "name": "psalm/plugin-phpunit", - "version": "0.18.4", + "version": "0.19.0", "source": { "type": "git", "url": "https://github.com/psalm/psalm-plugin-phpunit.git", - "reference": "e4ab3096653d9eb6f6d0ea5f4461898d59ae4dbc" + "reference": "e344eaaa27871e79c6cb97b9efe52a735f9d1966" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/psalm/psalm-plugin-phpunit/zipball/e4ab3096653d9eb6f6d0ea5f4461898d59ae4dbc", - "reference": "e4ab3096653d9eb6f6d0ea5f4461898d59ae4dbc", + "url": "https://api.github.com/repos/psalm/psalm-plugin-phpunit/zipball/e344eaaa27871e79c6cb97b9efe52a735f9d1966", + "reference": "e344eaaa27871e79c6cb97b9efe52a735f9d1966", "shasum": "" }, "require": { "composer/package-versions-deprecated": "^1.10", "composer/semver": "^1.4 || ^2.0 || ^3.0", "ext-simplexml": "*", - "php": "^7.1 || ^8.0", - "vimeo/psalm": "dev-master || dev-4.x || ^4.7.1 || ^5@beta || ^5.0" + "php": "^7.4 || ^8.0", + "vimeo/psalm": "dev-master || ^5@beta || ^5.0" }, "conflict": { "phpunit/phpunit": "<7.5" @@ -2617,9 +2617,9 @@ "description": "Psalm plugin for PHPUnit", "support": { "issues": "https://github.com/psalm/psalm-plugin-phpunit/issues", - "source": "https://github.com/psalm/psalm-plugin-phpunit/tree/0.18.4" + "source": "https://github.com/psalm/psalm-plugin-phpunit/tree/0.19.0" }, - "time": "2022-12-03T07:47:07+00:00" + "time": "2024-03-15T10:43:15+00:00" }, { "name": "psr/event-dispatcher", diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 853abaaf..b6ddec79 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,5 +1,5 @@ - + @@ -119,11 +119,6 @@ - - - - - @@ -460,10 +455,6 @@ - - - - @@ -499,18 +490,6 @@ - - - - - - - - - - - - @@ -518,24 +497,6 @@ - - - - - - - - - - - - - - - - - - diff --git a/src/Psr/CacheItemPool/CacheItemPoolDecorator.php b/src/Psr/CacheItemPool/CacheItemPoolDecorator.php index dd41210d..22641b9c 100644 --- a/src/Psr/CacheItemPool/CacheItemPoolDecorator.php +++ b/src/Psr/CacheItemPool/CacheItemPoolDecorator.php @@ -129,7 +129,7 @@ public function getItems(array $keys = []): array } foreach ($cacheItems as $key => $value) { - $items[$key] = new CacheItem($key, $value, true, $this->clock); + $items[$key] = new CacheItem((string) $key, $value, true, $this->clock); } // Return empty items for any keys that where not found diff --git a/src/Psr/SimpleCache/SimpleCacheDecorator.php b/src/Psr/SimpleCache/SimpleCacheDecorator.php index ab1e3bf7..27b6e5b1 100644 --- a/src/Psr/SimpleCache/SimpleCacheDecorator.php +++ b/src/Psr/SimpleCache/SimpleCacheDecorator.php @@ -247,7 +247,7 @@ public function setMultiple(iterable $values, int|DateInterval|null $ttl = null) } foreach ($result as $index => $key) { - if (! $this->storage->hasItem($key)) { + if (! $this->storage->hasItem((string) $key)) { unset($result[$index]); } } @@ -276,7 +276,7 @@ public function deleteMultiple(iterable $keys): bool } foreach ($result as $index => $key) { - if (! $this->storage->hasItem($key)) { + if (! $this->storage->hasItem((string) $key)) { unset($result[$index]); } } diff --git a/src/Storage/AbstractMetadataCapableAdapter.php b/src/Storage/AbstractMetadataCapableAdapter.php index 8770ef36..24fadbb5 100644 --- a/src/Storage/AbstractMetadataCapableAdapter.php +++ b/src/Storage/AbstractMetadataCapableAdapter.php @@ -132,15 +132,15 @@ public function getMetadatas(array $keys): array /** * Internal method to get multiple metadata * - * @param array $normalizedKeys - * @return array Associative array of keys and metadata + * @param array $normalizedKeys + * @return array Associative array of keys and metadata * @throws ExceptionInterface */ protected function internalGetMetadatas(array $normalizedKeys): array { $result = []; foreach ($normalizedKeys as $normalizedKey) { - $metadata = $this->internalGetMetadata($normalizedKey); + $metadata = $this->internalGetMetadata((string) $normalizedKey); if ($metadata === null) { continue; } diff --git a/src/Storage/Adapter/AbstractAdapter.php b/src/Storage/Adapter/AbstractAdapter.php index 8daa1488..84c82519 100644 --- a/src/Storage/Adapter/AbstractAdapter.php +++ b/src/Storage/Adapter/AbstractAdapter.php @@ -24,6 +24,7 @@ use function array_values; use function func_num_args; use function is_array; +use function is_int; use function is_string; use function preg_match; use function sprintf; @@ -73,6 +74,15 @@ public function __construct(iterable|AdapterOptions|null $options = null) } } + /** + * @psalm-assert list $result + */ + private function assertListOfKeys(mixed $result): void + { + Assert::isList($result); + $this->assertValidKeys($result); + } + /** * Destructor * @@ -329,7 +339,7 @@ public function getItem(string $key, ?bool &$success = null, mixed &$casToken = try { $eventRs = $this->triggerPre(__FUNCTION__, $args); $key = $args['key']; - $this->assertValidKey($key); + Assert::stringNotEmpty($key); if ($eventRs->stopped()) { $result = $eventRs->last(); @@ -372,11 +382,8 @@ abstract protected function internalGetItem( ): mixed; /** - * Get multiple items. + * {@inheritDoc} * - * @param non-empty-list $keys - * @return array Associative array of keys and values - * @throws Exception\ExceptionInterface * @triggers getItems.pre(PreEvent) * @triggers getItems.post(PostEvent) * @triggers getItems.exception(ExceptionEvent) @@ -418,8 +425,8 @@ public function getItems(array $keys): array /** * Internal method to get multiple items. * - * @param non-empty-list $normalizedKeys - * @return array Associative array of keys and values + * @param non-empty-list $normalizedKeys + * @return array Associative array of keys and values * @throws Exception\ExceptionInterface */ protected function internalGetItems(array $normalizedKeys): array @@ -427,7 +434,7 @@ protected function internalGetItems(array $normalizedKeys): array $success = null; $result = []; foreach ($normalizedKeys as $normalizedKey) { - $value = $this->internalGetItem($normalizedKey, $success); + $value = $this->internalGetItem((string) $normalizedKey, $success); if ($success) { $result[$normalizedKey] = $value; } @@ -486,11 +493,8 @@ protected function internalHasItem(string $normalizedKey): bool } /** - * Test multiple items. + * {@inheritDoc} * - * @param non-empty-list $keys - * @return list Array of found keys - * @throws Exception\ExceptionInterface * @triggers hasItems.pre(PreEvent) * @triggers hasItems.post(PostEvent) * @triggers hasItems.exception(ExceptionEvent) @@ -518,24 +522,22 @@ public function hasItems(array $keys): array $result = $this->triggerThrowable(__FUNCTION__, $args, [], $throwable); } - Assert::isList($result); - Assert::allStringNotEmpty($result); - + self::assertListOfKeys($result); return $result; } /** * Internal method to test multiple items. * - * @param non-empty-list $normalizedKeys - * @return list Array of found keys + * @param non-empty-list $normalizedKeys + * @return list Array of found keys * @throws Exception\ExceptionInterface */ protected function internalHasItems(array $normalizedKeys): array { $result = []; foreach ($normalizedKeys as $normalizedKey) { - if ($this->internalHasItem($normalizedKey)) { + if ($this->internalHasItem((string) $normalizedKey)) { $result[] = $normalizedKey; } } @@ -590,11 +592,8 @@ public function setItem(string $key, mixed $value): bool abstract protected function internalSetItem(string $normalizedKey, mixed $value): bool; /** - * Store multiple items. + * {@inheritDoc} * - * @param array $keyValuePairs - * @return list Array of not stored keys - * @throws Exception\ExceptionInterface * @triggers setItems.pre(PreEvent) * @triggers setItems.post(PostEvent) * @triggers setItems.exception(ExceptionEvent) @@ -624,8 +623,7 @@ public function setItems(array $keyValuePairs): array $result = $this->triggerThrowable(__FUNCTION__, $args, array_keys($keyValuePairs), $throwable); } - Assert::isList($result); - Assert::allStringNotEmpty($result); + $this->assertListOfKeys($result); return $result; } @@ -703,11 +701,8 @@ protected function internalAddItem(string $normalizedKey, mixed $value): bool } /** - * Add multiple items. + * {@inheritDoc} * - * @param array $keyValuePairs - * @return list Array of not stored keys - * @throws Exception\ExceptionInterface * @triggers addItems.pre(PreEvent) * @triggers addItems.post(PostEvent) * @triggers addItems.exception(ExceptionEvent) @@ -816,11 +811,8 @@ protected function internalReplaceItem(string $normalizedKey, mixed $value): boo } /** - * Replace multiple existing items. + * {@inheritDoc} * - * @param array $keyValuePairs - * @return list Array of not stored keys - * @throws Exception\ExceptionInterface * @triggers replaceItems.pre(PreEvent) * @triggers replaceItems.post(PostEvent) * @triggers replaceItems.exception(ExceptionEvent) @@ -848,8 +840,7 @@ public function replaceItems(array $keyValuePairs): array $result = $this->triggerThrowable(__FUNCTION__, $args, array_keys($keyValuePairs), $throwable); } - Assert::isList($result); - Assert::allStringNotEmpty($result); + $this->assertListOfKeys($result); return $result; } @@ -984,11 +975,8 @@ protected function internalTouchItem(string $normalizedKey): bool } /** - * Reset lifetime of multiple items. + * {@inheritDoc} * - * @param non-empty-list $keys - * @return list Array of not updated keys - * @throws Exception\ExceptionInterface * @triggers touchItems.pre(PreEvent) * @triggers touchItems.post(PostEvent) * @triggers touchItems.exception(ExceptionEvent) @@ -1012,13 +1000,11 @@ public function touchItems(array $keys): array : $this->internalTouchItems($args['keys']); $result = $this->triggerPost(__FUNCTION__, $args, $result); - Assert::isList($result); - Assert::allStringNotEmpty($result); + $this->assertListOfKeys($result); return $result; } catch (Throwable $throwable) { $result = $this->triggerThrowable(__FUNCTION__, $args, $keys, $throwable); - Assert::isList($result); - Assert::allStringNotEmpty($result); + $this->assertListOfKeys($result); return $result; } } @@ -1026,15 +1012,15 @@ public function touchItems(array $keys): array /** * Internal method to reset lifetime of multiple items. * - * @param non-empty-list $normalizedKeys - * @return list Array of not updated keys + * @param non-empty-list $normalizedKeys + * @return list Array of not updated keys * @throws Exception\ExceptionInterface */ protected function internalTouchItems(array $normalizedKeys): array { $result = []; foreach ($normalizedKeys as $normalizedKey) { - if (! $this->internalTouchItem($normalizedKey)) { + if (! $this->internalTouchItem((string) $normalizedKey)) { $result[] = $normalizedKey; } } @@ -1089,11 +1075,8 @@ public function removeItem(string $key): bool abstract protected function internalRemoveItem(string $normalizedKey): bool; /** - * Remove multiple items. + * {@inheritDoc} * - * @param non-empty-list $keys - * @return list Array of not removed keys - * @throws Exception\ExceptionInterface * @triggers removeItems.pre(PreEvent) * @triggers removeItems.post(PostEvent) * @triggers removeItems.exception(ExceptionEvent) @@ -1133,15 +1116,15 @@ public function removeItems(array $keys): array /** * Internal method to remove multiple items. * - * @param non-empty-list $normalizedKeys - * @return list Array of not removed keys + * @param non-empty-list $normalizedKeys + * @return list Array of not removed keys * @throws Exception\ExceptionInterface */ protected function internalRemoveItems(array $normalizedKeys): array { $result = []; foreach ($normalizedKeys as $normalizedKey) { - if (! $this->internalRemoveItem($normalizedKey)) { + if (! $this->internalRemoveItem((string) $normalizedKey)) { $result[] = $normalizedKey; } } @@ -1207,8 +1190,8 @@ protected function normalizeKey(string $key): void /** * Validates and normalizes multiple keys * - * @param non-empty-list $keys - * @return non-empty-list $keys + * @param non-empty-list $keys + * @return non-empty-list $keys * @throws Exception\InvalidArgumentException On an invalid key. */ protected function normalizeKeys(array $keys): array @@ -1235,13 +1218,15 @@ protected function normalizeKeyValuePairs(array $keyValuePairs): void } /** - * @psalm-assert non-empty-string $key + * @template TKey + * @param TKey $key + * @psalm-assert (TKey is string ? non-empty-string : non-empty-string|int) $key */ protected function assertValidKey(mixed $key): void { - if (! is_string($key)) { + if (! is_int($key) && ! is_string($key)) { throw new Exception\InvalidArgumentException( - "Key has to be string" + "Key has to be either string or int" ); } @@ -1251,6 +1236,8 @@ protected function assertValidKey(mixed $key): void ); } + $key = (string) $key; + $pattern = $this->getOptions()->getKeyPattern(); if ($pattern !== '' && ! preg_match($pattern, $key)) { throw new Exception\InvalidArgumentException( @@ -1282,4 +1269,14 @@ protected function assertValidKeyValuePairs(mixed $keyValuePairs): void $this->assertValidKey($key); } } + + /** + * @psalm-assert list $keys + */ + private function assertValidKeys(array $keys): void + { + foreach ($keys as $key) { + $this->assertValidKey($key); + } + } } diff --git a/src/Storage/StorageInterface.php b/src/Storage/StorageInterface.php index 8eb5d7fc..b3bb5ec2 100644 --- a/src/Storage/StorageInterface.php +++ b/src/Storage/StorageInterface.php @@ -4,22 +4,20 @@ use Laminas\Cache\Exception\ExceptionInterface; +/** + * NOTE: when providing integrish cache keys in iterables, internal array conversion might convert these to int, even + * tho they were non-empty-string beforehand. See https://3v4l.org/GsiBl for more details. + * + * @psalm-type CacheKeyInIterableType = non-empty-string|int + */ interface StorageInterface { - /** - * Set options. - */ public function setOptions(iterable|Adapter\AdapterOptions $options): self; - /** - * Get options - */ public function getOptions(): Adapter\AdapterOptions; /* reading */ /** - * Get an item. - * * @param non-empty-string $key * @param-out bool $success * @return mixed Data on success, null on failure @@ -30,8 +28,8 @@ public function getItem(string $key, bool|null &$success = null, mixed &$casToke /** * Get multiple items. * - * @param non-empty-list $keys - * @return array Associative array of keys and values + * @param non-empty-list $keys + * @return array Associative array of keys and values * @throws ExceptionInterface */ public function getItems(array $keys): array; @@ -47,8 +45,8 @@ public function hasItem(string $key): bool; /** * Test multiple items. * - * @param non-empty-list $keys - * @return list Array of found keys + * @param non-empty-list $keys + * @return list Array of found keys * @throws ExceptionInterface */ public function hasItems(array $keys): array; @@ -65,8 +63,8 @@ public function setItem(string $key, mixed $value): bool; /** * Store multiple items. * - * @param non-empty-array $keyValuePairs - * @return list Array of not stored keys + * @param non-empty-array $keyValuePairs + * @return list Array of not stored keys * @throws ExceptionInterface */ public function setItems(array $keyValuePairs): array; @@ -74,6 +72,7 @@ public function setItems(array $keyValuePairs): array; /** * Add an item. * + * @param non-empty-string $key * @throws ExceptionInterface */ public function addItem(string $key, mixed $value): bool; @@ -81,8 +80,8 @@ public function addItem(string $key, mixed $value): bool; /** * Add multiple items. * - * @param non-empty-array $keyValuePairs - * @return list Array of not stored keys + * @param non-empty-array $keyValuePairs + * @return list Array of not stored keys * @throws ExceptionInterface */ public function addItems(array $keyValuePairs): array; @@ -98,8 +97,8 @@ public function replaceItem(string $key, mixed $value): bool; /** * Replace multiple existing items. * - * @param non-empty-array $keyValuePairs - * @return list Array of not stored keys + * @param non-empty-array $keyValuePairs + * @return list Array of not stored keys * @throws ExceptionInterface */ public function replaceItems(array $keyValuePairs): array; @@ -130,8 +129,8 @@ public function touchItem(string $key): bool; /** * Reset lifetime of multiple items. * - * @param non-empty-list $keys - * @return list Array of not updated keys + * @param non-empty-list $keys + * @return list Array of not updated keys * @throws ExceptionInterface */ public function touchItems(array $keys): array; @@ -147,8 +146,8 @@ public function removeItem(string $key): bool; /** * Remove multiple items. * - * @param non-empty-list $keys - * @return list Array of not removed keys + * @param non-empty-list $keys + * @return list Array of not removed keys * @throws ExceptionInterface */ public function removeItems(array $keys): array; diff --git a/test/Psr/SimpleCache/SimpleCacheDecoratorTest.php b/test/Psr/SimpleCache/SimpleCacheDecoratorTest.php index c4c0698e..7ca493d2 100644 --- a/test/Psr/SimpleCache/SimpleCacheDecoratorTest.php +++ b/test/Psr/SimpleCache/SimpleCacheDecoratorTest.php @@ -128,9 +128,9 @@ public function setSuccessReference(SimpleCacheDecorator $cache, bool $success): * Set of string key names that should be considered invalid for operations * that create cache entries. * - * @return array + * @return non-empty-array */ - public function invalidKeyProvider() + public function invalidKeyProvider(): array { return [ 'brace-start' => ['key{', 'cannot contain'], @@ -148,9 +148,9 @@ public function invalidKeyProvider() /** * TTL values less than 1 should result in immediate cache removal. * - * @return array + * @return non-empty-array */ - public function invalidatingTtls() + public function invalidatingTtls(): array { return [ 'zero' => [0], diff --git a/test/Storage/Adapter/AbstractAdapterTest.php b/test/Storage/Adapter/AbstractAdapterTest.php index 81c87f62..4447786d 100644 --- a/test/Storage/Adapter/AbstractAdapterTest.php +++ b/test/Storage/Adapter/AbstractAdapterTest.php @@ -7,7 +7,6 @@ use ArrayObject; use Laminas\Cache; use Laminas\Cache\Exception; -use Laminas\Cache\Exception\InvalidArgumentException; use Laminas\Cache\Exception\RuntimeException; use Laminas\Cache\Storage\Adapter\AbstractAdapter; use Laminas\Cache\Storage\Adapter\AdapterOptions; @@ -19,6 +18,7 @@ use Laminas\EventManager\ResponseCollection; use Laminas\Serializer\AdapterPluginManager; use Laminas\ServiceManager\ServiceManager; +use LaminasTest\Cache\Storage\TestAsset\MockAdapter; use LaminasTest\Cache\Storage\TestAsset\MockPlugin; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -56,72 +56,6 @@ public function testGetOptions(): void self::assertIsString($options->getKeyPattern()); } - public function testSetWritable(): void - { - $this->options->setWritable(true); - self::assertTrue($this->options->getWritable()); - - $this->options->setWritable(false); - self::assertFalse($this->options->getWritable()); - } - - public function testSetReadable(): void - { - $this->options->setReadable(true); - self::assertTrue($this->options->getReadable()); - - $this->options->setReadable(false); - self::assertFalse($this->options->getReadable()); - } - - public function testSetTtl(): void - { - $this->options->setTtl('123'); - self::assertSame(123, $this->options->getTtl()); - } - - public function testSetTtlThrowsInvalidArgumentException(): void - { - $this->expectException(InvalidArgumentException::class); - $this->options->setTtl(-1); - } - - public function testGetDefaultNamespaceNotEmpty(): void - { - $ns = $this->options->getNamespace(); - self::assertNotEmpty($ns); - } - - public function testSetNamespace(): void - { - $this->options->setNamespace('new_namespace'); - self::assertSame('new_namespace', $this->options->getNamespace()); - } - - public function testSetNamespace0(): void - { - $this->options->setNamespace('0'); - self::assertSame('0', $this->options->getNamespace()); - } - - public function testSetKeyPattern(): void - { - $this->options->setKeyPattern('/^[key]+$/Di'); - self::assertEquals('/^[key]+$/Di', $this->options->getKeyPattern()); - } - - public function testUnsetKeyPattern(): void - { - $this->options->setKeyPattern(''); - self::assertSame('', $this->options->getKeyPattern()); - } - - public function testSetKeyPatternThrowsExceptionOnInvalidPattern(): void - { - $this->expectException(InvalidArgumentException::class); - $this->options->setKeyPattern('#'); - } - public function testPluginRegistry(): void { $storage = $this->getMockForAbstractAdapter(); @@ -867,4 +801,17 @@ public function testCanCompareOldValueWithTokenWhenUsedWithSerializerPlugin(): v self::assertTrue($storage->checkAndSetItem('bar', 'foo', 'baz')); } + + public function testCanHandleIntegerishKeysInIterables(): void + { + $storage = new MockAdapter(); + $keyValuePair = ['0' => '0']; + self::assertSame([], $storage->setItems($keyValuePair)); + self::assertSame([], $storage->addItems($keyValuePair)); + self::assertSame([0], $storage->replaceItems($keyValuePair)); + self::assertSame([], $storage->removeItems(array_keys($keyValuePair))); + self::assertSame([], $storage->getItems(array_keys($keyValuePair))); + self::assertSame([], $storage->hasItems(array_keys($keyValuePair))); + self::assertSame([0], $storage->touchItems(array_keys($keyValuePair))); + } } diff --git a/test/Storage/Adapter/AdapterOptionsTest.php b/test/Storage/Adapter/AdapterOptionsTest.php index f10b090b..d2a3d3c2 100644 --- a/test/Storage/Adapter/AdapterOptionsTest.php +++ b/test/Storage/Adapter/AdapterOptionsTest.php @@ -5,10 +5,10 @@ namespace LaminasTest\Cache\Storage\Adapter; use Laminas\Cache\Exception; +use Laminas\Cache\Exception\InvalidArgumentException; use Laminas\Cache\Storage\Adapter\AbstractAdapter; use Laminas\Cache\Storage\Adapter\AdapterOptions; use Laminas\Cache\Storage\Event; -use Laminas\Cache\Storage\StorageInterface; use LaminasTest\Cache\Storage\Adapter\TestAsset\AdapterOptionsWithPrioritizedOptions; use PHPUnit\Framework\TestCase; @@ -20,25 +20,79 @@ */ class AdapterOptionsTest extends TestCase { - /** - * Mock of the storage - * - * @var StorageInterface - */ - protected $storage; - - /** - * Adapter options - * - * @var null|AdapterOptions - */ - protected $options; + protected AdapterOptions $options; public function setUp(): void { $this->options = new AdapterOptions(); } + public function testSetWritable(): void + { + $this->options->setWritable(true); + self::assertTrue($this->options->getWritable()); + + $this->options->setWritable(false); + self::assertFalse($this->options->getWritable()); + } + + public function testSetReadable(): void + { + $this->options->setReadable(true); + self::assertTrue($this->options->getReadable()); + + $this->options->setReadable(false); + self::assertFalse($this->options->getReadable()); + } + + public function testSetTtl(): void + { + $this->options->setTtl('123'); + self::assertSame(123, $this->options->getTtl()); + } + + public function testSetTtlThrowsInvalidArgumentException(): void + { + $this->expectException(InvalidArgumentException::class); + $this->options->setTtl(-1); + } + + public function testGetDefaultNamespaceNotEmpty(): void + { + $ns = $this->options->getNamespace(); + self::assertNotEmpty($ns); + } + + public function testSetNamespace(): void + { + $this->options->setNamespace('new_namespace'); + self::assertSame('new_namespace', $this->options->getNamespace()); + } + + public function testSetNamespace0(): void + { + $this->options->setNamespace('0'); + self::assertSame('0', $this->options->getNamespace()); + } + + public function testSetKeyPattern(): void + { + $this->options->setKeyPattern('/^[key]+$/Di'); + self::assertEquals('/^[key]+$/Di', $this->options->getKeyPattern()); + } + + public function testUnsetKeyPattern(): void + { + $this->options->setKeyPattern(''); + self::assertSame('', $this->options->getKeyPattern()); + } + + public function testSetKeyPatternThrowsExceptionOnInvalidPattern(): void + { + $this->expectException(InvalidArgumentException::class); + $this->options->setKeyPattern('#'); + } + public function testKeyPattern(): void { // test default value diff --git a/test/Storage/TestAsset/MockAdapter.php b/test/Storage/TestAsset/MockAdapter.php index f126fd0f..9dd63de5 100644 --- a/test/Storage/TestAsset/MockAdapter.php +++ b/test/Storage/TestAsset/MockAdapter.php @@ -15,6 +15,7 @@ class MockAdapter extends AbstractAdapter { protected function internalGetItem(string $normalizedKey, ?bool &$success = null, mixed &$casToken = null): mixed { + $success = false; return null; }