From dcd68ed8a0296d79815a52cc723a5bb59fee4e69 Mon Sep 17 00:00:00 2001 From: Hans Erik Jepsen Date: Wed, 24 Aug 2022 14:47:20 +0200 Subject: [PATCH] Upgrade to simple cache 2 & 3 (#11) * Updated PHP requirement to >=8.0 and replaced test versions with 8.0 & 8.1 * Updated codeception to ^5 * Updated simple-cache to ^2||^3 * Removed mindplay/simple-cache dev-dependency * Updated FileCache::get signature * Updated FileCache::set signature * Updated FileCache::delete signature * Updated FileCache::clear signature * Updated FileCache::getMultiple signature * Updated FileCache::setMultiple signature * Updated FileCache::deleteMultiple signature * Updated FileCache::has signature * Changed expected throwables from `InvalidArgumentException` to `TypeError` where necessary * Removed unnecessary throw statements, these errors will be caught by PHPs type checks * Updated FileCacheIntegrationTest to resolve errors produced by the new typehints * Removed mindplay/simple-cache dev-dependency * Replaced Travis with Github Actions --- composer.json | 2 +- src/FileCache.php | 38 ++-- tests/integration/FileCacheCest.php | 7 +- .../integration/FileCacheIntegrationTest.php | 170 +++++++++++++++++- 4 files changed, 184 insertions(+), 33 deletions(-) diff --git a/composer.json b/composer.json index 9c7907e..a729427 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ }, "require": { "php": ">= 8.0", - "psr/simple-cache": "^1" + "psr/simple-cache": "^2||^3" }, "require-dev": { "codeception/codeception": "^5", diff --git a/src/FileCache.php b/src/FileCache.php index 83ccdac..ef8b5cc 100644 --- a/src/FileCache.php +++ b/src/FileCache.php @@ -1,17 +1,15 @@ cache_path = $path; } - public function get($key, $default = null) + public function get(string $key, mixed $default = null): mixed { $path = $this->getPath($key); @@ -109,7 +109,7 @@ public function get($key, $default = null) return $value; } - public function set($key, $value, $ttl = null) + public function set(string $key, mixed $value, DateInterval|int|null $ttl = null): bool { $path = $this->getPath($key); @@ -125,7 +125,7 @@ public function set($key, $value, $ttl = null) if (is_int($ttl)) { $expires_at = $this->getTime() + $ttl; } elseif ($ttl instanceof DateInterval) { - $expires_at = date_create_from_format("U", $this->getTime())->add($ttl)->getTimestamp(); + $expires_at = date_create_from_format("U", (string) $this->getTime())->add($ttl)->getTimestamp(); } elseif ($ttl === null) { $expires_at = $this->getTime() + $this->default_ttl; } else { @@ -149,7 +149,7 @@ public function set($key, $value, $ttl = null) return false; } - public function delete($key) + public function delete(string $key): bool { $this->validateKey($key); @@ -158,7 +158,7 @@ public function delete($key) return !file_exists($path) || @unlink($path); } - public function clear() + public function clear(): bool { $success = true; @@ -173,12 +173,8 @@ public function clear() return $success; } - public function getMultiple($keys, $default = null) + public function getMultiple(iterable $keys, mixed $default = null): iterable { - if (! is_array($keys) && ! $keys instanceof Traversable) { - throw new InvalidArgumentException("keys must be either of type array or Traversable"); - } - $values = []; foreach ($keys as $key) { @@ -188,12 +184,8 @@ public function getMultiple($keys, $default = null) return $values; } - public function setMultiple($values, $ttl = null) + public function setMultiple(iterable $values, DateInterval|int|null $ttl = null): bool { - if (! is_array($values) && ! $values instanceof Traversable) { - throw new InvalidArgumentException("keys must be either of type array or Traversable"); - } - $ok = true; foreach ($values as $key => $value) { @@ -209,12 +201,8 @@ public function setMultiple($values, $ttl = null) return $ok; } - public function deleteMultiple($keys) + public function deleteMultiple(iterable $keys): bool { - if (! is_array($keys) && ! $keys instanceof Traversable) { - throw new InvalidArgumentException("keys must be either of type array or Traversable"); - } - $ok = true; foreach ($keys as $key) { @@ -226,7 +214,7 @@ public function deleteMultiple($keys) return $ok; } - public function has($key) + public function has(string $key): bool { return $this->get($key, $this) !== $this; } diff --git a/tests/integration/FileCacheCest.php b/tests/integration/FileCacheCest.php index 6eed661..d94d996 100644 --- a/tests/integration/FileCacheCest.php +++ b/tests/integration/FileCacheCest.php @@ -7,6 +7,7 @@ use IntegrationTester; use Kodus\Cache\InvalidArgumentException; use Kodus\Cache\Test\TestableFileCache; +use TypeError; class FileCacheCest { @@ -187,11 +188,11 @@ public function testGetAndSetMultiple(IntegrationTester $I) $I->assertSame(["key1" => "value1", "key2" => "value2", "key3" => false], $results); - $I->expectThrowable(InvalidArgumentException::class, function () { + $I->expectThrowable(TypeError::class, function () { $this->cache->getMultiple("Invalid type"); }); - $I->expectThrowable(InvalidArgumentException::class, function () { + $I->expectThrowable(TypeError::class, function () { $this->cache->setMultiple("Invalid type"); }); @@ -214,7 +215,7 @@ public function testDeleteMultiple(IntegrationTester $I) $I->assertSame("value3", $this->cache->get("key3")); - $I->expectThrowable(InvalidArgumentException::class, function () { + $I->expectThrowable(TypeError::class, function () { $this->cache->deleteMultiple("Invalid type"); }); diff --git a/tests/integration/FileCacheIntegrationTest.php b/tests/integration/FileCacheIntegrationTest.php index 9361ce9..39d6c0e 100644 --- a/tests/integration/FileCacheIntegrationTest.php +++ b/tests/integration/FileCacheIntegrationTest.php @@ -1,14 +1,13 @@ 'New simple-cache v3 type hints break the test. FileCacheIntegrationTest contains updated versions.', + 'testGetMultipleInvalidKeys' => 'New simple-cache v3 type hints break the test. FileCacheIntegrationTest contains updated versions.', + 'testSetInvalidKeys' => 'New simple-cache v3 type hints break the test. FileCacheIntegrationTest contains updated versions.', + 'testHasInvalidKeys' => 'New simple-cache v3 type hints break the test. FileCacheIntegrationTest contains updated versions.', + 'testDeleteInvalidKeys' => 'New simple-cache v3 type hints break the test. FileCacheIntegrationTest contains updated versions.', + ]; + public function createSimpleCache() { $path = dirname(__DIR__) . "/_output/cache"; @@ -30,4 +37,159 @@ public function createSimpleCache() return $cache; } + + /** + * @dataProvider invalidStringKeys + */ + public function testGetInvalidStringKeys($key) + { + $this->expectException('Psr\SimpleCache\InvalidArgumentException'); + $this->cache->get($key); + } + + /** + * @dataProvider invalidNonStringKeys + */ + public function testGetInvalidNonStringKeys($key) + { + $this->expectException(TypeError::class); + $this->cache->get($key); + } + + /** + * @dataProvider invalidStringKeys + */ + public function testGetMultipleInvalidStringKeys($key) + { + $this->expectException('Psr\SimpleCache\InvalidArgumentException'); + $this->cache->getMultiple(['key1', $key, 'key2']); + } + + /** + * @dataProvider invalidNonStringKeys + */ + public function testGetMultipleInvalidNonStringKeys($key) + { + $this->expectException(TypeError::class); + $this->cache->getMultiple(['key1', $key, 'key2']); + } + + public function testGetMultipleNoIterable() + { + $this->expectException(TypeError::class); + $this->cache->getMultiple('key'); + } + + /** + * @dataProvider invalidStringKeys + */ + public function testSetInvalidStringKeys($key) + { + $this->expectException('Psr\SimpleCache\InvalidArgumentException'); + $this->cache->set($key, 'foobar'); + } + + /** + * @dataProvider invalidNonStringKeys + */ + public function testSetInvalidNonStringKeys($key) + { + $this->expectException(TypeError::class); + $this->cache->set($key, 'foobar'); + } + + public function testSetMultipleNoIterable() + { + $this->expectException(TypeError::class); + $this->cache->setMultiple('key'); + } + + /** + * @dataProvider invalidStringKeys + */ + public function testHasInvalidStringKeys($key) + { + $this->expectException('Psr\SimpleCache\InvalidArgumentException'); + $this->cache->has($key); + } + /** + * @dataProvider invalidNonStringKeys + */ + public function testHasInvalidNonStringKeys($key) + { + $this->expectException(TypeError::class); + $this->cache->has($key); + } + + /** + * @dataProvider invalidStringKeys + */ + public function testDeleteInvalidStringKeys($key) + { + $this->expectException('Psr\SimpleCache\InvalidArgumentException'); + $this->cache->delete($key); + } + + /** + * @dataProvider invalidNonStringKeys + */ + public function testDeleteInvalidNonStringKeys($key) + { + $this->expectException(TypeError::class); + $this->cache->delete($key); + } + + + public function testDeleteMultipleNoIterable() + { + $this->expectException(TypeError::class); + $this->cache->deleteMultiple('key'); + } + + /** + * @dataProvider invalidTtl + */ + public function testSetInvalidTtl($ttl) + { + $this->expectException(TypeError::class); + $this->cache->set('key', 'value', $ttl); + } + + /** + * @dataProvider invalidTtl + */ + public function testSetMultipleInvalidTtl($ttl) + { + $this->expectException(TypeError::class); + $this->cache->setMultiple(['key' => 'value'], $ttl); + } + + public static function invalidNonStringKeys() + { + return [ + [true], + [false], + [null], + [2.5], + [new \stdClass()], + [['array']], + ]; + } + + public static function invalidStringKeys() + { + return [ + [''], + ['{str'], + ['rand{'], + ['rand{str'], + ['rand}str'], + ['rand(str'], + ['rand)str'], + ['rand/str'], + ['rand\\str'], + ['rand@str'], + ['rand:str'], + ]; + } }