Implement PSR-16
Gitea - aviat/banker/pipeline/head There was a failure building this commit Details

This commit is contained in:
Timothy Warren 2020-05-07 17:17:03 -04:00
parent ac22e0d647
commit f31fe826b0
26 changed files with 562 additions and 154 deletions

View File

@ -1,5 +1,10 @@
# Changelog
## 3.0.0
* Updated dependencies
* Increased required PHP version to 7.4
* Added SimpleCache (PSR-16) implementation in `Teller` class
## 2.0.0
* Removed `Memcache` integration, as the extension does not seem to be maintained
* Increased required PHP version to 7.1

View File

@ -51,7 +51,7 @@ class RoboFile extends \Robo\Tasks {
/**
* Do static analysis tasks
*/
public function analyze()
public function analyze(): void
{
$this->prepare();
$this->lint();
@ -64,7 +64,7 @@ class RoboFile extends \Robo\Tasks {
/**
* Run all tests, generate coverage, generate docs, generate code statistics
*/
public function build()
public function build(): void
{
$this->analyze();
$this->coverage();
@ -74,22 +74,22 @@ class RoboFile extends \Robo\Tasks {
/**
* Cleanup temporary files
*/
public function clean()
public function clean(): void
{
$cleanFiles = [
'build/humbug.json',
'build/humbug-log.txt',
];
array_map(function ($file) {
array_map(static function ($file) {
@unlink($file);
}, $cleanFiles);
// So the task doesn't complain,
// make any 'missing' dirs to cleanup
array_map(function ($dir) {
array_map(static function ($dir) {
if ( ! is_dir($dir))
{
`mkdir -p {$dir}`;
shell_exec("mkdir -p {$dir}");
}
}, $this->cleanDirs);
@ -100,18 +100,15 @@ class RoboFile extends \Robo\Tasks {
/**
* Run unit tests and generate coverage reports
*/
public function coverage()
public function coverage(): void
{
$this->taskPhpUnit()
->configFile('build/phpunit.xml')
->printed(true)
->run();
$this->_run(['phpdbg -qrr -- vendor/bin/phpunit -c build']);
}
/**
* Generate documentation with phpdox
*/
public function docs()
public function docs(): void
{
$cmd_parts = [
'cd build',
@ -124,7 +121,7 @@ class RoboFile extends \Robo\Tasks {
/**
* Verify that source files are valid
*/
public function lint()
public function lint(): void
{
$files = $this->getAllSourceFiles();
@ -142,7 +139,7 @@ class RoboFile extends \Robo\Tasks {
*
* @param bool $stats - if true, generates stats rather than running mutation tests
*/
public function mutate($stats = FALSE)
public function mutate($stats = FALSE): void
{
$test_parts = [
'vendor/bin/humbug'
@ -164,7 +161,7 @@ class RoboFile extends \Robo\Tasks {
*
* @param bool $report - if true, generates reports instead of direct output
*/
public function phpcs($report = FALSE)
public function phpcs($report = FALSE): void
{
$report_cmd_parts = [
'vendor/bin/phpcs',
@ -187,7 +184,7 @@ class RoboFile extends \Robo\Tasks {
*
* @param bool $report - if true, generates reports instead of direct output
*/
public function phploc($report = FALSE)
public function phploc($report = FALSE): void
{
// Command for generating reports
$report_cmd_parts = [
@ -215,7 +212,7 @@ class RoboFile extends \Robo\Tasks {
/**
* Create temporary directories
*/
public function prepare()
public function prepare(): void
{
array_map([$this, '_mkdir'], $this->taskDirs);
}
@ -223,7 +220,7 @@ class RoboFile extends \Robo\Tasks {
/**
* Lint php files and run unit tests
*/
public function test()
public function test(): void
{
$this->lint();
$this->taskPHPUnit()
@ -235,7 +232,7 @@ class RoboFile extends \Robo\Tasks {
/**
* Watches for file updates, and automatically runs appropriate actions
*/
public function watch()
public function watch(): void
{
$this->taskWatch()
->monitor('composer.json', function() {
@ -253,7 +250,7 @@ class RoboFile extends \Robo\Tasks {
/**
* Create pdepend reports
*/
protected function dependencyReport()
protected function dependencyReport(): void
{
$cmd_parts = [
'vendor/bin/pdepend',
@ -270,14 +267,14 @@ class RoboFile extends \Robo\Tasks {
*
* @return array
*/
protected function getAllSourceFiles()
protected function getAllSourceFiles(): array
{
$files = array_merge(
$files = array_unique(array_merge(
glob_recursive('build/*.php'),
glob_recursive('src/*.php'),
glob_recursive('tests/*.php'),
glob('*.php')
);
));
sort($files);
@ -289,7 +286,7 @@ class RoboFile extends \Robo\Tasks {
*
* @param array $chunk
*/
protected function parallelLint(array $chunk)
protected function parallelLint(array $chunk): void
{
$task = $this->taskParallelExec()
->timeout(5)
@ -306,7 +303,7 @@ class RoboFile extends \Robo\Tasks {
/**
* Generate copy paste detector report
*/
protected function phpcpdReport()
protected function phpcpdReport(): void
{
$cmd_parts = [
'vendor/bin/phpcpd',
@ -323,7 +320,7 @@ class RoboFile extends \Robo\Tasks {
* @param array $cmd_parts - command arguments
* @param string $join_on - what to join the command arguments with
*/
protected function _run(array $cmd_parts, $join_on = ' ')
protected function _run(array $cmd_parts, $join_on = ' '): void
{
$this->taskExec(implode($join_on, $cmd_parts))->run();
}

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*
@ -30,7 +30,7 @@ abstract class AbstractDriver implements DriverInterface, LoggerAwareInterface {
*
* @var array
*/
protected $deferred = [];
protected array $deferred = [];
/**
* Common constructor interface for driver classes
@ -40,11 +40,6 @@ abstract class AbstractDriver implements DriverInterface, LoggerAwareInterface {
*/
abstract public function __construct(array $config = [], array $options = []);
/**
* Common destructor
*/
abstract public function __destruct();
/**
* Retrieve a set of values by their cache key
*

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*
@ -17,6 +17,11 @@ namespace Aviat\Banker\Driver;
use Aviat\Banker\Exception\CacheException;
use function apcu_clear_cache;
use function apcu_delete;
use function apcu_exists;
use function apcu_fetch;
use function apcu_store;
/**
* Memcached cache backend
@ -29,6 +34,7 @@ class ApcuDriver extends AbstractDriver {
* @param array $config - Not used by this driver
* @param array $options - Not used by this driver
* @throws CacheException
* @codeCoverageIgnore
*/
public function __construct(array $config = [], array $options = [])
{
@ -38,14 +44,6 @@ class ApcuDriver extends AbstractDriver {
}
}
/**
* Destructor
*/
public function __destruct()
{
// noop
}
/**
* See if a key currently exists in the cache
*
@ -54,7 +52,7 @@ class ApcuDriver extends AbstractDriver {
*/
public function exists(string $key): bool
{
return \apcu_exists($key) !== FALSE;
return apcu_exists($key) !== FALSE;
}
/**
@ -65,7 +63,7 @@ class ApcuDriver extends AbstractDriver {
*/
public function get(string $key)
{
return \apcu_fetch($key);
return apcu_fetch($key);
}
/**
@ -77,7 +75,7 @@ class ApcuDriver extends AbstractDriver {
public function getMultiple(array $keys = []): array
{
$status = FALSE;
return \apcu_fetch($keys, $status);
return apcu_fetch($keys, $status);
}
/**
@ -86,20 +84,13 @@ class ApcuDriver extends AbstractDriver {
* @param string $key
* @param mixed $value
* @param int $expires
* @return DriverInterface
* @return bool
*/
public function set(string $key, $value, int $expires = 0): DriverInterface
public function set(string $key, $value, int $expires = 0): bool
{
if ( ! \apcu_exists($key))
{
\apcu_add($key, $value, $expires);
}
else
{
\apcu_store($key, $value, $expires);
}
$ttl = $this->getTTLFromExpiration($expires);
return $this;
return apcu_store($key, $value, $ttl);
}
/**
@ -110,7 +101,7 @@ class ApcuDriver extends AbstractDriver {
*/
public function delete(string $key): bool
{
return (bool) \apcu_delete($key);
return apcu_delete($key);
}
/**
@ -121,7 +112,8 @@ class ApcuDriver extends AbstractDriver {
*/
public function deleteMultiple(array $keys = []): bool
{
return (bool) \apcu_delete($keys);
$deleted = apcu_delete($keys);
return ($keys <=> $deleted) === 0;
}
/**
@ -131,7 +123,7 @@ class ApcuDriver extends AbstractDriver {
*/
public function flush(): bool
{
return \apcu_clear_cache();
return apcu_clear_cache();
}
/**
@ -146,11 +138,25 @@ class ApcuDriver extends AbstractDriver {
if ($this->exists($key))
{
$value = $this->get($key);
return \apcu_store($key, $value, $expires);
$ttl = $this->getTTLFromExpiration($expires);
return apcu_store($key, $value, $ttl);
}
$this->getLogger()->log('warning', 'Tried to set expiration on a key that does not exist');
return FALSE;
}
/**
* Convert expiration date argument into TTL argument
*
* @param int $expires
* @return int
*/
protected function getTTLFromExpiration(int $expires): int
{
$ttl = $expires - time();
return ($ttl < 0) ? 0 : $ttl;
}
}

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*
@ -34,9 +34,9 @@ interface DriverInterface {
* @param string $key
* @param mixed $value
* @param int $expires
* @return DriverInterface
* @return bool
*/
public function set(string $key, $value, int $expires = 0): DriverInterface;
public function set(string $key, $value, int $expires = 0): bool;
/**
* Get the value for the selected cache key

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*
@ -17,15 +17,18 @@ namespace Aviat\Banker\Driver;
use Aviat\Banker\Exception\CacheException;
use Memcached;
use MemcachedException;
/**
* Memcached cache backend
*/
class MemcachedDriver extends AbstractDriver {
/**
* @var \Memcached
* @var Memcached
*/
private $conn;
private ?Memcached $conn;
/**
* Driver for PHP Memcache extension
@ -47,8 +50,8 @@ class MemcachedDriver extends AbstractDriver {
try
{
$this->conn = new \Memcached();
$this->conn->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
$this->conn = new Memcached();
$this->conn->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
$this->conn->addServer($config['host'], (int) $config['port']);
if ( ! empty($options))
@ -56,7 +59,7 @@ class MemcachedDriver extends AbstractDriver {
$this->conn->setOptions($options);
}
}
catch (\MemcachedException $e)
catch (MemcachedException $e)
{
// Rewrite MemcachedException as a CacheException to
// match the requirements of the interface
@ -66,6 +69,7 @@ class MemcachedDriver extends AbstractDriver {
/**
* Disconnect from memcached server
* @codeCoverageIgnore
*/
public function __destruct()
{
@ -80,7 +84,10 @@ class MemcachedDriver extends AbstractDriver {
*/
public function exists(string $key): bool
{
return $this->conn->get($key) !== FALSE;
$this->conn->get($key);
$resultFlag = $this->conn->getResultCode();
return ($resultFlag !== Memcached::RES_NOTFOUND);
}
/**
@ -102,8 +109,8 @@ class MemcachedDriver extends AbstractDriver {
*/
public function getMultiple(array $keys = []): array
{
$return = $this->conn->getMulti($keys);
return ($return === FALSE) ? [] : $return;
$response = $this->conn->getMulti($keys);
return (is_array($response)) ? $response : [];
}
/**
@ -112,20 +119,11 @@ class MemcachedDriver extends AbstractDriver {
* @param string $key
* @param mixed $value
* @param int $expires
* @return DriverInterface
* @return bool
*/
public function set(string $key, $value, int $expires = 0): DriverInterface
public function set(string $key, $value, int $expires = 0): bool
{
if ( ! $this->exists($key))
{
$this->conn->add($key, $value, $expires);
}
else
{
$this->conn->replace($key, $value, $expires);
}
return $this;
return $this->conn->set($key, $value, $expires);
}
/**
@ -136,7 +134,7 @@ class MemcachedDriver extends AbstractDriver {
*/
public function delete(string $key): bool
{
return (bool) $this->conn->delete($key);
return $this->conn->delete($key);
}
/**

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*
@ -27,7 +27,7 @@ class NullDriver extends AbstractDriver {
*
* @var array
*/
protected $store = [];
protected array $store = [];
/**
* NullDriver constructor.
@ -40,14 +40,6 @@ class NullDriver extends AbstractDriver {
$this->store = [];
}
/**
* Clean up nothing
*/
public function __destruct()
{
//noop
}
/**
* See if a key currently exists in the cache
*
@ -78,12 +70,12 @@ class NullDriver extends AbstractDriver {
* @param string $key
* @param mixed $value
* @param int $expires
* @return DriverInterface
* @return bool
*/
public function set(string $key, $value, int $expires = 0): DriverInterface
public function set(string $key, $value, int $expires = 0): bool
{
$this->store[$key] = $value;
return $this;
return $this->store[$key] === $value;
}
/**

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*
@ -28,7 +28,7 @@ class RedisDriver extends AbstractDriver {
*
* @var Client
*/
protected $conn;
protected ?Client $conn;
/**
* RedisDriver constructor.
@ -49,7 +49,8 @@ class RedisDriver extends AbstractDriver {
}
/**
* Disconnect from memcached server
* Disconnect from redis server
* @codeCoverageIgnore
*/
public function __destruct()
{
@ -85,22 +86,18 @@ class RedisDriver extends AbstractDriver {
* @param string $key
* @param mixed $value
* @param int $expires
* @return DriverInterface
* @return bool
*/
public function set(string $key, $value, int $expires = 0): DriverInterface
public function set(string $key, $value, int $expires = 0): bool
{
$value = serialize($value);
if ($expires !== 0)
{
$this->conn->set($key, $value, 'EX', $expires);
}
else
{
$this->conn->set($key, $value);
return (bool) $this->conn->set($key, $value, 'EX', $expires);
}
return $this;
return (bool)$this->conn->set($key, $value);
}
/**
@ -123,7 +120,7 @@ class RedisDriver extends AbstractDriver {
public function deleteMultiple(array $keys = []): bool
{
$res = $this->conn->del(...$keys);
return $res === \count($keys);
return $res === count($keys);
}
/**

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*
@ -16,10 +16,11 @@
namespace Aviat\Banker\Exception;
use Psr\Cache\CacheException as CacheExceptionInterface;
use Psr\SimpleCache\CacheException as SimpleCacheExceptionInterface;
/**
* Exception interface for all exceptions thrown by an Implementing Library.
*/
class CacheException extends \Exception implements CacheExceptionInterface {
class CacheException extends \Exception implements CacheExceptionInterface, SimpleCacheExceptionInterface {
}

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*
@ -15,7 +15,8 @@
*/
namespace Aviat\Banker\Exception;
use Psr\Cache\InvalidArgumentException as InvalidArgumentExceptionInterface;
use Psr\Cache\InvalidArgumentException as IAEInterface;
use Psr\SimpleCache\InvalidArgumentException as SimpleIAEInterface;
/**
* Exception interface for invalid cache arguments.
@ -23,7 +24,7 @@ use Psr\Cache\InvalidArgumentException as InvalidArgumentExceptionInterface;
* Any time an invalid argument is passed into a method it must throw an
* exception class which implements Psr\Cache\InvalidArgumentException.
*/
class InvalidArgumentException extends CacheException implements InvalidArgumentExceptionInterface {
class InvalidArgumentException extends CacheException implements IAEInterface, SimpleIAEInterface {
/**
* Constructor
@ -32,7 +33,7 @@ class InvalidArgumentException extends CacheException implements InvalidArgument
* @param int $code
* @param \Exception $previous
*/
public function __construct(string $message = "Cache key must be a string.", int $code = 0, \Exception $previous = NULL)
public function __construct(string $message = 'Cache key must be a string.', int $code = 0, \Exception $previous = NULL)
{
parent::__construct($message, $code, $previous);
}

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*
@ -15,6 +15,8 @@
*/
namespace Aviat\Banker;
use DateInterval;
use DateTimeInterface;
use Psr\Cache\CacheItemInterface;
use Aviat\Banker\Driver\DriverInterface;
@ -29,28 +31,28 @@ class Item implements CacheItemInterface {
*
* @var DriverInterface
*/
protected $driver;
protected DriverInterface $driver;
/**
* The key of the cache item
*
* @var string
*/
protected $key;
protected string $key;
/**
* The expiration time
*
* @var int | null
*/
protected $expiresAt;
protected ?int $expiresAt;
/**
* The time to live
*
* @var int | null
*/
protected $ttl;
protected ?int $ttl;
/**
* The value to save in the cache
@ -65,10 +67,13 @@ class Item implements CacheItemInterface {
* @param DriverInterface $driver
* @param string $key
*/
public function __construct(DriverInterface $driver, $key)
public function __construct(DriverInterface $driver, string $key)
{
$this->driver = $driver;
$this->key = $key;
$this->expiresAt = NULL;
$this->ttl = NULL;
}
/**
@ -143,7 +148,7 @@ class Item implements CacheItemInterface {
/**
* Sets the expiration time for this cache item.
*
* @param \DateTimeInterface|null $expiration
* @param DateTimeInterface|null $expiration
* The point in time after which the item MUST be considered expired.
* If null is passed explicitly, a default value MAY be used. If none is set,
* the value should be stored permanently or for as long as the
@ -154,7 +159,7 @@ class Item implements CacheItemInterface {
*/
public function expiresAt($expiration = NULL): Item
{
if ($expiration instanceof \DateTimeInterface)
if ($expiration instanceof DateTimeInterface)
{
$expiration = $expiration->getTimestamp();
}
@ -167,7 +172,7 @@ class Item implements CacheItemInterface {
/**
* Sets the expiration time for this cache item.
*
* @param int|\DateInterval|null $time
* @param int|DateInterval|null $time
* The period of time from the present after which the item MUST be considered
* expired. An integer parameter is understood to be the time in seconds until
* expiration. If null is passed explicitly, a default value MAY be used.
@ -179,7 +184,7 @@ class Item implements CacheItemInterface {
*/
public function expiresAfter($time = NULL): Item
{
if ($time instanceof \DateInterval)
if ($time instanceof DateInterval)
{
$time = $time->format("%s");
}

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*
@ -17,10 +17,11 @@ namespace Aviat\Banker;
use Aviat\Banker\Driver\DriverInterface;
use Aviat\Banker\Exception\InvalidArgumentException;
use Aviat\Banker\{Item, ItemCollection};
use Psr\Cache\{CacheItemInterface, CacheItemPoolInterface};
use Psr\Log\{LoggerAwareInterface, LoggerInterface};
use function is_string;
/**
* The main cache manager
*/
@ -33,14 +34,14 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
*
* @var DriverInterface
*/
protected $driver;
protected DriverInterface $driver;
/**
* Cache Items to be saved
*
* @var array
*/
protected $deferred = [];
protected array $deferred = [];
/**
* Set up the cache backend
@ -76,7 +77,7 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
*/
public function getItem($key): CacheItemInterface
{
if ( ! \is_string($key))
if ( ! is_string($key))
{
throw new InvalidArgumentException();
}
@ -117,7 +118,7 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
$items = [];
foreach($keys as $key)
{
if ( ! \is_string($key))
if ( ! is_string($key))
{
throw new InvalidArgumentException();
}
@ -149,7 +150,7 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
*/
public function hasItem($key): bool
{
if ( ! \is_string($key))
if ( ! is_string($key))
{
throw new InvalidArgumentException();
}
@ -189,7 +190,7 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
*/
public function deleteItem($key): bool
{
if ( ! \is_string($key))
if ( ! is_string($key))
{
throw new InvalidArgumentException();
}
@ -219,7 +220,7 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
{
foreach ($keys as $key)
{
if ( ! \is_string($key))
if ( ! is_string($key))
{
throw new InvalidArgumentException();
}

240
src/Teller.php Normal file
View File

@ -0,0 +1,240 @@
<?php declare(strict_types=1);
/**
* Banker
*
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*
* @package Banker
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2016 - 2019 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 3.0.0
* @link https://git.timshomepage.net/timw4mail/banker
*/
namespace Aviat\Banker;
use Aviat\Banker\Exception\InvalidArgumentException;
use Psr\SimpleCache;
use Psr\Log\LoggerInterface;
class Teller implements SimpleCache\CacheInterface {
private Pool $pool;
/**
* Set up the cache backend
*
* @param array $config
* @param LoggerInterface $logger
*/
public function __construct(array $config, ?LoggerInterface $logger = NULL)
{
$this->pool = new Pool($config, $logger);
}
/**
* Fetches a value from the cache.
*
* @param string $key The unique key of this item in the cache.
* @param mixed $default Default value to return if the key does not exist.
*
* @return mixed The value of the item from the cache, or $default in case of cache miss.
*
* @throws SimpleCache\InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
*/
public function get($key, $default = null)
{
$this->validateKey($key);
$item = $this->pool->getItem($key);
return ($item->isHit()) ? $item->get() : $default;
}
/**
* Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time.
*
* @param string $key The key of the item to store.
* @param mixed $value The value of the item to store, must be serializable.
* @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and
* the driver supports TTL then the library may set a default value
* for it or let the driver take care of that.
*
* @return bool True on success and false on failure.
*
* @throws SimpleCache\InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
*/
public function set($key, $value, $ttl = null): bool
{
$this->validateKey($key);
$item = $this->pool->getItem($key);
$item->set($value);
if ($ttl !== NULL)
{
$item->expiresAfter($ttl);
}
return $this->pool->save($item);
}
/**
* Delete an item from the cache by its unique key.
*
* @param string $key The unique cache key of the item to delete.
*
* @return bool True if the item was successfully removed. False if there was an error.
*
* @throws SimpleCache\InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
*/
public function delete($key): bool
{
$this->validateKey($key);
return $this->pool->deleteItem($key);
}
/**
* Wipes clean the entire cache's keys.
*
* @return bool True on success and false on failure.
*/
public function clear(): bool
{
return $this->pool->clear();
}
/**
* Obtains multiple cache items by their unique keys.
*
* @param iterable $keys A list of keys that can obtained in a single operation.
* @param mixed $default Default value to return for keys that do not exist.
*
* @return iterable A list of key => value pairs. Cache keys that do not exist or are stale will have $default as value.
*
* @throws SimpleCache\InvalidArgumentException
* MUST be thrown if $keys is neither an array nor a Traversable,
* or if any of the $keys are not a legal value.
*/
public function getMultiple($keys, $default = null)
{
$this->validateKeys($keys);
$output = [];
foreach ($keys as $k)
{
$output[$k] = $this->get($k, $default);
}
return $output;
}
/**
* Persists a set of key => value pairs in the cache, with an optional TTL.
*
* @param iterable $values A list of key => value pairs for a multiple-set operation.
* @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and
* the driver supports TTL then the library may set a default value
* for it or let the driver take care of that.
*
* @return bool True on success and false on failure.
*
* @throws SimpleCache\InvalidArgumentException
* MUST be thrown if $values is neither an array nor a Traversable,
* or if any of the $values are not a legal value.
*/
public function setMultiple($values, $ttl = null): bool
{
$this->validateKeys($values, TRUE);
$setResults = [];
foreach ($values as $k => $v)
{
$setResults[] = $this->set($k, $v, $ttl);
}
// Only return true if all the results are true
return array_reduce($setResults, fn ($carry, $item) => $item && $carry, TRUE);
}
/**
* Deletes multiple cache items in a single operation.
*
* @param iterable $keys A list of string-based keys to be deleted.
*
* @return bool True if the items were successfully removed. False if there was an error.
*
* @throws SimpleCache\InvalidArgumentException
* MUST be thrown if $keys is neither an array nor a Traversable,
* or if any of the $keys are not a legal value.
*/
public function deleteMultiple($keys): bool
{
$this->validateKeys($keys);
return $this->pool->deleteItems((array)$keys);
}
/**
* Determines whether an item is present in the cache.
*
* NOTE: It is recommended that has() is only to be used for cache warming type purposes
* and not to be used within your live applications operations for get/set, as this method
* is subject to a race condition where your has() will return true and immediately after,
* another script can remove it making the state of your app out of date.
*
* @param string $key The cache item key.
*
* @return bool
*
* @throws SimpleCache\InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
*/
public function has($key): bool
{
$this->validateKey($key);
return $this->pool->hasItem($key);
}
/**
* @param $keys
* @param bool $hash
* @throws InvalidArgumentException
*/
private function validateKeys($keys, bool $hash = FALSE): void
{
// Check type of keys
if ( ! is_iterable($keys))
{
throw new InvalidArgumentException('Keys must be an array or a traversable object');
}
$keys = ($hash) ? array_keys((array)$keys) : (array)$keys;
// Check each key
array_walk($keys, fn($key) => $this->validateKey($key));
}
/**
* @param string $key
* @throws InvalidArgumentException
*/
private function validateKey($key): void
{
if ( ! is_string($key))
{
throw new InvalidArgumentException('Cache key must be a string.');
}
if (is_string($key) && preg_match("`[{}()/@:\\\]`", $key) === 1)
{
throw new InvalidArgumentException('Invalid characters in cache key');
}
}
}

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*
@ -15,16 +15,14 @@
*/
namespace Aviat\Banker\Tests\Driver;
use Aviat\Banker\Driver\DriverInterface;
use PHPUnit\Framework\TestCase;
class DriverTestBase extends TestCase {
protected $driver;
protected DriverInterface $driver;
public function tearDown(): void
{
$this->driver->__destruct();
}
public function testGetSet(): void
{

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*
@ -214,11 +214,19 @@ class PoolTest extends TestCase {
public function testDeleteItemBadKey(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage("Cache key must be a string.");
$this->expectExceptionMessage('Cache key must be a string.');
$this->pool->deleteItem(34);
}
public function testDeleteItemsBadKey(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Cache key must be a string.');
$this->pool->deleteItems([34]);
}
public function testDeleteItemThatDoesNotExist(): void
{
$this->pool->clear();

164
tests/TellerTest.php Normal file
View File

@ -0,0 +1,164 @@
<?php declare(strict_types=1);
/**
* Banker
*
* A Caching library implementing psr/cache
*
* PHP version 7.1
*
* @package Banker
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2016 - 2018 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
* @link https://git.timshomepage.net/timw4mail/banker
*/
namespace Aviat\Banker\Tests;
use Aviat\Banker\Teller;
use Aviat\Banker\Exception\InvalidArgumentException;
use PHPUnit\Framework\TestCase;
class TellerTest extends TestCase {
protected Teller $teller;
private array $testValues = [
'foo' => 24,
'bar' => '87',
'baz' => [1, 2, 3],
'a' => TRUE,
'b' => 1,
'c' => FALSE,
'd' => 0,
'e' => NULL,
'f' => [
'a' => [
'b' => 'c',
'd' => [1, 2, 3]
]
]
];
public function setUp(): void
{
$this->teller = new Teller([
'driver' => 'null',
'connection' => []
]);
// Call clear to make sure we are working from a clean slate to start
$this->teller->clear();
}
public function testGetSet(): void
{
foreach ($this->testValues as $key => $value)
{
$this->assertTrue($this->teller->set($key, $value, 0), "Failed to set value for key: {$key}");
$received = $this->teller->get($key);
$this->assertEquals($value, $received, "Invalid value returned for key: {$key}");
}
}
public function testGetSetMultiple(): void
{
$this->assertTrue($this->teller->setMultiple($this->testValues));
$received = $this->teller->getMultiple(array_keys($this->testValues));
$this->assertEquals($this->testValues, $received);
}
public function testClear(): void
{
$data = [
'foo' => 'bar',
'bar' => 'baz',
'foobar' => 'foobarbaz'
];
// Set up some data
$this->teller->setMultiple($data);
foreach($data as $key => $val)
{
$this->assertTrue($this->teller->has($key));
$this->assertEquals($val, $this->teller->get($key));
}
// Now we clear it all!
$this->teller->clear();
foreach($data as $key => $val)
{
$this->assertFalse($this->teller->has($key));
$this->assertNull($this->teller->get($key));
}
}
public function testDelete(): void
{
$this->teller->setMultiple($this->testValues);
$this->assertTrue($this->teller->delete('foo'));
$this->assertFalse($this->teller->has('foo'));
// Make sure we get the default value for the key
$this->assertEquals('Q', $this->teller->get('foo', 'Q'));
}
public function testDeleteMultiple(): void
{
$this->teller->setMultiple($this->testValues);
$deleteKeys = ['foo', 'bar', 'baz'];
$hasKeys = ['a', 'b', 'c', 'd', 'e', 'f'];
$this->assertTrue($this->teller->deleteMultiple($deleteKeys));
array_walk($deleteKeys, fn ($key) => $this->assertFalse($this->teller->has($key)));
array_walk($hasKeys, fn ($key) => $this->assertTrue($this->teller->has($key)));
}
public function testBadKeyType(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Cache key must be a string.');
$this->teller->get(546567);
}
public function testBadKeysType (): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Keys must be an array or a traversable object');
$keys = (object)[];
$this->teller->getMultiple($keys);
}
/**
* @dataProvider keyValidationTests
*/
public function testKeyValidation($key): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid characters in cache key');
$this->teller->get($key);
}
public function keyValidationTests(): array
{
// {}()/@:\\\
return [
['key' => '{}()/@:\\'],
['key' => 'a: b'],
['key' => 'a/b'],
['key' => '{'],
['key' => 'a@b'],
];
}
}

View File

@ -2,7 +2,7 @@
/**
* Banker
*
* A Caching library implementing psr/cache
* A Caching library implementing psr/cache (PSR 6)
*
* PHP version 7.2
*