From 8dc313c64f6413afef6b7ed490deb990468ca62d Mon Sep 17 00:00:00 2001 From: Damiano Petrungaro Date: Mon, 17 Jul 2017 20:44:09 +0200 Subject: [PATCH 1/6] Updated composer.json --- composer.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/composer.json b/composer.json index 7fc2a2a..5d80817 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,8 @@ { "name": "moon/cache", "description": "A very simple Cache with support for PSR-6", + "license": "MIT", + "homepage": "https://www.moon-php.com/", "require": { "php": ">=7.1", "psr/cache": "^1.0" From 0e890f7fe398f62565793cccabe337b497859a1c Mon Sep 17 00:00:00 2001 From: Damiano Petrungaro Date: Mon, 17 Jul 2017 23:50:54 +0200 Subject: [PATCH 2/6] Some refactoring and added some tests for CacheItem TO BE REFACTORED --- phpunit.xml | 22 +++ src/Adapters/AbstractAdapter.php | 8 +- src/Adapters/AdapterInterface.php | 4 +- src/Adapters/DbalAdapter.php | 37 +++- src/Adapters/FilesystemAdapter.php | 29 ++- src/Adapters/MemcacheAdapter.php | 32 ++-- src/Adapters/MemoryAdapter.php | 8 +- src/Adapters/RedisAdapter.php | 11 +- src/CacheItem.php | 45 +++-- src/CacheItemPool.php | 4 +- src/Collection/CacheItemCollection.php | 6 +- .../CacheInvalidArgumentException.php | 11 -- src/Exception/InvalidArgumentException.php | 9 + ...xception.php => ItemNotFoundException.php} | 2 +- ...Exception.php => PersistenceException.php} | 2 +- src/Helper/CreateTableHelper.php | 9 +- src/KeyValidator.php | 11 +- tests/Unit/.gitkeep | 0 tests/Unit/CacheItemTest.php | 172 ++++++++++++++++++ 19 files changed, 336 insertions(+), 86 deletions(-) create mode 100644 phpunit.xml delete mode 100644 src/Exception/CacheInvalidArgumentException.php create mode 100644 src/Exception/InvalidArgumentException.php rename src/Exception/{CacheItemNotFoundException.php => ItemNotFoundException.php} (51%) rename src/Exception/{CachePersistenceException.php => PersistenceException.php} (55%) delete mode 100644 tests/Unit/.gitkeep create mode 100644 tests/Unit/CacheItemTest.php diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..9b02aef --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,22 @@ + + + + + ./tests/ + + + + + ./src/ + + + \ No newline at end of file diff --git a/src/Adapters/AbstractAdapter.php b/src/Adapters/AbstractAdapter.php index c25297d..d56319f 100644 --- a/src/Adapters/AbstractAdapter.php +++ b/src/Adapters/AbstractAdapter.php @@ -7,7 +7,7 @@ use Closure; use Moon\Cache\Collection\CacheItemCollection; use Moon\Cache\Collection\CacheItemCollectionInterface; -use Moon\Cache\Exception\CacheInvalidArgumentException; +use Moon\Cache\Exception\InvalidArgumentException; use Psr\Cache\CacheItemInterface; abstract class AbstractAdapter implements AdapterInterface @@ -26,6 +26,8 @@ abstract class AbstractAdapter implements AdapterInterface * @param array $items * * @return CacheItemCollectionInterface + * + * @throws InvalidArgumentException */ protected function createCacheItemCollection(array $items = []): CacheItemCollectionInterface { @@ -38,6 +40,8 @@ protected function createCacheItemCollection(array $items = []): CacheItemCollec * @param CacheItemInterface $cacheItem * * @return \DateTimeImmutable + * + * @throws InvalidArgumentException */ protected function retrieveExpiringDateFromCacheItem(CacheItemInterface $cacheItem): \DateTimeImmutable { @@ -52,7 +56,7 @@ protected function retrieveExpiringDateFromCacheItem(CacheItemInterface $cacheIt return $expirationDate; } catch (\Exception $e) { - throw new CacheInvalidArgumentException( + throw new InvalidArgumentException( "The CacheItemInterface object haven't any {$this->expirationParameterName} attribute.", 0, $e ); } diff --git a/src/Adapters/AdapterInterface.php b/src/Adapters/AdapterInterface.php index 925a5cd..66b4e3c 100644 --- a/src/Adapters/AdapterInterface.php +++ b/src/Adapters/AdapterInterface.php @@ -5,7 +5,7 @@ namespace Moon\Cache\Adapters; use Moon\Cache\Collection\CacheItemCollectionInterface; -use Moon\Cache\Exception\CacheItemNotFoundException; +use Moon\Cache\Exception\ItemNotFoundException; use Psr\Cache\CacheItemInterface; interface AdapterInterface @@ -17,7 +17,7 @@ interface AdapterInterface * * @return CacheItemInterface * - * @throws CacheItemNotFoundException + * @throws ItemNotFoundException */ public function getItem(string $key): CacheItemInterface; diff --git a/src/Adapters/DbalAdapter.php b/src/Adapters/DbalAdapter.php index 48b418c..d22323c 100644 --- a/src/Adapters/DbalAdapter.php +++ b/src/Adapters/DbalAdapter.php @@ -7,8 +7,9 @@ use Doctrine\DBAL\Connection; use Moon\Cache\CacheItem; use Moon\Cache\Collection\CacheItemCollectionInterface; -use Moon\Cache\Exception\CacheItemNotFoundException; -use Moon\Cache\Exception\CachePersistenceException; +use Moon\Cache\Exception\InvalidArgumentException; +use Moon\Cache\Exception\ItemNotFoundException; +use Moon\Cache\Exception\PersistenceException; use Psr\Cache\CacheItemInterface; class DbalAdapter extends AbstractAdapter @@ -51,6 +52,7 @@ class DbalAdapter extends AbstractAdapter * @param Connection $connection * @param array $tableOptions * @param null $expirationDateFormat + * @throws InvalidArgumentException */ public function __construct(string $poolName, Connection $connection, array $tableOptions = [], $expirationDateFormat = null) { @@ -63,7 +65,7 @@ public function __construct(string $poolName, Connection $connection, array $tab $checkValidFormat = \DateTimeImmutable::createFromFormat($this->expirationDateFormat, 'now'); unset($checkValidFormat); } catch (\Exception $e) { - throw new CacheItemNotFoundException('Invalid expiration column format', 0, $e); + throw new InvalidArgumentException('Invalid expiration column format', 0, $e); } } @@ -94,6 +96,8 @@ public function getItems(array $keys = []): CacheItemCollectionInterface * @param array $row * * @return CacheItemInterface + * + * @throws InvalidArgumentException */ protected function createCacheItemFromRow(array $row): CacheItemInterface { @@ -107,12 +111,14 @@ protected function createCacheItemFromRow(array $row): CacheItemInterface /** * {@inheritdoc} + * + * @throws \Moon\Cache\Exception\PersistenceException */ public function hasItem(string $key): bool { try { $this->getItem($key); - } catch (CacheItemNotFoundException $e) { + } catch (ItemNotFoundException $e) { return false; } @@ -121,6 +127,8 @@ public function hasItem(string $key): bool /** * {@inheritdoc} + * + * @throws \Moon\Cache\Exception\PersistenceException */ public function getItem(string $key): CacheItemInterface { @@ -134,11 +142,11 @@ public function getItem(string $key): CacheItemInterface ->execute() ->fetch(\PDO::FETCH_ASSOC); } catch (\Exception $e) { - throw new CachePersistenceException($e->getMessage(), 0, $e); + throw new PersistenceException($e->getMessage(), 0, $e); } if (empty($row)) { - throw new CacheItemNotFoundException(); + throw new ItemNotFoundException(); } return $this->createCacheItemFromRow($row); @@ -146,6 +154,8 @@ public function getItem(string $key): CacheItemInterface /** * {@inheritdoc} + * + * @throws \Moon\Cache\Exception\PersistenceException */ public function clear(): bool { @@ -157,12 +167,14 @@ public function clear(): bool ->execute(); } catch (\Exception $e) { - throw new CachePersistenceException($e->getMessage(), 0, $e); + throw new PersistenceException($e->getMessage(), 0, $e); } } /** * {@inheritdoc} + * + * @throws \Moon\Cache\Exception\PersistenceException */ public function deleteItem(string $key): bool { @@ -174,12 +186,14 @@ public function deleteItem(string $key): bool ->execute(); } catch (\Exception $e) { - throw new CachePersistenceException($e->getMessage(), 0, $e); + throw new PersistenceException($e->getMessage(), 0, $e); } } /** * {@inheritdoc} + * + * @throws \Moon\Cache\Exception\PersistenceException */ public function deleteItems(array $keys): bool { @@ -192,7 +206,7 @@ public function deleteItems(array $keys): bool return (bool)$deletedRows; } catch (\Exception $e) { - throw new CachePersistenceException($e->getMessage(), 0, $e); + throw new PersistenceException($e->getMessage(), 0, $e); } } @@ -222,6 +236,9 @@ public function saveItems(CacheItemCollectionInterface $items): bool /** * {@inheritdoc} + * + * @throws PersistenceException + * @throws InvalidArgumentException */ public function save(CacheItemInterface $item): bool { @@ -235,7 +252,7 @@ public function save(CacheItemInterface $item): bool try { return (bool)$this->connection->insert("`{$this->tableOptions['tableName']}`", $data); } catch (\Exception $e) { - throw new CachePersistenceException($e->getMessage(), 0, $e); + throw new PersistenceException($e->getMessage(), 0, $e); } } } \ No newline at end of file diff --git a/src/Adapters/FilesystemAdapter.php b/src/Adapters/FilesystemAdapter.php index 52f98b1..24f6554 100644 --- a/src/Adapters/FilesystemAdapter.php +++ b/src/Adapters/FilesystemAdapter.php @@ -6,7 +6,8 @@ use Moon\Cache\CacheItem; use Moon\Cache\Collection\CacheItemCollectionInterface; -use Moon\Cache\Exception\CacheItemNotFoundException; +use Moon\Cache\Exception\InvalidArgumentException; +use Moon\Cache\Exception\ItemNotFoundException; use Psr\Cache\CacheItemInterface; class FilesystemAdapter extends AbstractAdapter @@ -47,7 +48,7 @@ public function getItem(string $key): CacheItemInterface return $this->createCacheItemFromFile($filename); } - throw new CacheItemNotFoundException(); + throw new ItemNotFoundException(); } /** @@ -59,11 +60,11 @@ public function getItems(array $keys = []): CacheItemCollectionInterface $cacheItemCollection = $this->createCacheItemCollection(); // Add to the collection all items found - // Do not throw CacheItemNotFoundException if item is not found + // Do not throw ItemNotFoundException if item is not found foreach ($keys as $key) { try { $cacheItemCollection->add($this->getItem($key)); - } catch (CacheItemNotFoundException $e) { + } catch (ItemNotFoundException $e) { continue; } } @@ -91,18 +92,20 @@ public function clear(): bool /** @var \SplFileInfo $file */ foreach ($directory as $element) { // Skip '.' and '..' directories - if (in_array($element->getFilename(), ['.', '..'])) { + if (in_array($element->getFilename(), ['.', '..'], true)) { continue; } - if ($element->isDir()) return false; + if ($element->isDir()) { + return false; + } } // Remove all files /** @var \SplFileInfo $element */ foreach ($directory as $element) { // Skip '.' and '..' directories - if (in_array($element->getFilename(), ['.', '..'])) { + if (in_array($element->getFilename(), ['.', '..'], true)) { continue; } @@ -138,7 +141,7 @@ public function deleteItems(array $keys): bool { foreach ($keys as $key) { if (!$this->deleteItem($key)) { - + return false; } } @@ -148,6 +151,8 @@ public function deleteItems(array $keys): bool /** * {@inheritdoc} + * + * @throws InvalidArgumentException */ public function save(CacheItemInterface $item): bool { @@ -159,6 +164,8 @@ public function save(CacheItemInterface $item): bool /** * THIS IS NOT TRANSACTION-SAFE * {@inheritdoc} + * + * @throws InvalidArgumentException */ public function saveItems(CacheItemCollectionInterface $items): bool { @@ -177,13 +184,15 @@ public function saveItems(CacheItemCollectionInterface $items): bool * @param string $path * * @return CacheItemInterface + * + * @throws InvalidArgumentException */ protected function createCacheItemFromFile(string $path): CacheItemInterface { // Get Key, Value and $expireDate from the file $parts = explode('/', $path); $key = end($parts); - list($value, $expireDate) = explode(PHP_EOL, file_get_contents($path)); + [$value, $expireDate] = explode(PHP_EOL, file_get_contents($path)); // Create a new CacheItem return new CacheItem($this->keyDecode($key), unserialize($value), unserialize($expireDate)); @@ -220,7 +229,7 @@ protected function keyDecode(string $key): string * * @return string */ - private function getFilenameFromKey($key) + private function getFilenameFromKey($key): string { return "{$this->directory}/{$this->keyEncode($key)}"; } diff --git a/src/Adapters/MemcacheAdapter.php b/src/Adapters/MemcacheAdapter.php index 9465fb8..86f52ed 100644 --- a/src/Adapters/MemcacheAdapter.php +++ b/src/Adapters/MemcacheAdapter.php @@ -6,8 +6,8 @@ use Moon\Cache\CacheItem; use Moon\Cache\Collection\CacheItemCollectionInterface; -use Moon\Cache\Exception\CacheInvalidArgumentException; -use Moon\Cache\Exception\CacheItemNotFoundException; +use Moon\Cache\Exception\InvalidArgumentException; +use Moon\Cache\Exception\ItemNotFoundException; use Psr\Cache\CacheItemInterface; class MemcacheAdapter extends AbstractAdapter @@ -34,6 +34,8 @@ class MemcacheAdapter extends AbstractAdapter * @param string $poolName * @param \Memcached $memcached * @param string $separator + * + * @throws InvalidArgumentException */ public function __construct(string $poolName, \Memcached $memcached, $separator = '.') { @@ -67,22 +69,20 @@ public function hasItem(string $key): bool $this->normalizeKeyName($keys); $item = $this->memcached->getByKey($this->poolName, $key); - if (!$item || \Memcached::RES_NOTFOUND == $item) { - return false; - } - - return true; + return !(!$item || \Memcached::RES_NOTFOUND === $item); } /** * {@inheritdoc} + * + * @throws InvalidArgumentException */ public function getItem(string $key): CacheItemInterface { $this->normalizeKeyName($key); $item = $this->memcached->getByKey($this->poolName, $key); - if (!$item || \Memcached::RES_NOTFOUND == $item) { - throw new CacheItemNotFoundException(); + if (!$item || \Memcached::RES_NOTFOUND === $item) { + throw new ItemNotFoundException(); } return $this->createCacheItemFromValue([$key => $item]); @@ -125,8 +125,8 @@ public function deleteItems(array $keys): bool { $this->normalizeKeyName($keys); - foreach ($this->memcached->deleteMultiByKey($this->poolName, $keys) as $deletedItem) { - if (!$deletedItem) { + foreach ($keys as $key) { + if (!$this->memcached->deleteMultiByKey($this->poolName, $key)) { return false; } @@ -137,6 +137,8 @@ public function deleteItems(array $keys): bool /** * {@inheritdoc} + * + * @throws InvalidArgumentException */ public function saveItems(CacheItemCollectionInterface $items): bool { @@ -154,6 +156,8 @@ public function saveItems(CacheItemCollectionInterface $items): bool /** * {@inheritdoc} + * + * @throws InvalidArgumentException */ public function save(CacheItemInterface $item): bool { @@ -190,6 +194,8 @@ protected function normalizeKeyName(&$keys): void * @param array $item * * @return CacheItemInterface + * + * @throws InvalidArgumentException */ protected function createCacheItemFromValue(array $item): CacheItemInterface { @@ -207,13 +213,13 @@ protected function createCacheItemFromValue(array $item): CacheItemInterface * * @param string $key * - * @throws CacheInvalidArgumentException + * @throws InvalidArgumentException */ protected function validateKey(string $key): void { foreach (self::INVALID_CHARS as $invalidChar) { if (strpos($key, $invalidChar) !== false) { - throw new CacheInvalidArgumentException("$key, is invalid, it contains an invalid character '$invalidChar'"); + throw new InvalidArgumentException("$key, is invalid, it contains an invalid character '$invalidChar'"); } } } diff --git a/src/Adapters/MemoryAdapter.php b/src/Adapters/MemoryAdapter.php index 75b5de8..e2dce78 100644 --- a/src/Adapters/MemoryAdapter.php +++ b/src/Adapters/MemoryAdapter.php @@ -5,7 +5,7 @@ namespace Moon\Cache\Adapters; use Moon\Cache\Collection\CacheItemCollectionInterface; -use Moon\Cache\Exception\CacheItemNotFoundException; +use Moon\Cache\Exception\ItemNotFoundException; use Psr\Cache\CacheItemInterface; class MemoryAdapter extends AbstractAdapter @@ -32,7 +32,7 @@ public function getItem(string $key): CacheItemInterface try { return $this->collection->get($key); } catch (\InvalidArgumentException $e) { - throw new CacheItemNotFoundException($e->getMessage(), $e->getCode(), $e); + throw new ItemNotFoundException($e->getMessage(), $e->getCode(), $e); } } @@ -46,11 +46,11 @@ public function getItems(array $keys = []): CacheItemCollectionInterface $cacheItemCollection = $this->createCacheItemCollection(); // Add to the collection all items found - // Do not throw CacheItemNotFoundException if item is not found + // Do not throw ItemNotFoundException if item is not found foreach ($keys as $key) { try { $cacheItemCollection->add($this->getItem($key)); - } catch (CacheItemNotFoundException $e) { + } catch (ItemNotFoundException $e) { continue; } } diff --git a/src/Adapters/RedisAdapter.php b/src/Adapters/RedisAdapter.php index 00fc53d..eb64039 100644 --- a/src/Adapters/RedisAdapter.php +++ b/src/Adapters/RedisAdapter.php @@ -6,7 +6,8 @@ use Moon\Cache\CacheItem; use Moon\Cache\Collection\CacheItemCollectionInterface; -use Moon\Cache\Exception\CacheItemNotFoundException; +use Moon\Cache\Exception\InvalidArgumentException; +use Moon\Cache\Exception\ItemNotFoundException; use Psr\Cache\CacheItemInterface; class RedisAdapter extends AbstractAdapter @@ -71,7 +72,7 @@ public function getItem(string $key): CacheItemInterface $item = $this->redis->get($key); if ($item === false) { - throw new CacheItemNotFoundException(); + throw new ItemNotFoundException(); } return $this->createCacheItemFromValue([$key => $item]); @@ -120,7 +121,7 @@ public function saveItems(CacheItemCollectionInterface $items): bool $value = [$item->get(), $this->retrieveExpiringDateFromCacheItem($item)]; $this->redis->set($key, serialize($value)); } - return !in_array(false, array_values($mul->exec())); + return !in_array(false, array_values($mul->exec()), true); } catch (\Exception $e) { $mul->discard(); return false; @@ -129,6 +130,8 @@ public function saveItems(CacheItemCollectionInterface $items): bool /** * {@inheritdoc} + * + * @throws InvalidArgumentException */ public function save(CacheItemInterface $item): bool { @@ -162,6 +165,8 @@ protected function normalizeKeyName(&$keys): void * @param array $item * * @return CacheItemInterface + * + * @throws InvalidArgumentException */ protected function createCacheItemFromValue(array $item): CacheItemInterface { diff --git a/src/CacheItem.php b/src/CacheItem.php index 4bba1ff..7be1cc7 100644 --- a/src/CacheItem.php +++ b/src/CacheItem.php @@ -4,7 +4,7 @@ namespace Moon\Cache; -use Moon\Cache\Exception\CacheInvalidArgumentException; +use Moon\Cache\Exception\InvalidArgumentException; use Psr\Cache\CacheItemInterface; class CacheItem implements CacheItemInterface @@ -21,11 +21,6 @@ class CacheItem implements CacheItemInterface */ protected $value; - /** - * @var bool $hit - */ - protected $hit; - /** * @var \DateTimeImmutable $expiration */ @@ -34,22 +29,22 @@ class CacheItem implements CacheItemInterface /** * Default value to use as default expiration date */ - protected const DEFAULT_EXPIRATION = 'now +1 week'; + public const DEFAULT_EXPIRATION = 'now +1 week'; /** * CacheItem constructor. * * @param string $key * @param $value - * @param bool $hit * @param \DateTimeImmutable $expiration + * + * @throws InvalidArgumentException */ - public function __construct(string $key, $value, \DateTimeImmutable $expiration = null, bool $hit = false) + public function __construct(string $key, $value, \DateTimeImmutable $expiration = null) { $this->validateKey($key); $this->key = $key; $this->value = $value; - $this->hit = $hit; $this->expiration = $expiration ?: new \DateTimeImmutable(static::DEFAULT_EXPIRATION); } @@ -66,7 +61,7 @@ public function getKey(): string */ public function get() { - return $this->value; + return $this->isHit() ? $this->value : null; } /** @@ -74,7 +69,7 @@ public function get() */ public function isHit(): bool { - return $this->hit; + return $this->expiration >= new \DateTimeImmutable(); } /** @@ -89,21 +84,19 @@ public function set($value): CacheItemInterface /** * {@inheritdoc} + * + * @throws InvalidArgumentException */ public function expiresAt($expiration = null): CacheItemInterface { - if ($expiration instanceof \DateTimeInterface) { + if ($expiration instanceof \DateTimeImmutable) { $this->expiration = $expiration; } elseif ($expiration instanceof \DateTime) { $this->expiration = \DateTimeImmutable::createFromMutable($expiration); - } elseif ($expiration instanceof \DateInterval) { - $this->expiration = (new \DateTimeImmutable())->add($expiration); - } elseif (is_int($expiration)) { - $this->expiration = new \DateTimeImmutable("now +$expiration seconds"); } elseif (null === $expiration) { $this->expiration = new \DateTimeImmutable(self::DEFAULT_EXPIRATION); } else { - throw new CacheInvalidArgumentException('Invalid expiration parameter for CacheItem.'); + throw new InvalidArgumentException('Invalid expiration parameter for CacheItem.'); } return $this; @@ -111,9 +104,21 @@ public function expiresAt($expiration = null): CacheItemInterface /** * {@inheritdoc} + * + * @throws InvalidArgumentException */ - public function expiresAfter($time): CacheItemInterface + public function expiresAfter($time = null): CacheItemInterface { - return $this->expiresAt($time); + if ($time instanceof \DateInterval) { + $this->expiration = (new \DateTimeImmutable())->add($time); + } elseif (is_int($time)) { + $this->expiration = new \DateTimeImmutable("now +$time seconds"); + } elseif ($time === null) { + $this->expiration = new \DateTimeImmutable(static::DEFAULT_EXPIRATION); + } else { + throw new InvalidArgumentException('Invalid time for CacheItem.'); + } + + return $this; } } \ No newline at end of file diff --git a/src/CacheItemPool.php b/src/CacheItemPool.php index 91b0826..e0175ea 100644 --- a/src/CacheItemPool.php +++ b/src/CacheItemPool.php @@ -118,7 +118,7 @@ public function save(CacheItemInterface $item): bool public function saveDeferred(CacheItemInterface $item): bool { // Do not add if the last try of saving deferred items fails - if ($this->isSaveDeferredItemsFailed == true) { + if ($this->isSaveDeferredItemsFailed === true) { return false; } @@ -153,6 +153,8 @@ public function commit(): bool * @param array $items * * @return CacheItemCollectionInterface + * + * @throws InvalidArgumentException */ protected function createCacheItemCollectionInterface(array $items = []): CacheItemCollectionInterface { diff --git a/src/Collection/CacheItemCollection.php b/src/Collection/CacheItemCollection.php index 65f6c6b..3a10878 100644 --- a/src/Collection/CacheItemCollection.php +++ b/src/Collection/CacheItemCollection.php @@ -5,7 +5,7 @@ namespace Moon\Cache\Collection; -use Moon\Cache\Exception\CacheInvalidArgumentException; +use Moon\Cache\Exception\InvalidArgumentException; use Psr\Cache\CacheItemInterface; class CacheItemCollection implements CacheItemCollectionInterface @@ -18,12 +18,14 @@ class CacheItemCollection implements CacheItemCollectionInterface /** * CacheItemCollection constructor. * @param CacheItemInterface[] $items + * + * @throws InvalidArgumentException */ public function __construct(array $items = []) { foreach ($items as $item) { if (!$item instanceof CacheItemInterface) { - throw new CacheInvalidArgumentException("Item $item be an instance of CacheItemInterface"); + throw new InvalidArgumentException("Item $item be an instance of CacheItemInterface"); } $this->items[$item->getKey()] = $item; } diff --git a/src/Exception/CacheInvalidArgumentException.php b/src/Exception/CacheInvalidArgumentException.php deleted file mode 100644 index d6ccb36..0000000 --- a/src/Exception/CacheInvalidArgumentException.php +++ /dev/null @@ -1,11 +0,0 @@ -tableOptions = array_merge($this->tableOptions, $tableOptions); diff --git a/src/KeyValidator.php b/src/KeyValidator.php index bce8a8d..3c8a97d 100644 --- a/src/KeyValidator.php +++ b/src/KeyValidator.php @@ -4,7 +4,7 @@ namespace Moon\Cache; -use Moon\Cache\Exception\CacheInvalidArgumentException; +use Moon\Cache\Exception\InvalidArgumentException; trait KeyValidator { @@ -15,18 +15,19 @@ trait KeyValidator * * @return void * - * @throws CacheInvalidArgumentException + * @throws InvalidArgumentException */ protected function validateKey(string $key): void { + $length = strlen($key); // String length must be at least 1 and less then 64 - if (strlen($key) <= 0 || strlen($key) > 64) { - throw new CacheInvalidArgumentException("The key '$key' must be length from 1 up to 64 characters"); + if ($length <= 0 || 64 < $length) { + throw new InvalidArgumentException("The key '$key' must be length from 1 up to 64 characters"); } // If string contains invalid character throws the exception if (!preg_match('#^[A-Za-z0-9._]+$#', $key)) { - throw new CacheInvalidArgumentException("The key $key contains invalid characters. Supported characters are A-Z a-z 0-9 _ and ."); + throw new InvalidArgumentException("The key '$key' contains invalid characters. Supported characters are A-Z a-z 0-9 _ and ."); } } } \ No newline at end of file diff --git a/tests/Unit/.gitkeep b/tests/Unit/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/tests/Unit/CacheItemTest.php b/tests/Unit/CacheItemTest.php new file mode 100644 index 0000000..8f9ff4e --- /dev/null +++ b/tests/Unit/CacheItemTest.php @@ -0,0 +1,172 @@ +expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("The key '$key' must be length from 1 up to 64 characters"); + new CacheItem($key, ''); + } + + /** + * @dataProvider invalidCharKeyDataProvider + */ + public function testInvalidCharKeyThrowAnException($key) + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("The key '$key' contains invalid characters. Supported characters are A-Z a-z 0-9 _ and ."); + new CacheItem($key, ''); + } + + public function testThatValueAndKeyAreProperlySet() + { + $item = new CacheItem('a_key', 'a value'); + $this->assertSame($item->getKey(), 'a_key'); + $this->assertSame($item->get(), 'a value'); + } + + public function testThatSetMethodCreateANewObjectWithADifferentValue() + { + $item = new CacheItem('a_key', 'a value'); + $itemTwo = $item->set('another_value'); + $this->assertSame($itemTwo->get(), 'another_value'); + } + + /** + * @dataProvider expirationDateDataProvider + */ + public function testDefaultException($expectedDate, $date) + { + $reflectionExpiration = new \ReflectionProperty(CacheItem::class, 'expiration'); + $reflectionExpiration->setAccessible(true); + $item = new CacheItem('key', '', $date); + $returnedDate = $reflectionExpiration->getValue($item); + $this->assertSame($expectedDate->format('Y-m-d H:i'), $returnedDate->format('Y-m-d H:i')); + } + + /** + * @dataProvider valueAcceptedByExpiresAtDataProvider + */ + public function testExpiresAt($expectedDate, $date) + { + $reflectionExpiration = new \ReflectionProperty(CacheItem::class, 'expiration'); + $reflectionExpiration->setAccessible(true); + $item = new CacheItem('key', ''); + $item->expiresAt($date); + $returnedDate = $reflectionExpiration->getValue($item); + $this->assertSame($expectedDate->format('Y-m-d H:i'), $returnedDate->format('Y-m-d H:i')); + } + + public function testIsHit() + { + $item = new CacheItem('key', ''); + $this->assertTrue($item->isHit()); + $item = new CacheItem('key', '', new \DateTimeImmutable('-1 day')); + $this->assertFalse($item->isHit()); + } + + /** + * @dataProvider valueInvalidByExpiresAtDataProvider + */ + public function testExpiresAtThrowInvalidArgumentExcpetion($invalidDate) + { + $this->expectException(InvalidArgumentException::class); + + $item = new CacheItem('key', ''); + $item->expiresAt($invalidDate); + } + + + /** + * @dataProvider valueInvalidByExpiresAfterDataProvider + */ + public function testExpiresAfterThrowInvalidArgumentExcpetion($invalidDate) + { + $this->expectException(InvalidArgumentException::class); + + $item = new CacheItem('key', ''); + $item->expiresAfter($invalidDate); + } + + /** + * @dataProvider valueAcceptedByExpiresAfterDataProvider + */ + public function testExpiresAfter($expectedDate, $date) + { + $reflectionExpiration = new \ReflectionProperty(CacheItem::class, 'expiration'); + $reflectionExpiration->setAccessible(true); + $item = new CacheItem('key', ''); + $item->expiresAfter($date); + $returnedDate = $reflectionExpiration->getValue($item); + $this->assertSame($expectedDate->format('Y-m-d H:i'), $returnedDate->format('Y-m-d H:i')); + } + + public function valueAcceptedByExpiresAfterDataProvider() + { + return [ + [new \DateTimeImmutable(), 10], + [new \DateTimeImmutable(), new \DateInterval('PT1S')], + [new \DateTimeImmutable(CacheItem::DEFAULT_EXPIRATION), null], + ]; + } + + public function valueInvalidByExpiresAfterDataProvider() + { + return [ + [[1, 2, 3]], + [new \DateTimeImmutable()], + [CacheItem::DEFAULT_EXPIRATION], + [new \SplStack()], + ]; + } + + public function valueInvalidByExpiresAtDataProvider() + { + return [ + [[1, 2, 3]], + [12], + [CacheItem::DEFAULT_EXPIRATION], + [new \SplStack()], + ]; + } + + public function valueAcceptedByExpiresAtDataProvider() + { + return [ + [new \DateTimeImmutable('now'), new \DateTime('now')], + [new \DateTimeImmutable('+1 day'), new \DateTimeImmutable('+1 day')], + [new \DateTimeImmutable(CacheItem::DEFAULT_EXPIRATION), null] + ]; + } + + public function expirationDateDataProvider() + { + return [ + [new \DateTimeImmutable('now'), new \DateTimeImmutable('now')], + [new \DateTimeImmutable('+1 day'), new \DateTimeImmutable('+1 day')], + [new \DateTimeImmutable(CacheItem::DEFAULT_EXPIRATION), null] + ]; + } + + public function invalidLengthKeyDataProvider() + { + return [[''], ['qqedjspjasopdjopasjqqedjspjasopdjopasjqqedjspjasopdjopasjqqedjspjasopdjopasjqqedjspjasopdjopasjqqedjspjasopdjopasjqqedjs']]; + } + + public function invalidCharKeyDataProvider() + { + return [[' '], ['ès + àò']]; + } +} \ No newline at end of file From 7bc86176462c340de2c25e89fed22606a41b3f29 Mon Sep 17 00:00:00 2001 From: Damiano Petrungaro Date: Fri, 21 Jul 2017 18:41:16 +0200 Subject: [PATCH 3/6] Better time test (but no so good at all) --- tests/Unit/CacheItemTest.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/Unit/CacheItemTest.php b/tests/Unit/CacheItemTest.php index 8f9ff4e..e62a6ba 100644 --- a/tests/Unit/CacheItemTest.php +++ b/tests/Unit/CacheItemTest.php @@ -7,7 +7,6 @@ use Moon\Cache\Exception\InvalidArgumentException; use PHPUnit\Framework\TestCase; -// TODO Refactor assert by time class CacheItemTest extends TestCase { /** @@ -53,7 +52,7 @@ public function testDefaultException($expectedDate, $date) $reflectionExpiration->setAccessible(true); $item = new CacheItem('key', '', $date); $returnedDate = $reflectionExpiration->getValue($item); - $this->assertSame($expectedDate->format('Y-m-d H:i'), $returnedDate->format('Y-m-d H:i')); + $this->assertEquals($expectedDate->getTimestamp(), $returnedDate->getTimestamp(), '', 3); } /** @@ -66,7 +65,7 @@ public function testExpiresAt($expectedDate, $date) $item = new CacheItem('key', ''); $item->expiresAt($date); $returnedDate = $reflectionExpiration->getValue($item); - $this->assertSame($expectedDate->format('Y-m-d H:i'), $returnedDate->format('Y-m-d H:i')); + $this->assertEquals($expectedDate->getTimestamp(), $returnedDate->getTimestamp(), '', 3); } public function testIsHit() @@ -110,14 +109,14 @@ public function testExpiresAfter($expectedDate, $date) $item = new CacheItem('key', ''); $item->expiresAfter($date); $returnedDate = $reflectionExpiration->getValue($item); - $this->assertSame($expectedDate->format('Y-m-d H:i'), $returnedDate->format('Y-m-d H:i')); + $this->assertEquals($expectedDate->getTimestamp(), $returnedDate->getTimestamp(), '', 3); } public function valueAcceptedByExpiresAfterDataProvider() { return [ - [new \DateTimeImmutable(), 10], - [new \DateTimeImmutable(), new \DateInterval('PT1S')], + [new \DateTimeImmutable('+10 seconds'), 10], + [new \DateTimeImmutable('+1 second'), new \DateInterval('PT1S')], [new \DateTimeImmutable(CacheItem::DEFAULT_EXPIRATION), null], ]; } From bff2e8a6dbc529917d9cd048ebcb9afab38c38ba Mon Sep 17 00:00:00 2001 From: Damiano Petrungaro Date: Fri, 21 Jul 2017 20:47:57 +0200 Subject: [PATCH 4/6] Removed ItemsCollection for stricter PSR implementation --- src/Adapters/AbstractAdapter.php | 16 ---- src/Adapters/AdapterInterface.php | 14 +-- src/Adapters/DbalAdapter.php | 13 ++- src/Adapters/FilesystemAdapter.php | 15 ++-- src/Adapters/MemcacheAdapter.php | 11 ++- src/Adapters/MemoryAdapter.php | 63 ++++++++------ src/Adapters/RedisAdapter.php | 14 +-- src/CacheItemPool.php | 52 ++++-------- src/Collection/CacheItemCollection.php | 85 ------------------- .../CacheItemCollectionInterface.php | 48 ----------- 10 files changed, 88 insertions(+), 243 deletions(-) delete mode 100644 src/Collection/CacheItemCollection.php delete mode 100644 src/Collection/CacheItemCollectionInterface.php diff --git a/src/Adapters/AbstractAdapter.php b/src/Adapters/AbstractAdapter.php index d56319f..1cae09b 100644 --- a/src/Adapters/AbstractAdapter.php +++ b/src/Adapters/AbstractAdapter.php @@ -5,8 +5,6 @@ namespace Moon\Cache\Adapters; use Closure; -use Moon\Cache\Collection\CacheItemCollection; -use Moon\Cache\Collection\CacheItemCollectionInterface; use Moon\Cache\Exception\InvalidArgumentException; use Psr\Cache\CacheItemInterface; @@ -20,20 +18,6 @@ abstract class AbstractAdapter implements AdapterInterface */ protected $expirationParameterName = 'expiration'; - /** - * Create a CacheItemCollection from an array - * - * @param array $items - * - * @return CacheItemCollectionInterface - * - * @throws InvalidArgumentException - */ - protected function createCacheItemCollection(array $items = []): CacheItemCollectionInterface - { - return new CacheItemCollection($items); - } - /** * Return the expiringDate from an CacheItemObject * diff --git a/src/Adapters/AdapterInterface.php b/src/Adapters/AdapterInterface.php index 66b4e3c..4a42c48 100644 --- a/src/Adapters/AdapterInterface.php +++ b/src/Adapters/AdapterInterface.php @@ -4,7 +4,7 @@ namespace Moon\Cache\Adapters; -use Moon\Cache\Collection\CacheItemCollectionInterface; +use Moon\Cache\Exception\InvalidArgumentException; use Moon\Cache\Exception\ItemNotFoundException; use Psr\Cache\CacheItemInterface; @@ -22,13 +22,13 @@ interface AdapterInterface public function getItem(string $key): CacheItemInterface; /** - * Return a CacheItemCollection from an array + * Return a array from an array of keys * * @param string[] $keys * - * @return CacheItemCollectionInterface + * @return array */ - public function getItems(array $keys = []): CacheItemCollectionInterface; + public function getItems(array $keys = []): array; /** @@ -78,9 +78,11 @@ public function save(CacheItemInterface $item): bool; /** * Add new CacheItems to the pool * - * @param CacheItemCollectionInterface $items + * @param array $items * * @return bool + * + * @throws InvalidArgumentException */ - public function saveItems(CacheItemCollectionInterface $items): bool; + public function saveItems(array $items): bool; } \ No newline at end of file diff --git a/src/Adapters/DbalAdapter.php b/src/Adapters/DbalAdapter.php index d22323c..a8153ef 100644 --- a/src/Adapters/DbalAdapter.php +++ b/src/Adapters/DbalAdapter.php @@ -6,7 +6,6 @@ use Doctrine\DBAL\Connection; use Moon\Cache\CacheItem; -use Moon\Cache\Collection\CacheItemCollectionInterface; use Moon\Cache\Exception\InvalidArgumentException; use Moon\Cache\Exception\ItemNotFoundException; use Moon\Cache\Exception\PersistenceException; @@ -72,7 +71,7 @@ public function __construct(string $poolName, Connection $connection, array $tab /** * {@inheritdoc} */ - public function getItems(array $keys = []): CacheItemCollectionInterface + public function getItems(array $keys = []): array { $stmt = $this->connection->createQueryBuilder() ->select('*') @@ -81,13 +80,13 @@ public function getItems(array $keys = []): CacheItemCollectionInterface ->setParameter(':keys', $keys, Connection::PARAM_STR_ARRAY) ->execute(); - $cacheItemCollection = $this->createCacheItemCollection(); + $cacheItems = []; while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $cacheItemCollection->add($this->createCacheItemFromRow($row)); + $cacheItems[] = $this->createCacheItemFromRow($row); } - return $cacheItemCollection; + return $cacheItems; } /** @@ -128,7 +127,7 @@ public function hasItem(string $key): bool /** * {@inheritdoc} * - * @throws \Moon\Cache\Exception\PersistenceException + * @throws PersistenceException */ public function getItem(string $key): CacheItemInterface { @@ -213,7 +212,7 @@ public function deleteItems(array $keys): bool /** * {@inheritdoc} */ - public function saveItems(CacheItemCollectionInterface $items): bool + public function saveItems(array $items): bool { $this->connection->beginTransaction(); try { diff --git a/src/Adapters/FilesystemAdapter.php b/src/Adapters/FilesystemAdapter.php index 24f6554..56bb15c 100644 --- a/src/Adapters/FilesystemAdapter.php +++ b/src/Adapters/FilesystemAdapter.php @@ -5,7 +5,6 @@ namespace Moon\Cache\Adapters; use Moon\Cache\CacheItem; -use Moon\Cache\Collection\CacheItemCollectionInterface; use Moon\Cache\Exception\InvalidArgumentException; use Moon\Cache\Exception\ItemNotFoundException; use Psr\Cache\CacheItemInterface; @@ -54,22 +53,22 @@ public function getItem(string $key): CacheItemInterface /** * {@inheritdoc} */ - public function getItems(array $keys = []): CacheItemCollectionInterface + public function getItems(array $keys = []): array { - // Create an empty collection - $cacheItemCollection = $this->createCacheItemCollection(); + // Create an empty array + $cacheItems = []; - // Add to the collection all items found + // Add to the array all items found // Do not throw ItemNotFoundException if item is not found foreach ($keys as $key) { try { - $cacheItemCollection->add($this->getItem($key)); + $cacheItems[] = $this->getItem($key); } catch (ItemNotFoundException $e) { continue; } } - return $cacheItemCollection; + return $cacheItems; } /** @@ -167,7 +166,7 @@ public function save(CacheItemInterface $item): bool * * @throws InvalidArgumentException */ - public function saveItems(CacheItemCollectionInterface $items): bool + public function saveItems(array $items): bool { foreach ($items as $item) { if (!$this->save($item)) { diff --git a/src/Adapters/MemcacheAdapter.php b/src/Adapters/MemcacheAdapter.php index 86f52ed..c679469 100644 --- a/src/Adapters/MemcacheAdapter.php +++ b/src/Adapters/MemcacheAdapter.php @@ -5,7 +5,6 @@ namespace Moon\Cache\Adapters; use Moon\Cache\CacheItem; -use Moon\Cache\Collection\CacheItemCollectionInterface; use Moon\Cache\Exception\InvalidArgumentException; use Moon\Cache\Exception\ItemNotFoundException; use Psr\Cache\CacheItemInterface; @@ -48,17 +47,17 @@ public function __construct(string $poolName, \Memcached $memcached, $separator /** * {@inheritdoc} */ - public function getItems(array $keys = []): CacheItemCollectionInterface + public function getItems(array $keys = []): array { $this->normalizeKeyName($keys); $items = $this->memcached->getMultiByKey($this->poolName, $keys); - $cacheItemCollection = $this->createCacheItemCollection(); + $cacheItems = []; foreach ($items as $k => $item) { - $cacheItemCollection->add($this->createCacheItemFromValue([$k => $item])); + $cacheItems[] = $this->createCacheItemFromValue([$k => $item]); } - return $cacheItemCollection; + return $cacheItems; } /** @@ -140,7 +139,7 @@ public function deleteItems(array $keys): bool * * @throws InvalidArgumentException */ - public function saveItems(CacheItemCollectionInterface $items): bool + public function saveItems(array $items): bool { $elaboratedItems = []; diff --git a/src/Adapters/MemoryAdapter.php b/src/Adapters/MemoryAdapter.php index e2dce78..698f0be 100644 --- a/src/Adapters/MemoryAdapter.php +++ b/src/Adapters/MemoryAdapter.php @@ -4,24 +4,24 @@ namespace Moon\Cache\Adapters; -use Moon\Cache\Collection\CacheItemCollectionInterface; +use Moon\Cache\Exception\InvalidArgumentException; use Moon\Cache\Exception\ItemNotFoundException; use Psr\Cache\CacheItemInterface; class MemoryAdapter extends AbstractAdapter { /** - * @var CacheItemCollectionInterface + * @var array */ - private $collection; + private $items; /** * MemoryAdapter constructor. - * @param CacheItemCollectionInterface $collection + * @param array $items */ - public function __construct(CacheItemCollectionInterface $collection) + public function __construct(array $items) { - $this->collection = $collection; + $this->items = $items; } /** @@ -29,33 +29,32 @@ public function __construct(CacheItemCollectionInterface $collection) */ public function getItem(string $key): CacheItemInterface { - try { - return $this->collection->get($key); - } catch (\InvalidArgumentException $e) { - throw new ItemNotFoundException($e->getMessage(), $e->getCode(), $e); + if (!isset($this->items[$key])) { + throw new ItemNotFoundException("The key $key is not available in the array"); } + return $this->items[$key]; } /** * {@inheritdoc} */ - public function getItems(array $keys = []): CacheItemCollectionInterface + public function getItems(array $keys = []): array { - // Create an empty collection - $cacheItemCollection = $this->createCacheItemCollection(); + // Create an empty items + $cacheItems = []; - // Add to the collection all items found + // Add to the items all items found // Do not throw ItemNotFoundException if item is not found foreach ($keys as $key) { try { - $cacheItemCollection->add($this->getItem($key)); + $cacheItems[] = $this->getItem($key); } catch (ItemNotFoundException $e) { continue; } } - return $cacheItemCollection; + return $cacheItems; } /** @@ -63,7 +62,7 @@ public function getItems(array $keys = []): CacheItemCollectionInterface */ public function hasItem(string $key): bool { - return $this->collection->has($key); + return isset($this->items[$key]); } /** @@ -71,7 +70,7 @@ public function hasItem(string $key): bool */ public function clear(): bool { - $this->collection = $this->createCacheItemCollection(); + $this->items = []; return true; } @@ -81,21 +80,29 @@ public function clear(): bool */ public function deleteItem(string $key): bool { - return $this->collection->delete($key); + if (isset($this[$key])) { + unset($this->items[$key]); + + return true; + } + + return false; } /** - * THIS IS NOT TRANSACTION-SAFE * {@inheritdoc} */ public function deleteItems(array $keys): bool { + $clonedItems = $this->items; foreach ($keys as $key) { - if (!$this->deleteItem($key)) { + if (!isset($clonedItems[$key])) { return false; } + unset($clonedItems[$key]); } + $this->items = $clonedItems; return true; } @@ -105,23 +112,25 @@ public function deleteItems(array $keys): bool */ public function save(CacheItemInterface $item): bool { - $this->collection->add($item); + $this->items[] = $item; return true; } /** - * THIS IS NOT TRANSACTION-SAFE * {@inheritdoc} + * @throws InvalidArgumentException */ - public function saveItems(CacheItemCollectionInterface $items): bool + public function saveItems(array $items): bool { + $clonedItems = $this->items; foreach ($items as $item) { - if (!$this->save($item)) { - - return false; + if (!$item instanceof CacheItemInterface) { + throw new InvalidArgumentException('All items must implement' . CacheItemInterface::class); } + $clonedItems[] = $item; } + $this->items = $clonedItems; return true; } diff --git a/src/Adapters/RedisAdapter.php b/src/Adapters/RedisAdapter.php index eb64039..430cbc3 100644 --- a/src/Adapters/RedisAdapter.php +++ b/src/Adapters/RedisAdapter.php @@ -5,7 +5,6 @@ namespace Moon\Cache\Adapters; use Moon\Cache\CacheItem; -use Moon\Cache\Collection\CacheItemCollectionInterface; use Moon\Cache\Exception\InvalidArgumentException; use Moon\Cache\Exception\ItemNotFoundException; use Psr\Cache\CacheItemInterface; @@ -21,6 +20,9 @@ class RedisAdapter extends AbstractAdapter */ private $redis; + /** + * @var string + */ private $separator = '.'; /** @@ -37,20 +39,20 @@ public function __construct(string $poolName, \Redis $redis) /** * {@inheritdoc} */ - public function getItems(array $keys = []): CacheItemCollectionInterface + public function getItems(array $keys = []): array { $this->normalizeKeyName($keys); $items = $this->redis->getMultiple($keys); - $cacheItemCollection = $this->createCacheItemCollection(); + $cacheItems = []; foreach ($items as $k => $item) { if ($item !== false) { - $cacheItemCollection->add($this->createCacheItemFromValue([$keys[$k] => $item])); + $cacheItems[] = $this->createCacheItemFromValue([$keys[$k] => $item]); } } - return $cacheItemCollection; + return $cacheItems; } /** @@ -110,7 +112,7 @@ public function deleteItems(array $keys): bool /** * {@inheritdoc} */ - public function saveItems(CacheItemCollectionInterface $items): bool + public function saveItems(array $items): bool { $mul = $this->redis->multi(); diff --git a/src/CacheItemPool.php b/src/CacheItemPool.php index e0175ea..868122d 100644 --- a/src/CacheItemPool.php +++ b/src/CacheItemPool.php @@ -5,8 +5,6 @@ namespace Moon\Cache; use Moon\Cache\Adapters\AdapterInterface; -use Moon\Cache\Collection\CacheItemCollection; -use Moon\Cache\Collection\CacheItemCollectionInterface; use Psr\Cache\CacheItemInterface; use Psr\Cache\CacheItemPoolInterface; @@ -17,12 +15,12 @@ class CacheItemPool implements CacheItemPoolInterface /** * @var AdapterInterface */ - protected $adapterInterface; + protected $adapter; /** * List of items waiting to be saved * - * @var CacheItemCollectionInterface $deferredItems + * @var array $deferredItems */ protected $deferredItems = []; @@ -35,11 +33,11 @@ class CacheItemPool implements CacheItemPoolInterface /** * CacheItemPool constructor. - * @param AdapterInterface $adapterInterface + * @param AdapterInterface $adapter */ - public function __construct(AdapterInterface $adapterInterface) + public function __construct(AdapterInterface $adapter) { - $this->adapterInterface = $adapterInterface; + $this->adapter = $adapter; } /** @@ -49,19 +47,19 @@ public function getItem($key): CacheItemInterface { $this->validateKey($key); - return $this->adapterInterface->getItem($key); + return $this->adapter->getItem($key); } /** * {@inheritdoc} */ - public function getItems(array $keys = []): CacheItemCollectionInterface + public function getItems(array $keys = []): array { foreach ($keys as $key) { $this->validateKey($key); } - return $this->adapterInterface->getItems($keys); + return $this->adapter->getItems($keys); } /** @@ -71,7 +69,7 @@ public function hasItem($key): bool { $this->validateKey($key); - return $this->adapterInterface->hasItem($key); + return $this->adapter->hasItem($key); } /** @@ -79,7 +77,7 @@ public function hasItem($key): bool */ public function clear(): bool { - return $this->adapterInterface->clear(); + return $this->adapter->clear(); } /** @@ -89,7 +87,7 @@ public function deleteItem($key): bool { $this->validateKey($key); - return $this->adapterInterface->deleteItem($key); + return $this->adapter->deleteItem($key); } /** @@ -100,8 +98,8 @@ public function deleteItems(array $keys): bool foreach ($keys as $key) { $this->validateKey($key); } - - return $this->adapterInterface->deleteItems($keys); + + return $this->adapter->deleteItems($keys); } /** @@ -109,7 +107,7 @@ public function deleteItems(array $keys): bool */ public function save(CacheItemInterface $item): bool { - return $this->adapterInterface->save($item); + return $this->adapter->save($item); } /** @@ -122,12 +120,12 @@ public function saveDeferred(CacheItemInterface $item): bool return false; } - // Create CacheItemCollectionInterface and assign it to deferredItems if is the first time + // Create array and assign it to deferredItems if is the first time if (!$this->deferredItems) { - $this->deferredItems = $this->createCacheItemCollectionInterface(); + $this->deferredItems = []; } - // Add to collection and return + // Add to array and return $this->deferredItems->add($item); return true; @@ -138,7 +136,7 @@ public function saveDeferred(CacheItemInterface $item): bool */ public function commit(): bool { - $isSucceed = $this->adapterInterface->saveItems($this->deferredItems); + $isSucceed = $this->adapter->saveItems($this->deferredItems); // If the commit fails, save isSaveDeferredItemsFailed as true // so that no other saveDeferred can be done as PSR-6 requires @@ -146,18 +144,4 @@ public function commit(): bool return $isSucceed; } - - /** - * Create a CacheItemCollection - * - * @param array $items - * - * @return CacheItemCollectionInterface - * - * @throws InvalidArgumentException - */ - protected function createCacheItemCollectionInterface(array $items = []): CacheItemCollectionInterface - { - return new CacheItemCollection($items); - } } \ No newline at end of file diff --git a/src/Collection/CacheItemCollection.php b/src/Collection/CacheItemCollection.php deleted file mode 100644 index 3a10878..0000000 --- a/src/Collection/CacheItemCollection.php +++ /dev/null @@ -1,85 +0,0 @@ -items[$item->getKey()] = $item; - } - } - - /** - * {@inheritdoc} - */ - public function add(CacheItemInterface $item): void - { - $this->items[$item->getKey()] = $item; - } - - /** - * {@inheritdoc} - */ - public function has(string $key): bool - { - return isset($this->items[$key]); - } - - /** - * {@inheritdoc} - */ - public function get(string $key): CacheItemInterface - { - if ($this->has($key)) { - return $this->items[$key]; - } - - throw new \InvalidArgumentException("The key $key is not available in the collection"); - } - - /** - * {@inheritdoc} - */ - public function delete(string $key): bool - { - if ($this->has($key)) { - unset($this->items[$key]); - - return true; - } - - return false; - } - - /** - * {@inheritdoc} - */ - public function getIterator() - { - foreach ($this->items as $key => $item) { - yield $key => $item; - } - } -} \ No newline at end of file diff --git a/src/Collection/CacheItemCollectionInterface.php b/src/Collection/CacheItemCollectionInterface.php deleted file mode 100644 index bc13c89..0000000 --- a/src/Collection/CacheItemCollectionInterface.php +++ /dev/null @@ -1,48 +0,0 @@ - Date: Fri, 21 Jul 2017 22:31:08 +0200 Subject: [PATCH 5/6] Some refactoring and added tests except for adapters --- src/Adapters/AbstractAdapter.php | 2 +- src/Adapters/AdapterInterface.php | 7 +- src/Adapters/DbalAdapter.php | 8 +- src/Adapters/FilesystemAdapter.php | 5 + src/Adapters/MemcacheAdapter.php | 6 +- src/Adapters/MemoryAdapter.php | 4 +- src/Adapters/RedisAdapter.php | 8 + src/CacheItemPool.php | 19 +- src/Exception/InvalidArgumentException.php | 22 ++ src/Exception/ItemNotFoundException.php | 4 +- src/Helper/CreateTableHelper.php | 3 +- tests/Unit/CacheItemPoolTest.php | 285 ++++++++++++++++++ tests/Unit/CacheItemTest.php | 39 ++- .../InvalidArgumentExceptionTest.php | 29 ++ tests/Unit/Helper/CreateTableHelperTest.php | 96 ++++++ 15 files changed, 496 insertions(+), 41 deletions(-) create mode 100644 tests/Unit/CacheItemPoolTest.php create mode 100644 tests/Unit/Exception/InvalidArgumentExceptionTest.php create mode 100644 tests/Unit/Helper/CreateTableHelperTest.php diff --git a/src/Adapters/AbstractAdapter.php b/src/Adapters/AbstractAdapter.php index 1cae09b..f15e21b 100644 --- a/src/Adapters/AbstractAdapter.php +++ b/src/Adapters/AbstractAdapter.php @@ -41,7 +41,7 @@ protected function retrieveExpiringDateFromCacheItem(CacheItemInterface $cacheIt return $expirationDate; } catch (\Exception $e) { throw new InvalidArgumentException( - "The CacheItemInterface object haven't any {$this->expirationParameterName} attribute.", 0, $e + "The CacheItemInterface object haven't any {$this->expirationParameterName} attribute.", null, 0, $e ); } } diff --git a/src/Adapters/AdapterInterface.php b/src/Adapters/AdapterInterface.php index 4a42c48..4323758 100644 --- a/src/Adapters/AdapterInterface.php +++ b/src/Adapters/AdapterInterface.php @@ -4,6 +4,7 @@ namespace Moon\Cache\Adapters; +use Moon\Cache\CacheItem; use Moon\Cache\Exception\InvalidArgumentException; use Moon\Cache\Exception\ItemNotFoundException; use Psr\Cache\CacheItemInterface; @@ -26,11 +27,10 @@ public function getItem(string $key): CacheItemInterface; * * @param string[] $keys * - * @return array + * @return CacheItem[] */ public function getItems(array $keys = []): array; - /** * Return true if CacheItem exists instead false * @@ -65,7 +65,6 @@ public function deleteItem(string $key): bool; */ public function deleteItems(array $keys): bool; - /** * Add a new CacheItem to the pool * @@ -78,7 +77,7 @@ public function save(CacheItemInterface $item): bool; /** * Add new CacheItems to the pool * - * @param array $items + * @param CacheItem[] $items * * @return bool * diff --git a/src/Adapters/DbalAdapter.php b/src/Adapters/DbalAdapter.php index a8153ef..a2733dd 100644 --- a/src/Adapters/DbalAdapter.php +++ b/src/Adapters/DbalAdapter.php @@ -47,10 +47,12 @@ class DbalAdapter extends AbstractAdapter /** * DbalAdapter constructor. + * * @param string $poolName * @param Connection $connection * @param array $tableOptions * @param null $expirationDateFormat + * * @throws InvalidArgumentException */ public function __construct(string $poolName, Connection $connection, array $tableOptions = [], $expirationDateFormat = null) @@ -64,7 +66,7 @@ public function __construct(string $poolName, Connection $connection, array $tab $checkValidFormat = \DateTimeImmutable::createFromFormat($this->expirationDateFormat, 'now'); unset($checkValidFormat); } catch (\Exception $e) { - throw new InvalidArgumentException('Invalid expiration column format', 0, $e); + throw new InvalidArgumentException('Invalid expiration column format', null, 0, $e); } } @@ -217,6 +219,10 @@ public function saveItems(array $items): bool $this->connection->beginTransaction(); try { foreach ($items as $item) { + if (!$item instanceof CacheItemInterface) { + throw new InvalidArgumentException('All items must implement' . CacheItemInterface::class, $item); + } + if (!$this->save($item)) { $this->connection->rollBack(); diff --git a/src/Adapters/FilesystemAdapter.php b/src/Adapters/FilesystemAdapter.php index 56bb15c..847a700 100644 --- a/src/Adapters/FilesystemAdapter.php +++ b/src/Adapters/FilesystemAdapter.php @@ -25,6 +25,7 @@ class FilesystemAdapter extends AbstractAdapter /** * FileSystemAdapter constructor. + * * @param string $poolName * @param null|string $directory */ @@ -169,6 +170,10 @@ public function save(CacheItemInterface $item): bool public function saveItems(array $items): bool { foreach ($items as $item) { + if (!$item instanceof CacheItemInterface) { + throw new InvalidArgumentException('All items must implement' . CacheItemInterface::class, $item); + } + if (!$this->save($item)) { return false; } diff --git a/src/Adapters/MemcacheAdapter.php b/src/Adapters/MemcacheAdapter.php index c679469..90f76e6 100644 --- a/src/Adapters/MemcacheAdapter.php +++ b/src/Adapters/MemcacheAdapter.php @@ -30,6 +30,7 @@ class MemcacheAdapter extends AbstractAdapter /** * MemcacheAdapter constructor. + * * @param string $poolName * @param \Memcached $memcached * @param string $separator @@ -143,8 +144,11 @@ public function saveItems(array $items): bool { $elaboratedItems = []; - /** @var CacheItemInterface $item */ foreach ($items as $k => $item) { + if (!$item instanceof CacheItemInterface) { + throw new InvalidArgumentException('All items must implement' . CacheItemInterface::class, $item); + } + $elaboratedItems[$this->poolName . $this->separator . $item->getKey()] = [ serialize($item->get()), serialize($this->retrieveExpiringDateFromCacheItem($item)) ]; diff --git a/src/Adapters/MemoryAdapter.php b/src/Adapters/MemoryAdapter.php index 698f0be..a877fc8 100644 --- a/src/Adapters/MemoryAdapter.php +++ b/src/Adapters/MemoryAdapter.php @@ -17,6 +17,7 @@ class MemoryAdapter extends AbstractAdapter /** * MemoryAdapter constructor. + * * @param array $items */ public function __construct(array $items) @@ -126,8 +127,9 @@ public function saveItems(array $items): bool $clonedItems = $this->items; foreach ($items as $item) { if (!$item instanceof CacheItemInterface) { - throw new InvalidArgumentException('All items must implement' . CacheItemInterface::class); + throw new InvalidArgumentException('All items must implement' . CacheItemInterface::class, $item); } + $clonedItems[] = $item; } $this->items = $clonedItems; diff --git a/src/Adapters/RedisAdapter.php b/src/Adapters/RedisAdapter.php index 430cbc3..20cd851 100644 --- a/src/Adapters/RedisAdapter.php +++ b/src/Adapters/RedisAdapter.php @@ -27,6 +27,7 @@ class RedisAdapter extends AbstractAdapter /** * RedisAdapter constructor. + * * @param string $poolName * @param \Redis $redis */ @@ -86,6 +87,7 @@ public function getItem(string $key): CacheItemInterface public function clear(): bool { $keys = $this->redis->keys($this->poolName . $this->separator . '*'); + return (bool)$this->redis->delete($keys); } @@ -119,13 +121,19 @@ public function saveItems(array $items): bool try { /** @var CacheItemInterface $item */ foreach ($items as $k => $item) { + if (!$item instanceof CacheItemInterface) { + throw new InvalidArgumentException('All items must implement' . CacheItemInterface::class, $item); + } + $key = $this->poolName . $this->separator . $item->getKey(); $value = [$item->get(), $this->retrieveExpiringDateFromCacheItem($item)]; $this->redis->set($key, serialize($value)); } + return !in_array(false, array_values($mul->exec()), true); } catch (\Exception $e) { $mul->discard(); + return false; } } diff --git a/src/CacheItemPool.php b/src/CacheItemPool.php index 868122d..44798f7 100644 --- a/src/CacheItemPool.php +++ b/src/CacheItemPool.php @@ -33,6 +33,7 @@ class CacheItemPool implements CacheItemPoolInterface /** * CacheItemPool constructor. + * * @param AdapterInterface $adapter */ public function __construct(AdapterInterface $adapter) @@ -120,13 +121,7 @@ public function saveDeferred(CacheItemInterface $item): bool return false; } - // Create array and assign it to deferredItems if is the first time - if (!$this->deferredItems) { - $this->deferredItems = []; - } - - // Add to array and return - $this->deferredItems->add($item); + $this->deferredItems[] = $item; return true; } @@ -138,10 +133,16 @@ public function commit(): bool { $isSucceed = $this->adapter->saveItems($this->deferredItems); + if ($isSucceed === true) { + $this->deferredItems = []; + + return true; + } + // If the commit fails, save isSaveDeferredItemsFailed as true // so that no other saveDeferred can be done as PSR-6 requires - $this->isSaveDeferredItemsFailed = !$isSucceed; + $this->isSaveDeferredItemsFailed = true; - return $isSucceed; + return false; } } \ No newline at end of file diff --git a/src/Exception/InvalidArgumentException.php b/src/Exception/InvalidArgumentException.php index e87ee57..d40f4b3 100644 --- a/src/Exception/InvalidArgumentException.php +++ b/src/Exception/InvalidArgumentException.php @@ -4,6 +4,28 @@ namespace Moon\Cache\Exception; +use Throwable; + class InvalidArgumentException extends \InvalidArgumentException implements \Psr\Cache\InvalidArgumentException { + /** + * @var mixed $invalidCacheItem + */ + private $invalidCacheItem; + + public function __construct($message = '', $invalidCacheItem = null, $code = 0, Throwable $previous = null) + { + parent::__construct($message, $code, $previous); + $this->invalidCacheItem = $invalidCacheItem; + } + + /** + * Get the invalid CacheItem + * + * @return mixed|null + */ + public function getInvalidCacheItem() + { + return $this->invalidCacheItem; + } } \ No newline at end of file diff --git a/src/Exception/ItemNotFoundException.php b/src/Exception/ItemNotFoundException.php index 9cf7672..58e8074 100644 --- a/src/Exception/ItemNotFoundException.php +++ b/src/Exception/ItemNotFoundException.php @@ -4,8 +4,8 @@ namespace Moon\Cache\Exception; -use Psr\Cache\InvalidArgumentException; +use Psr\Cache\CacheException; -class ItemNotFoundException extends \InvalidArgumentException implements InvalidArgumentException +class ItemNotFoundException extends \Exception implements CacheException { } \ No newline at end of file diff --git a/src/Helper/CreateTableHelper.php b/src/Helper/CreateTableHelper.php index 4d3d881..60705cb 100644 --- a/src/Helper/CreateTableHelper.php +++ b/src/Helper/CreateTableHelper.php @@ -6,7 +6,6 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\DBALException; -use Doctrine\DBAL\Schema\Schema; class CreateTableHelper { @@ -40,7 +39,7 @@ public function generate(Connection $connection, array $tableOptions = []): void $this->tableOptions = array_merge($this->tableOptions, $tableOptions); // Build query for create table - $schema = new Schema(); + $schema = $connection->getSchemaManager()->createSchema(); $myTable = $schema->createTable("`{$this->tableOptions['tableName']}`"); $myTable->addColumn("`{$this->tableOptions['idColumn']}`", 'bigint', ['unsigned' => true, 'autoincrement' => true]); $myTable->addColumn("`{$this->tableOptions['keyColumn']}`", 'string', ['notnull' => false]); diff --git a/tests/Unit/CacheItemPoolTest.php b/tests/Unit/CacheItemPoolTest.php new file mode 100644 index 0000000..97549db --- /dev/null +++ b/tests/Unit/CacheItemPoolTest.php @@ -0,0 +1,285 @@ +prophesize(AdapterInterface::class)->reveal(); + $pool = new CacheItemPool($adapter); + $reflectionProperty = new \ReflectionProperty(CacheItemPool::class, 'adapter'); + $reflectionProperty->setAccessible(true); + $this->assertSame($adapter, $reflectionProperty->getValue($pool)); + } + + public function testItemIsProperlyRetrivedFromPool() + { + $adapter = $this->prophesize(AdapterInterface::class); + $cacheItem = $this->prophesize(CacheItemInterface::class)->reveal(); + $adapter->getItem('key')->shouldBeCalled(1)->willReturn($cacheItem); + $pool = new CacheItemPool($adapter->reveal()); + $this->assertSame($cacheItem, $pool->getItem('key')); + } + + /** + * @dataProvider invalidLengthKeyDataProvider + */ + public function testGetItemByInvalidKeyLegthThrowInvalidArgumentExcpetion($key) + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("The key '$key' must be length from 1 up to 64 characters"); + $adapter = $this->prophesize(AdapterInterface::class)->reveal(); + $pool = new CacheItemPool($adapter); + $pool->getItem($key); + } + + /** + * @dataProvider invalidCharKeyDataProvider + */ + public function testGetItemByInvalidKeyCharsThrowInvalidArgumentExcpetion($key) + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("The key '$key' contains invalid characters. Supported characters are A-Z a-z 0-9 _ and ."); + $adapter = $this->prophesize(AdapterInterface::class)->reveal(); + $pool = new CacheItemPool($adapter); + $pool->getItem($key); + } + + public function testItemNotFoundExceptionIsThrownGettingAnItemNotSaved() + { + $this->expectException(ItemNotFoundException::class); + $adapter = $this->prophesize(AdapterInterface::class); + $adapter->getItem('key')->willThrow(ItemNotFoundException::class); + $pool = new CacheItemPool($adapter->reveal()); + $pool->getItem('key'); + } + + public function testGetItemsReturnArray() + { + $inArray = ['an', 'input', 'array']; + $outArray = ['an', 'output', 'array']; + $adapter = $this->prophesize(AdapterInterface::class); + $adapter->getItems($inArray)->shouldBeCalled(1)->willReturn($outArray); + $pool = new CacheItemPool($adapter->reveal()); + $this->assertSame($outArray, $pool->getItems($inArray)); + } + + /** + * @dataProvider invalidLengthKeyDataProvider + */ + public function testGetItemsByInvalidKeyLegthThrowInvalidArgumentException($key) + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("The key '$key' must be length from 1 up to 64 characters"); + $adapter = $this->prophesize(AdapterInterface::class)->reveal(); + $pool = new CacheItemPool($adapter); + $pool->getItems([$key]); + } + + /** + * @dataProvider invalidCharKeyDataProvider + */ + public function testGetItemsByInvalidKeyCharsThrowInvalidArgumentExcpetion($key) + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("The key '$key' contains invalid characters. Supported characters are A-Z a-z 0-9 _ and ."); + $adapter = $this->prophesize(AdapterInterface::class)->reveal(); + $pool = new CacheItemPool($adapter); + $pool->getItems([$key]); + } + + public function testHasItems() + { + $adapter = $this->prophesize(AdapterInterface::class); + $adapter->hasItem('existingItem')->shouldBeCalled(1)->willReturn(true); + $adapter->hasItem('notExistingItem')->shouldBeCalled(1)->willReturn(false); + $pool = new CacheItemPool($adapter->reveal()); + $this->assertTrue($pool->hasItem('existingItem')); + $this->assertFalse($pool->hasItem('notExistingItem')); + } + + /** + * @dataProvider invalidLengthKeyDataProvider + */ + public function testHasItemByInvalidKeyLegthThrowInvalidArgumentExcpetion($key) + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("The key '$key' must be length from 1 up to 64 characters"); + $adapter = $this->prophesize(AdapterInterface::class)->reveal(); + $pool = new CacheItemPool($adapter); + $pool->hasItem($key); + } + + /** + * @dataProvider invalidCharKeyDataProvider + */ + public function testHasItemByInvalidKeyCharsThrowInvalidArgumentExcpetion($key) + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("The key '$key' contains invalid characters. Supported characters are A-Z a-z 0-9 _ and ."); + $adapter = $this->prophesize(AdapterInterface::class)->reveal(); + $pool = new CacheItemPool($adapter); + $pool->hasItem($key); + } + + public function testClearMethod() + { + $adapter = $this->prophesize(AdapterInterface::class); + $adapter->clear()->shouldBeCalled(1); + $pool = new CacheItemPool($adapter->reveal()); + $pool->clear(); + } + + public function testDeleteItem() + { + $adapter = $this->prophesize(AdapterInterface::class); + $adapter->deleteItem('existingItem')->shouldBeCalled(1)->willReturn(true); + $adapter->deleteItem('notExistingItem')->shouldBeCalled(1)->willReturn(false); + $pool = new CacheItemPool($adapter->reveal()); + $this->assertTrue($pool->deleteItem('existingItem')); + $this->assertFalse($pool->deleteItem('notExistingItem')); + } + + /** + * @dataProvider invalidLengthKeyDataProvider + */ + public function testDeleteItemByInvalidKeyLegthThrowInvalidArgumentExcpetion($key) + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("The key '$key' must be length from 1 up to 64 characters"); + $adapter = $this->prophesize(AdapterInterface::class)->reveal(); + $pool = new CacheItemPool($adapter); + $pool->deleteItem($key); + } + + /** + * @dataProvider invalidCharKeyDataProvider + */ + public function testDeleteItemByInvalidKeyCharsThrowInvalidArgumentExcpetion($key) + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("The key '$key' contains invalid characters. Supported characters are A-Z a-z 0-9 _ and ."); + $adapter = $this->prophesize(AdapterInterface::class)->reveal(); + $pool = new CacheItemPool($adapter); + $pool->deleteItem($key); + } + + public function testDeleteItems() + { + $adapter = $this->prophesize(AdapterInterface::class); + $adapter->deleteItems(['existingItem'])->shouldBeCalled(1)->willReturn(true); + $adapter->deleteItems(['notExistingItem'])->shouldBeCalled(1)->willReturn(false); + $pool = new CacheItemPool($adapter->reveal()); + $this->assertTrue($pool->deleteItems(['existingItem'])); + $this->assertFalse($pool->deleteItems(['notExistingItem'])); + } + + /** + * @dataProvider invalidLengthKeyDataProvider + */ + public function testDeleteItemsByInvalidKeyLegthThrowInvalidArgumentExcpetion($key) + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("The key '$key' must be length from 1 up to 64 characters"); + $adapter = $this->prophesize(AdapterInterface::class)->reveal(); + $pool = new CacheItemPool($adapter); + $pool->deleteItems([$key]); + } + + /** + * @dataProvider invalidCharKeyDataProvider + */ + public function testDeleteItemsByInvalidKeyCharsThrowInvalidArgumentExcpetion($key) + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("The key '$key' contains invalid characters. Supported characters are A-Z a-z 0-9 _ and ."); + $adapter = $this->prophesize(AdapterInterface::class)->reveal(); + $pool = new CacheItemPool($adapter); + $pool->deleteItems([$key]); + } + + public function testSaveItem() + { + $adapter = $this->prophesize(AdapterInterface::class); + $goodCacheItem = $this->prophesize(CacheItemInterface::class)->reveal(); + $badCacheItem = $this->prophesize(CacheItemInterface::class)->reveal(); + $adapter->save($goodCacheItem)->shouldBeCalled(1)->willReturn(true); + $adapter->save($badCacheItem)->shouldBeCalled(1)->willReturn(false); + $pool = new CacheItemPool($adapter->reveal()); + $this->assertTrue($pool->save($goodCacheItem)); + $this->assertFalse($pool->save($badCacheItem)); + } + + public function testSaveDeferredReturnFalseForSaveFail() + { + $adapter = $this->prophesize(AdapterInterface::class)->reveal(); + $cacheItem = $this->prophesize(CacheItemInterface::class)->reveal(); + $pool = new CacheItemPool($adapter); + $reflectionProperty = new \ReflectionProperty($pool, 'isSaveDeferredItemsFailed'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($pool, true); + $this->assertFalse($pool->saveDeferred($cacheItem)); + } + + public function testSaveDeferredAddTheNewItemToTheDeferredItemsList() + { + $adapter = $this->prophesize(AdapterInterface::class)->reveal(); + $cacheItem = $this->prophesize(CacheItemInterface::class)->reveal(); + $pool = new CacheItemPool($adapter); + $this->assertTrue($pool->saveDeferred($cacheItem)); + $reflectionProperty = new \ReflectionProperty($pool, 'deferredItems'); + $reflectionProperty->setAccessible(true); + $this->assertSame([$cacheItem], $reflectionProperty->getValue($pool)); + } + + public function testCommitFails() + { + $cacheItem = $this->prophesize(CacheItemInterface::class)->reveal(); + $adapter = $this->prophesize(AdapterInterface::class); + $adapter->saveItems([$cacheItem])->shouldBeCalled(1)->willReturn(false); + $pool = new CacheItemPool($adapter->reveal()); + $reflectionPropertyDeferredItems = new \ReflectionProperty(CacheItemPool::class, 'deferredItems'); + $reflectionPropertyDeferredItems->setAccessible(true); + $reflectionPropertyDeferredItems->setValue($pool, [$cacheItem]); + $this->assertFalse($pool->commit()); + $reflectionPropertyIsSaveDeferredItemsFailed = new \ReflectionProperty($pool, 'isSaveDeferredItemsFailed'); + $reflectionPropertyIsSaveDeferredItemsFailed->setAccessible(true); + $this->assertSame([$cacheItem], $reflectionPropertyDeferredItems->getValue($pool)); + $this->assertTrue($reflectionPropertyIsSaveDeferredItemsFailed->getValue($pool)); + } + + public function testCommitSucceed() + { + $cacheItem = $this->prophesize(CacheItemInterface::class)->reveal(); + $adapter = $this->prophesize(AdapterInterface::class); + $adapter->saveItems([$cacheItem])->shouldBeCalled(1)->willReturn(true); + $pool = new CacheItemPool($adapter->reveal()); + $reflectionPropertyDeferredItems = new \ReflectionProperty(CacheItemPool::class, 'deferredItems'); + $reflectionPropertyDeferredItems->setAccessible(true); + $reflectionPropertyDeferredItems->setValue($pool, [$cacheItem]); + $this->assertTrue($pool->commit()); + $reflectionPropertyIsSaveDeferredItemsFailed = new \ReflectionProperty($pool, 'isSaveDeferredItemsFailed'); + $reflectionPropertyIsSaveDeferredItemsFailed->setAccessible(true); + $this->assertSame([], $reflectionPropertyDeferredItems->getValue($pool)); + $this->assertFalse($reflectionPropertyIsSaveDeferredItemsFailed->getValue($pool)); + } + + public function invalidLengthKeyDataProvider() + { + return [[''], ['qqedjspjasopdjopasjqqedjspjasopdjopasjqqedjspjasopdjopasjqqedjspjasopdjopasjqqedjspjasopdjopasjqqedjspjasopdjopasjqqedjs']]; + } + + public function invalidCharKeyDataProvider() + { + return [[' '], ['ès + àò']]; + } +} \ No newline at end of file diff --git a/tests/Unit/CacheItemTest.php b/tests/Unit/CacheItemTest.php index e62a6ba..b6b8c39 100644 --- a/tests/Unit/CacheItemTest.php +++ b/tests/Unit/CacheItemTest.php @@ -22,7 +22,7 @@ public function testInvalidLegthKeyThrowAnException($key) /** * @dataProvider invalidCharKeyDataProvider */ - public function testInvalidCharKeyThrowAnException($key) + public function testInvalidCharsThrowAnException($key) { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage("The key '$key' contains invalid characters. Supported characters are A-Z a-z 0-9 _ and ."); @@ -36,7 +36,7 @@ public function testThatValueAndKeyAreProperlySet() $this->assertSame($item->get(), 'a value'); } - public function testThatSetMethodCreateANewObjectWithADifferentValue() + public function testThatSetMethodReturnAnObjectWithADifferentValue() { $item = new CacheItem('a_key', 'a value'); $itemTwo = $item->set('another_value'); @@ -46,7 +46,7 @@ public function testThatSetMethodCreateANewObjectWithADifferentValue() /** * @dataProvider expirationDateDataProvider */ - public function testDefaultException($expectedDate, $date) + public function testDefaultExpirationDateIsProperlySet($expectedDate, $date) { $reflectionExpiration = new \ReflectionProperty(CacheItem::class, 'expiration'); $reflectionExpiration->setAccessible(true); @@ -56,7 +56,7 @@ public function testDefaultException($expectedDate, $date) } /** - * @dataProvider valueAcceptedByExpiresAtDataProvider + * @dataProvider expiresAtDataProvider */ public function testExpiresAt($expectedDate, $date) { @@ -77,7 +77,7 @@ public function testIsHit() } /** - * @dataProvider valueInvalidByExpiresAtDataProvider + * @dataProvider invalidExpiresAtValuesDataProvider */ public function testExpiresAtThrowInvalidArgumentExcpetion($invalidDate) { @@ -87,18 +87,6 @@ public function testExpiresAtThrowInvalidArgumentExcpetion($invalidDate) $item->expiresAt($invalidDate); } - - /** - * @dataProvider valueInvalidByExpiresAfterDataProvider - */ - public function testExpiresAfterThrowInvalidArgumentExcpetion($invalidDate) - { - $this->expectException(InvalidArgumentException::class); - - $item = new CacheItem('key', ''); - $item->expiresAfter($invalidDate); - } - /** * @dataProvider valueAcceptedByExpiresAfterDataProvider */ @@ -112,6 +100,17 @@ public function testExpiresAfter($expectedDate, $date) $this->assertEquals($expectedDate->getTimestamp(), $returnedDate->getTimestamp(), '', 3); } + /** + * @dataProvider invalidExpiresAfterValuesDataProvider + */ + public function testExpiresAfterThrowInvalidArgumentExcpetion($invalidDate) + { + $this->expectException(InvalidArgumentException::class); + + $item = new CacheItem('key', ''); + $item->expiresAfter($invalidDate); + } + public function valueAcceptedByExpiresAfterDataProvider() { return [ @@ -121,7 +120,7 @@ public function valueAcceptedByExpiresAfterDataProvider() ]; } - public function valueInvalidByExpiresAfterDataProvider() + public function invalidExpiresAfterValuesDataProvider() { return [ [[1, 2, 3]], @@ -131,7 +130,7 @@ public function valueInvalidByExpiresAfterDataProvider() ]; } - public function valueInvalidByExpiresAtDataProvider() + public function invalidExpiresAtValuesDataProvider() { return [ [[1, 2, 3]], @@ -141,7 +140,7 @@ public function valueInvalidByExpiresAtDataProvider() ]; } - public function valueAcceptedByExpiresAtDataProvider() + public function expiresAtDataProvider() { return [ [new \DateTimeImmutable('now'), new \DateTime('now')], diff --git a/tests/Unit/Exception/InvalidArgumentExceptionTest.php b/tests/Unit/Exception/InvalidArgumentExceptionTest.php new file mode 100644 index 0000000..6b1a8bb --- /dev/null +++ b/tests/Unit/Exception/InvalidArgumentExceptionTest.php @@ -0,0 +1,29 @@ +assertSame($invalidCacheItem, $exception->getInvalidCacheItem()); + } + + public function invalidCacheItemDataProvider(): array + { + return [ + [1], + ['string'], + [['an', 'array']], + [null], + [$this->prophesize(\Moon\Cache\CacheItem::class)->reveal()] + ]; + } +} \ No newline at end of file diff --git a/tests/Unit/Helper/CreateTableHelperTest.php b/tests/Unit/Helper/CreateTableHelperTest.php new file mode 100644 index 0000000..d32129d --- /dev/null +++ b/tests/Unit/Helper/CreateTableHelperTest.php @@ -0,0 +1,96 @@ +prophesize(\Doctrine\DBAL\Schema\Table::class); + $table->addColumn("`{$expectedTableOptions['idColumn']}`", 'bigint', ['unsigned' => true, 'autoincrement' => true])->shouldBeCalled(1); + $table->addColumn("`{$expectedTableOptions['keyColumn']}`", 'string', ['notnull' => false])->shouldBeCalled(1); + $table->addColumn("`{$expectedTableOptions['valueColumn']}`", 'text')->shouldBeCalled(1); + $table->addColumn("`{$expectedTableOptions['poolNameColumn']}`", 'string', ['notnull' => false])->shouldBeCalled(1); + $table->addColumn("`{$expectedTableOptions['expirationColumn']}`", 'datetime', ['notnull' => false])->shouldBeCalled(1); + $table->setPrimaryKey(["`{$expectedTableOptions['idColumn']}`"], true)->shouldBeCalled(1); + $table->addUniqueIndex(["`{$expectedTableOptions['keyColumn']}`", "`{$expectedTableOptions['poolNameColumn']}`"], 'key_pool')->shouldBeCalled(1); + + $schema = $this->prophesize(\Doctrine\DBAL\Schema\Schema::class); + $schema->createTable("`{$expectedTableOptions['tableName']}`")->shouldBeCalled(1)->willReturn($table->reveal()); + $schema->toSql(\Prophecy\Argument::type(Doctrine\DBAL\Platforms\AbstractPlatform::class))->shouldBeCalled(1)->willReturn(['first', 'second']); + + $schemaManager = $this->prophesize(\Doctrine\DBAL\Schema\AbstractSchemaManager::class); + $schemaManager->createSchema()->shouldBeCalled(1)->willReturn($schema->reveal()); + + $connection = $this->prophesize(\Doctrine\DBAL\Connection::class); + $connection->exec(\Prophecy\Argument::type('string'))->shouldBeCalled(1)->willReturn($schemaManager->reveal()); + $connection->getSchemaManager()->shouldBeCalled(1)->willReturn($schemaManager->reveal()); + $connection->getDatabasePlatform()->shouldBeCalled(1)->willReturn($this->prophesize(Doctrine\DBAL\Platforms\AbstractPlatform::class)->reveal()); + + $helper = new CreateTableHelper(); + $helper->generate($connection->reveal(), $tableOptions); + } + + public function tableOptionsDataProvider() + { + $one = [ + 'tableName' => 'moon_cache', + 'idColumn' => 'id', + 'keyColumn' => 'key', + 'valueColumn' => 'value', + 'poolNameColumn' => 'pool_name', + 'expirationColumn' => 'expires_at' + ]; + + $two = [ + 'tableName' => 'those', + 'idColumn' => 'are', + 'keyColumn' => 'some', + 'valueColumn' => 'random', + 'poolNameColumn' => 'values', + 'expirationColumn' => 'ok' + ]; + + $three = [ + 'tableName' => 'only', + 'poolNameColumn' => 'three', + 'expirationColumn' => 'columns' + ]; + + + $expectedOne = [ + 'tableName' => 'moon_cache', + 'idColumn' => 'id', + 'keyColumn' => 'key', + 'valueColumn' => 'value', + 'poolNameColumn' => 'pool_name', + 'expirationColumn' => 'expires_at' + ]; + + $expectedTwo = [ + 'tableName' => 'those', + 'idColumn' => 'are', + 'keyColumn' => 'some', + 'valueColumn' => 'random', + 'poolNameColumn' => 'values', + 'expirationColumn' => 'ok' + ]; + + $expectedThree = [ + 'tableName' => 'only', + 'idColumn' => 'id', + 'keyColumn' => 'key', + 'valueColumn' => 'value', + 'poolNameColumn' => 'three', + 'expirationColumn' => 'columns' + ]; + + return [[$one, $expectedOne], [$two, $expectedTwo], [$three, $expectedThree]]; + } +} \ No newline at end of file From e9704437ccbc6fcccc51dd82b3485a2d4ee13ea8 Mon Sep 17 00:00:00 2001 From: Damiano Petrungaro Date: Sun, 23 Jul 2017 23:07:20 +0200 Subject: [PATCH 6/6] Added tests for MemoryAdapter --- composer.json | 13 +- src/Adapters/MemoryAdapter.php | 18 +- tests/Unit/Adapter/MemoryAdapterTest.php | 158 ++++++++++++++++++ .../InvalidArgumentExceptionTest.php | 6 +- tests/Unit/Helper/CreateTableHelperTest.php | 23 ++- 5 files changed, 191 insertions(+), 27 deletions(-) create mode 100644 tests/Unit/Adapter/MemoryAdapterTest.php diff --git a/composer.json b/composer.json index 5d80817..673dfe6 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "moon/cache", - "description": "A very simple Cache with support for PSR-6", + "description": "Cache supporting PSR-6", "license": "MIT", "homepage": "https://www.moon-php.com/", "require": { @@ -17,7 +17,7 @@ "authors": [ { "name": "Damiano Petrungaro", - "email": "damiano.petrungaro@qwentes.it" + "email": "damiano.petrungaro@gmail.com" } ], "autoload": { @@ -29,5 +29,12 @@ "psr-4": { "Moon\\Cache\\Unit\\": "tests/Unit/" } - } + }, + "prefer-stable": true, + "keywords": [ + "cache", + "caching", + "psr-6", + "moon" + ] } diff --git a/src/Adapters/MemoryAdapter.php b/src/Adapters/MemoryAdapter.php index a877fc8..62012e5 100644 --- a/src/Adapters/MemoryAdapter.php +++ b/src/Adapters/MemoryAdapter.php @@ -13,17 +13,7 @@ class MemoryAdapter extends AbstractAdapter /** * @var array */ - private $items; - - /** - * MemoryAdapter constructor. - * - * @param array $items - */ - public function __construct(array $items) - { - $this->items = $items; - } + private $items = []; /** * {@inheritdoc} @@ -81,7 +71,7 @@ public function clear(): bool */ public function deleteItem(string $key): bool { - if (isset($this[$key])) { + if (isset($this->items[$key])) { unset($this->items[$key]); return true; @@ -113,7 +103,7 @@ public function deleteItems(array $keys): bool */ public function save(CacheItemInterface $item): bool { - $this->items[] = $item; + $this->items[$item->getKey()] = $item; return true; } @@ -130,7 +120,7 @@ public function saveItems(array $items): bool throw new InvalidArgumentException('All items must implement' . CacheItemInterface::class, $item); } - $clonedItems[] = $item; + $clonedItems[$item->getKey()] = $item; } $this->items = $clonedItems; diff --git a/tests/Unit/Adapter/MemoryAdapterTest.php b/tests/Unit/Adapter/MemoryAdapterTest.php new file mode 100644 index 0000000..2e9b77c --- /dev/null +++ b/tests/Unit/Adapter/MemoryAdapterTest.php @@ -0,0 +1,158 @@ +prophesize(CacheItem::class)->reveal(); + $adapter = new MemoryAdapter(); + $reflectionProperty = new ReflectionProperty(MemoryAdapter::class, 'items'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($adapter, ['a key' => $itemCache]); + + $this->assertSame($itemCache, $adapter->getItem('a key')); + } + + public function testGetItemThrowNotFoundItem() + { + $this->expectException(ItemNotFoundException::class); + $adapter = new MemoryAdapter(); + $adapter->getItem('a key'); + } + + public function testGetItems() + { + $itemCacheOne = $this->prophesize(CacheItem::class)->reveal(); + $itemCacheTwo = $this->prophesize(CacheItem::class)->reveal(); + $itemCacheThree = $this->prophesize(CacheItem::class)->reveal(); + $items = ['one' => $itemCacheOne, 'two' => $itemCacheTwo, 'three' => $itemCacheThree]; + + $adapter = new MemoryAdapter(); + $reflectionProperty = new ReflectionProperty(MemoryAdapter::class, 'items'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($adapter, $items); + + $this->assertSame([$itemCacheOne, $itemCacheThree], $adapter->getItems(['one', 'three'])); + } + + public function testGetItemsReturnEmptyArray() + { + $adapter = new MemoryAdapter(); + $this->assertSame([], $adapter->getItems(['keyOne', 'keyTwo'])); + } + + public function testHasItem() + { + $itemCache = $this->prophesize(CacheItem::class)->reveal(); + $adapter = new MemoryAdapter(); + $reflectionProperty = new ReflectionProperty(MemoryAdapter::class, 'items'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($adapter, ['one' => $itemCache]); + + $this->assertTrue($adapter->hasItem('one')); + $this->assertFalse($adapter->hasItem('two')); + } + + public function testClearItem() + { + $itemCache = $this->prophesize(CacheItem::class)->reveal(); + $adapter = new MemoryAdapter(); + $reflectionProperty = new ReflectionProperty(MemoryAdapter::class, 'items'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($adapter, ['one' => $itemCache]); + $adapter->clear(); + $this->assertSame([], $reflectionProperty->getValue($adapter)); + } + + public function testDeleteItem() + { + $itemCacheOne = $this->prophesize(CacheItem::class)->reveal(); + $itemCacheTwo = $this->prophesize(CacheItem::class)->reveal(); + $itemCacheThree = $this->prophesize(CacheItem::class)->reveal(); + $items = ['one' => $itemCacheOne, 'two' => $itemCacheTwo, 'three' => $itemCacheThree]; + + $adapter = new MemoryAdapter(); + $reflectionProperty = new ReflectionProperty(MemoryAdapter::class, 'items'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($adapter, $items); + + $this->assertTrue($adapter->deleteItem('one')); + $this->assertSame(['two' => $itemCacheTwo, 'three' => $itemCacheThree], $reflectionProperty->getValue($adapter)); + $this->assertFalse($adapter->deleteItem('one')); + } + + public function testDeleteItems() + { + $itemCacheOne = $this->prophesize(CacheItem::class)->reveal(); + $itemCacheTwo = $this->prophesize(CacheItem::class)->reveal(); + $itemCacheThree = $this->prophesize(CacheItem::class)->reveal(); + $itemCacheFour = $this->prophesize(CacheItem::class)->reveal(); + $items = ['one' => $itemCacheOne, 'two' => $itemCacheTwo, 'three' => $itemCacheThree, 'four' => $itemCacheFour]; + + $adapter = new MemoryAdapter(); + $reflectionProperty = new ReflectionProperty(MemoryAdapter::class, 'items'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($adapter, $items); + + $this->assertTrue($adapter->deleteItems(['two', 'three'])); + $this->assertSame(['one' => $itemCacheOne, 'four' => $itemCacheFour], $reflectionProperty->getValue($adapter)); + $this->assertFalse($adapter->deleteItems(['four', 'two'])); + $this->assertSame(['one' => $itemCacheOne, 'four' => $itemCacheFour], $reflectionProperty->getValue($adapter)); + } + + public function testSaveItem() + { + $itemCacheOne = $this->prophesize(CacheItem::class)->reveal(); + $itemCacheTwo = $this->prophesize(CacheItem::class); + $itemCacheTwo->getKey()->shouldBeCalled(1)->willReturn('two'); + $itemCacheTwo = $itemCacheTwo->reveal(); + $itemCacheThree = $this->prophesize(CacheItem::class)->reveal(); + $items = ['one' => $itemCacheOne, 'three' => $itemCacheThree]; + + $adapter = new MemoryAdapter(); + $reflectionProperty = new ReflectionProperty(MemoryAdapter::class, 'items'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($adapter, $items); + + $this->assertTrue($adapter->save($itemCacheTwo)); + $this->assertSame(['one' => $itemCacheOne, 'three' => $itemCacheThree, 'two' => $itemCacheTwo], $reflectionProperty->getValue($adapter)); + } + + public function testSaveItems() + { + $itemCacheOne = $this->prophesize(CacheItem::class); + $itemCacheOne->getKey()->shouldBeCalled(1)->willReturn('one'); + $itemCacheOne = $itemCacheOne->reveal(); + $itemCacheTwo = $this->prophesize(CacheItem::class); + $itemCacheTwo->getKey()->shouldBeCalled(1)->willReturn('two'); + $itemCacheTwo = $itemCacheTwo->reveal(); + $itemCacheThree = $this->prophesize(CacheItem::class)->reveal(); + $items = ['three' => $itemCacheThree]; + + $adapter = new MemoryAdapter(); + $reflectionProperty = new ReflectionProperty(MemoryAdapter::class, 'items'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($adapter, $items); + + $this->assertTrue($adapter->saveItems([$itemCacheOne, $itemCacheTwo])); + $this->assertSame(['three' => $itemCacheThree, 'one' => $itemCacheOne, 'two' => $itemCacheTwo], $reflectionProperty->getValue($adapter)); + } + + public function testSaveItemsThorwInvalidArgumentException() + { + $this->expectException(InvalidArgumentException::class); + $adapter = new MemoryAdapter(); + $adapter->saveItems(['invalid cache item']); + } +} \ No newline at end of file diff --git a/tests/Unit/Exception/InvalidArgumentExceptionTest.php b/tests/Unit/Exception/InvalidArgumentExceptionTest.php index 6b1a8bb..f7c93a5 100644 --- a/tests/Unit/Exception/InvalidArgumentExceptionTest.php +++ b/tests/Unit/Exception/InvalidArgumentExceptionTest.php @@ -2,7 +2,9 @@ declare(strict_types=1); -use Moon\Cache\Exception\InvalidArgumentException; +namespace Moon\Cache\Exception; + +use Moon\Cache\CacheItem; use PHPUnit\Framework\TestCase; class InvalidArgumentExceptionTest extends TestCase @@ -23,7 +25,7 @@ public function invalidCacheItemDataProvider(): array ['string'], [['an', 'array']], [null], - [$this->prophesize(\Moon\Cache\CacheItem::class)->reveal()] + [$this->prophesize(CacheItem::class)->reveal()] ]; } } \ No newline at end of file diff --git a/tests/Unit/Helper/CreateTableHelperTest.php b/tests/Unit/Helper/CreateTableHelperTest.php index d32129d..6fb6117 100644 --- a/tests/Unit/Helper/CreateTableHelperTest.php +++ b/tests/Unit/Helper/CreateTableHelperTest.php @@ -2,8 +2,15 @@ declare(strict_types=1); -use Moon\Cache\Helper\CreateTableHelper; +namespace Moon\Cache\Helper; + +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Schema\AbstractSchemaManager; +use Doctrine\DBAL\Schema\Schema; +use Doctrine\DBAL\Schema\Table; use PHPUnit\Framework\TestCase; +use Prophecy\Argument; class CreateTableHelperTest extends TestCase { @@ -12,7 +19,7 @@ class CreateTableHelperTest extends TestCase */ public function testQueryIsProperlyBuilt(array $tableOptions, array $expectedTableOptions) { - $table = $this->prophesize(\Doctrine\DBAL\Schema\Table::class); + $table = $this->prophesize(Table::class); $table->addColumn("`{$expectedTableOptions['idColumn']}`", 'bigint', ['unsigned' => true, 'autoincrement' => true])->shouldBeCalled(1); $table->addColumn("`{$expectedTableOptions['keyColumn']}`", 'string', ['notnull' => false])->shouldBeCalled(1); $table->addColumn("`{$expectedTableOptions['valueColumn']}`", 'text')->shouldBeCalled(1); @@ -21,17 +28,17 @@ public function testQueryIsProperlyBuilt(array $tableOptions, array $expectedTab $table->setPrimaryKey(["`{$expectedTableOptions['idColumn']}`"], true)->shouldBeCalled(1); $table->addUniqueIndex(["`{$expectedTableOptions['keyColumn']}`", "`{$expectedTableOptions['poolNameColumn']}`"], 'key_pool')->shouldBeCalled(1); - $schema = $this->prophesize(\Doctrine\DBAL\Schema\Schema::class); + $schema = $this->prophesize(Schema::class); $schema->createTable("`{$expectedTableOptions['tableName']}`")->shouldBeCalled(1)->willReturn($table->reveal()); - $schema->toSql(\Prophecy\Argument::type(Doctrine\DBAL\Platforms\AbstractPlatform::class))->shouldBeCalled(1)->willReturn(['first', 'second']); + $schema->toSql(Argument::type(AbstractPlatform::class))->shouldBeCalled(1)->willReturn(['first', 'second']); - $schemaManager = $this->prophesize(\Doctrine\DBAL\Schema\AbstractSchemaManager::class); + $schemaManager = $this->prophesize(AbstractSchemaManager::class); $schemaManager->createSchema()->shouldBeCalled(1)->willReturn($schema->reveal()); - $connection = $this->prophesize(\Doctrine\DBAL\Connection::class); - $connection->exec(\Prophecy\Argument::type('string'))->shouldBeCalled(1)->willReturn($schemaManager->reveal()); + $connection = $this->prophesize(Connection::class); + $connection->exec(Argument::type('string'))->shouldBeCalled(1)->willReturn($schemaManager->reveal()); $connection->getSchemaManager()->shouldBeCalled(1)->willReturn($schemaManager->reveal()); - $connection->getDatabasePlatform()->shouldBeCalled(1)->willReturn($this->prophesize(Doctrine\DBAL\Platforms\AbstractPlatform::class)->reveal()); + $connection->getDatabasePlatform()->shouldBeCalled(1)->willReturn($this->prophesize(AbstractPlatform::class)->reveal()); $helper = new CreateTableHelper(); $helper->generate($connection->reveal(), $tableOptions);