Lots of fixes and tests

This commit is contained in:
Timothy Warren 2016-09-06 17:03:43 -04:00
parent b1fb6dccaa
commit 03bf558d62
20 changed files with 829 additions and 55 deletions

View File

@ -24,8 +24,9 @@
}
},
"require": {
"predis/predis": "^1.1",
"psr/log": "^1.0",
"psr/cache": "^1.0"
"psr/cache": "^1.0.1"
},
"require-dev": {
"consolidation/robo": "1.0.0-RC2",
@ -36,7 +37,6 @@
"phploc/phploc": "^3.0",
"phpmd/phpmd": "^2.4",
"phpunit/phpunit": "^5.5",
"predis/predis": "^1.1",
"sebastian/phpcpd": "^2.0",
"squizlabs/php_codesniffer": "^3.0.0@alpha",
"theseer/phpdox": "^0.9.0"

View File

@ -16,10 +16,14 @@
namespace Aviat\Banker\Driver;
use Psr\Log\LoggerAwareInterface;
/**
* Base class for cache backends
*/
abstract class Driver implements DriverInterface {
abstract class AbstractDriver implements DriverInterface, LoggerAwareInterface {
use \Aviat\Banker\LoggerTrait;
/**
* The object encapsulating the connection to the cache backend
@ -41,4 +45,9 @@ abstract class Driver implements DriverInterface {
* @param array $config - Connection parameters for the specified backend
*/
abstract public function __construct(array $config = []);
/**
* Common destructor
*/
abstract public function __destruct();
}

View File

@ -77,4 +77,13 @@ interface DriverInterface {
* @return boolean
*/
public function flush();
/**
* Set the specified key to expire at the given time
*
* @param string $key
* @param int $expires
* @return boolean
*/
public function expiresAt($key, $expires);
}

View File

@ -21,7 +21,7 @@ use Aviat\Banker\Exception\CacheException;
/**
* Redis cache backend
*/
class MemcacheDriver extends Driver {
class MemcacheDriver extends AbstractDriver {
/**
* Driver for PHP Memcache extension
@ -93,8 +93,16 @@ class MemcacheDriver extends Driver {
* @return DriverInterface
*/
public function set($key, $value, $expires = 0)
{
if ($this->exists($key))
{
$this->conn->replace($key, $value, 0, $expires);
}
else
{
$this->conn->set($key, $value, 0, $expires);
}
return $this;
}
@ -133,4 +141,19 @@ class MemcacheDriver extends Driver {
{
return $this->conn->flush();
}
/**
* Set the specified key to expire at the given time
*
* @param string $key
* @param int $expires
* @return DriverInterface
*/
public function expiresAt($key, $expires)
{
$value = $this->get($key);
$timediff = $expires - time();
return $this->set($key, $value, $timediff);
}
}

View File

@ -24,7 +24,7 @@ use MemcachedException;
/**
* Memcached cache backend
*/
class MemcachedDriver extends Driver {
class MemcachedDriver extends AbstractDriver {
/**
* Driver for PHP Memcache extension
@ -39,10 +39,19 @@ class MemcachedDriver extends Driver {
throw new CacheException("Memcached driver requires memcached extensions");
}
try
{
$this->conn = new Memcached();
$this->conn->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
$this->conn->addServer($config['host'], $config['port']);
}
catch (MemcachedException $e)
{
// Rewrite MemcachedException as a CacheException to
// match the requirements of the interface
throw new CacheException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* Disconnect from memcached server
@ -95,7 +104,15 @@ class MemcachedDriver extends Driver {
*/
public function set($key, $value, $expires = 0)
{
$this->conn->set($key, $value, $expires);
if ( ! $this->exists($key))
{
$this->conn->add($key, $value, $expires);
}
else
{
$this->conn->replace($key, $value, $expires);
}
return $this;
}
@ -130,4 +147,23 @@ class MemcachedDriver extends Driver {
{
return $this->conn->flush();
}
/**
* Set the specified key to expire at the given time
*
* @param string $key
* @param int $expires
* @return boolean
*/
public function expiresAt($key, $expires)
{
if ($this->exists($key))
{
return $this->conn->touch($key, $expires);
}
$this->getLogger()->warn("Tried to set expiration on a key that does not exist");
return FALSE;
}
}

View File

@ -21,7 +21,7 @@ namespace Aviat\Banker\Driver;
* Cache backend for use without a cache server. Only does transient
* in-memory caching
*/
class NullDriver extends Driver {
class NullDriver extends AbstractDriver {
/**
* In memory store
@ -40,6 +40,14 @@ class NullDriver extends Driver {
$this->store = [];
}
/**
* Clean up nothing
*/
public function __destruct()
{
//noop
}
/**
* See if a key currently exists in the cache
*
@ -59,7 +67,9 @@ class NullDriver extends Driver {
*/
public function get($key)
{
return $this->store[$key];
return ($this->exists($key))
? $this->store[$key]
: NULL;
}
/**
@ -134,4 +144,17 @@ class NullDriver extends Driver {
$this->store = [];
return TRUE;
}
/**
* Set the specified key to expire at the given time
*
* @param string $key
* @param int $expires
* @return boolean
*/
public function expiresAt($key, $expires)
{
//noop
return TRUE;
}
}

View File

@ -22,7 +22,7 @@ use Predis\Client;
/**
* Redis cache backend
*/
class RedisDriver extends Driver {
class RedisDriver extends AbstractDriver {
/**
* The object encapsulating the connection to the Redis server
@ -108,7 +108,15 @@ class RedisDriver extends Driver {
{
$value = \serialize($value);
if ($expires !== 0)
{
$this->conn->set($key, $value, "EX {$expires}");
}
else
{
$this->conn->set($key, $value);
}
return $this;
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Banker
*
* A Caching library implementing psr/cache
*
* PHP version 5.6
*
* @package Banker
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2016 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 1.0.0
* @link https://git.timshomepage.net/timw4mail/banker
*/
namespace Aviat\Banker\Driver;
/**
* SQL cache backend
*/
class SQLDriver extends Driver {
}

View File

@ -26,4 +26,15 @@ use Psr\Cache\InvalidArgumentException as InvalidArgumentExceptionInterface;
*/
class InvalidArgumentException extends CacheException implements InvalidArgumentExceptionInterface {
/**
* Constructor
*
* @param string $message
* @param int $code
* @param \Exception $previous
*/
public function __construct($message = "Cache key must be a string.", $code = 0, \Exception $previous = NULL)
{
parent::__construct($message, $code, $previous);
}
}

View File

@ -99,10 +99,15 @@ class Item implements CacheItemInterface {
* The value corresponding to this cache item's key, or null if not found.
*/
public function get()
{
if ($this->isHit())
{
return $this->driver->get($this->key);
}
return NULL;
}
/**
* Confirms if the cache item lookup resulted in a cache hit.
*
@ -150,6 +155,13 @@ class Item implements CacheItemInterface {
*/
public function expiresAt($expiration = NULL)
{
if ($time instanceof \DateTimeInterface)
{
$time = $time->getTimestamp();
}
$this->expiresAt = (int) $time;
return $this;
}
@ -168,7 +180,34 @@ class Item implements CacheItemInterface {
*/
public function expiresAfter($time = 0)
{
$this->ttl = $time;
if ($time instanceof \DateInterval)
{
$time = $time->format("%s");
}
$this->ttl = (int) $time;
return $this;
}
/**
* Save the current value to the cache
*
* @return bool
*/
public function save()
{
if ($this->expiresAt !== NULL && $this->expiresAt !== 0)
{
$setResult = $this->driver->set($this->key, $this->value);
$expResult = $this->driver->expiresAt($this->key, $this->expiresAt);
return $setResult && $expResult;
}
else if ($this->ttl !== NULL && $this->ttl !== 0)
{
return $this->driver->set($this->key, $this->value, $this->ttl);
}
return $this->driver->set($this->key, $this->value);
}
}

View File

@ -22,6 +22,7 @@ use Psr\Cache\CacheItemInterface;
* Collection of Psr\Cache\CacheItemIterface objects to be returned by getItems
*
* @see http://php.net/manual/en/class.arrayiterator.php
* @see http://php.net/manual/en/class.jsonserializable.php
*/
class ItemCollection extends \ArrayIterator implements \JsonSerializable {

68
src/LoggerTrait.php Normal file
View File

@ -0,0 +1,68 @@
<?php
/**
* Banker
*
* A Caching library implementing psr/cache
*
* PHP version 5.6
*
* @package Banker
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2016 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 1.0.0
* @link https://git.timshomepage.net/timw4mail/banker
*/
namespace Aviat\Banker;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Psr\Log\NullLogger;
/**
* Trait for keeping track of logger objects
*/
trait LoggerTrait {
/**
* Logger instance to use
*
* @var LoggerInterface
*/
protected $logger = NULL;
/**
* Return the existing logger instance or
* a NullLogger, if no instance set
*
* @return LoggerInterface
*/
protected function getLogger()
{
if ($this->logger === NULL)
{
$this->logger = new NullLogger();
}
return $this->logger;
}
/**
* Set a logger to keep track of errors
*
* @param LoggerInterface $logger
* @return self
*/
public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
// Set the logger for the current driver too
if (isset($this->driver))
{
$this->driver->setLogger($logger);
}
return $this;
}
}

View File

@ -18,16 +18,20 @@ namespace Aviat\Banker;
use Psr\Cache\CacheItemInterface;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
use Aviat\Banker\Driver;
use Aviat\Banker\Driver\DriverInterface;
use Aviat\Banker\Exception\InvalidArgumentException;
use Aviat\Banker\Item;
use Aviat\Banker\ItemCollection;
/**
* The main cache manager
*/
class Pool implements CacheItemPoolInterface {
class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
use LoggerTrait;
/**
* Driver class for handling the chosen caching backend
@ -48,9 +52,14 @@ class Pool implements CacheItemPoolInterface {
*
* @param array $config
*/
public function __construct(array $config)
public function __construct(array $config, LoggerInterface $logger = NULL)
{
$this->driver = $this->loadDriver($config);
if ( ! is_null($logger))
{
$this->setLogger($logger);
}
}
/**
@ -73,7 +82,13 @@ class Pool implements CacheItemPoolInterface {
{
if ( ! is_string($key))
{
throw new InvalidArgumentException("Cache key must be a string.");
throw new InvalidArgumentException();
}
// If a deferred item exists, return that
if (array_key_exists($key, $this->deferred))
{
return $this->deferred[$key];
}
$item = new Item($this->driver, $key);
@ -98,11 +113,32 @@ class Pool implements CacheItemPoolInterface {
*/
public function getItems(array $keys = [])
{
// Get the set of items selected
$items = [];
if (empty($keys))
{
return new ItemCollection([]);
}
foreach($keys as $key)
{
$items[$key] = $this->getItem($key);
if ( ! is_string($key))
{
throw new InvalidArgumentException();
}
}
// Get the set of items selected
$items = [];
$rawItems = $this->driver->getMultiple($keys);
foreach($rawItems as $key => $val)
{
if (array_key_exists($key, $this->deferred))
{
$items[$key] = $this->deferred[$key];
}
else
{
$items[$key] = new Item($this->driver, $key);
}
}
return new ItemCollection($items);
@ -129,7 +165,13 @@ class Pool implements CacheItemPoolInterface {
{
if ( ! is_string($key))
{
throw new InvalidArgumentException("Cache item must be a string");
throw new InvalidArgumentException();
}
// See if there are any deferred items
if (array_key_exists($key, $this->deferred))
{
return TRUE;
}
return $this->driver->exists($key);
@ -163,7 +205,7 @@ class Pool implements CacheItemPoolInterface {
{
if ( ! is_string($key))
{
throw new InvalidArgumentException("Cache item must be a string");
throw new InvalidArgumentException();
}
if ( ! $this->hasItem($key))
@ -195,7 +237,7 @@ class Pool implements CacheItemPoolInterface {
{
if ( ! is_string($key))
{
throw new InvalidArgumentException("Cache item must be a string");
throw new InvalidArgumentException();
}
}
@ -213,7 +255,7 @@ class Pool implements CacheItemPoolInterface {
*/
public function save(CacheItemInterface $item)
{
return $item->save();
}
/**
@ -227,7 +269,8 @@ class Pool implements CacheItemPoolInterface {
*/
public function saveDeferred(CacheItemInterface $item)
{
$this->deferred[] = $item;
$this->deferred[$item->getKey()] = $item;
return TRUE;
}
/**
@ -250,6 +293,11 @@ class Pool implements CacheItemPoolInterface {
$result = $result && $this->save($item);
}
if ($result === TRUE)
{
$this->deferred = [];
}
return $result;
}
@ -262,7 +310,7 @@ class Pool implements CacheItemPoolInterface {
protected function loadDriver(array $driverConfig)
{
$driver = ucfirst(strtolower($driverConfig['driver']));
$class = "Driver\\${driver}Driver";
$class = __NAMESPACE__ . "\\Driver\\${driver}Driver";
return new $class($driverConfig['connection']);
}

View File

@ -8,6 +8,11 @@ class DriverTestBase extends TestCase {
protected $driver;
public function tearDown()
{
$this->driver->__destruct();
}
public function testGetSet()
{
$this->driver->set('foo', 'bar');

View File

@ -0,0 +1,14 @@
<?php
namespace Aviat\Banker\Tests\Driver;
use Aviat\Banker\Driver\NullDriver;
class NullDriverTest extends DriverTestBase {
public function setup()
{
$this->driver = new NullDriver();
$this->driver->flush();
}
}

View File

@ -2,6 +2,14 @@
namespace Aviat\Banker\Tests\Driver;
use Aviat\Banker\Driver\RedisDriver;
class RedisDriverTest extends DriverTestBase {
public function setup()
{
$this->driver = new RedisDriver();
$this->driver->flush();
}
}

120
tests/Friend.php Normal file
View File

@ -0,0 +1,120 @@
<?php
namespace Aviat\Banker\Tests;
use ReflectionClass;
use ReflectionMethod;
use ReflectionProperty;
use InvalidArgumentException;
use BadMethodCallException;
/**
* Friend class for testing
*/
class Friend {
/**
* Object to create a friend of
* @var object
*/
private $_friend_;
/**
* Reflection class of the object
* @var object
*/
private $_reflect_;
/**
* Create a friend object
*
* @param object $obj
* @throws InvalidArgumentException
*/
public function __construct($obj)
{
if ( ! is_object($obj))
{
throw new InvalidArgumentException("Friend must be an object");
}
$this->_friend_ = $obj;
$this->_reflect_ = new ReflectionClass($obj);
}
/**
* Retrieve a friend's property
*
* @param string $key
* @return mixed
*/
public function __get($key)
{
if ($this->_reflect_->hasProperty($key))
{
$property = $this->_get_property($key);
return $property->getValue($this->_friend_);
}
return NULL;
}
/**
* Set a friend's property
*
* @param string $key
* @param mixed $value
* @return void
*/
public function __set($key, $value)
{
if ($this->_reflect_->hasProperty($key))
{
$property = $this->_get_property($key);
$property->setValue($this->_friend_, $value);
}
}
/**
* Calls a protected or private method on the friend
*
* @param string $method
* @param array $args
* @return mixed
* @throws BadMethodCallException
*/
public function __call($method, $args)
{
if ( ! $this->_reflect_->hasMethod($method))
{
throw new BadMethodCallException("Method '{$method}' does not exist");
}
$friendMethod = new ReflectionMethod($this->_friend_, $method);
$friendMethod->setAccessible(TRUE);
return $friendMethod->invokeArgs($this->_friend_, $args);
}
/**
* Iterates over parent classes to get a ReflectionProperty
*
* @codeCoverageIgnore
* @param string $name
* @return ReflectionProperty|null
*/
private function _get_property($name)
{
try
{
$property = $this->_reflect_->getProperty($name);
$property->setAccessible(TRUE);
return $property;
}
// Return NULL on any exception, so no further logic needed
// in the catch block
catch (\Exception $e)
{
return NULL;
}
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace Aviat\Banker\Tests;
use Aviat\Banker\ItemCollection;
use PHPUnit\Framework\TestCase;
class ItemCollectionTest extends TestCase {
public function setUp()
{
$this->collection = new ItemCollection([]);
}
public function testJsonSerialize()
{
$this->assertEquals([], $this->collection->jsonSerialize());
$json = json_encode($this->collection);
$result = json_decode($json);
$this->assertEquals([], $result);
}
}

39
tests/ItemTest.php Normal file
View File

@ -0,0 +1,39 @@
<?php
namespace Aviat\Banker\Tests;
use Aviat\Banker\Item;
use Aviat\Banker\ItemCollection;
use Aviat\Banker\Driver\NullDriver;
use Aviat\Banker\Exception\InvalidArgumentException;
use PHPUnit\Framework\TestCase;
class ItemTest extends TestCase {
protected $key = 'foo';
protected $item;
protected $driver;
public function setUp()
{
$this->driver = new NullDriver();
$this->item = new Item($this->driver, $this->key);
}
public function testGetKey()
{
$this->assertEquals($this->key, $this->item->getKey());
}
public function testGet()
{
// No value set yet
$this->assertNull($this->item->get());
// Set a value
$this->item->set('bar')
->save();
$this->assertEquals('bar', $this->item->get());
}
}

314
tests/PoolTest.php Normal file
View File

@ -0,0 +1,314 @@
<?php
namespace Aviat\Banker\Tests;
use Aviat\Banker\Pool;
use Aviat\Banker\Item;
use Aviat\Banker\ItemCollection;
use Aviat\Banker\Exception\InvalidArgumentException;
use Monolog\Logger;
use Monolog\Handler\SyslogHandler;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
class PoolTest extends TestCase {
protected $pool;
public function setUp()
{
$this->pool = new Pool([
'driver' => 'null',
'connection' => []
]);
}
public function testGetDefaultLogger()
{
$friend = new Friend($this->pool);
$driverFriend = new Friend($friend->driver);
// Check that a valid logger is set
$this->assertInstanceOf(LoggerInterface::class, $friend->getLogger(), "Logger exists after being set");
$this->assertInstanceOf(LoggerInterface::class, $driverFriend->getLogger(), "Logger exists on driver after being set");
// Make sure we get the default Null logger
$this->assertTrue(is_a($friend->getLogger(), NullLogger::class));
$this->assertTrue(is_a($driverFriend->getLogger(), NullLogger::class));
}
public function testSetLoggerInConstructor()
{
$logger = new Logger('test');
$logger->pushHandler(new SyslogHandler(Logger::WARNING));
$pool = new Pool([
'driver' => 'null',
'connection' => [],
], $logger);
$friend = new Friend($pool);
$driverFriend = new Friend($friend->driver);
// Check that a valid logger is set
$this->assertInstanceOf(LoggerInterface::class, $friend->getLogger(), "Logger exists after being set");
$this->assertInstanceOf(LoggerInterface::class, $driverFriend->getLogger(), "Logger exists on driver after being set");
// Make sure we aren't just getting the default Null logger
$this->assertFalse(is_a($friend->getLogger(), NullLogger::class));
$this->assertFalse(is_a($driverFriend->getLogger(), NullLogger::class));
}
public function testGetSetLogger()
{
$logger = new Logger('test');
$logger->pushHandler(new SyslogHandler(Logger::WARNING));
$this->pool->setLogger($logger);
$friend = new Friend($this->pool);
$driverFriend = new Friend($friend->driver);
// Check that a valid logger is set
$this->assertInstanceOf(LoggerInterface::class, $friend->getLogger(), "Logger exists after being set");
$this->assertInstanceOf(LoggerInterface::class, $driverFriend->getLogger(), "Logger exists on driver after being set");
// Make sure we aren't just getting the default Null logger
$this->assertFalse(is_a($friend->getLogger(), NullLogger::class));
$this->assertFalse(is_a($driverFriend->getLogger(), NullLogger::class));
}
public function testGetItem()
{
$item = $this->pool->getItem('foo');
$this->assertInstanceOf(Item::class, $item);
}
public function testItemBadKey()
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage("Cache key must be a string.");
$this->pool->getItem([]);
}
public function testGetItems()
{
$collection = $this->pool->getItems(['foo', 'bar', 'baz']);
$this->assertInstanceOf(ItemCollection::class, $collection);
foreach($collection as $item)
{
$this->assertInstanceOf(Item::class, $item);
}
}
public function testEmptyGetItems()
{
$collection = $this->pool->getItems();
$this->assertInstanceOf(ItemCollection::class, $collection);
$this->assertEquals(0, count($collection));
}
public function testHasItem()
{
// The key doesn't exist yet
$this->assertFalse($this->pool->hasItem('foobar'));
// Create the item
$item = $this->pool->getItem('foobar')
->set('baz')
->save();
// The item exists now
$this->assertTrue($this->pool->hasItem('foobar'));
}
public function testHasItemBadKey()
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage("Cache key must be a string.");
$this->pool->hasItem(34);
}
public function testClear()
{
// Call clear to make sure we are working from a clean slate to start
$this->pool->clear();
$data = [
'foo' => 'bar',
'bar' => 'baz',
'foobar' => 'foobarbaz'
];
// Set up some data
$this->setupDataInCache($data);
foreach($data as $key => $val)
{
$this->assertTrue($this->pool->hasItem($key));
$item = $this->pool->getItem($key);
$this->assertEquals($val, $item->get());
}
// Now we clear it all!
$this->pool->clear();
foreach($data as $key => $val)
{
$this->assertFalse($this->pool->hasItem($key));
$item = $this->pool->getItem($key);
$this->assertNull($item->get());
}
}
public function testDeleteItemBadKey()
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage("Cache key must be a string.");
$this->pool->deleteItem(34);
}
public function testDeleteItemThatDoesNotExist()
{
$this->pool->clear();
$this->assertFalse($this->pool->deleteItem('foo'));
}
public function testDeleteItem()
{
// Start with a clean slate
$this->pool->clear();
$data = [
'foo' => 'bar',
'bar' => 'baz',
'foobar' => 'foobarbaz'
];
$this->setupDataInCache($data);
$this->pool->deleteItem('foo');
// The item no longer exists
$this->assertFalse($this->pool->hasItem('foo'));
$item = $this->pool->getItem('foo');
$this->assertNull($item->get());
// The other items still exist
foreach(['bar', 'foobar'] as $key)
{
$this->assertTrue($this->pool->hasItem($key));
$item = $this->pool->getItem($key);
$this->assertFalse(is_null($item->get()));
}
}
public function testDeleteItems()
{
$this->pool->clear();
$data = [
'foo' => 'bar',
'bar' => 'baz',
'foobar' => 'foobarbaz'
];
$this->setupDataInCache($data);
$this->pool->deleteItems(['foo', 'bar']);
foreach(['foo', 'bar'] as $key)
{
$this->assertFalse($this->pool->hasItem($key));
$item = $this->pool->getItem($key);
$this->assertNull($item->get());
}
}
public function testSaveDeferred()
{
$this->pool->clear();
$data = [
'foo' => 'bar',
'bar' => 'baz',
'foobar' => 'foobarbaz'
];
$this->setupDeferredData($data);
// See that the data is returned by the pool
foreach($data as $key => $val)
{
$this->assertTrue($this->pool->hasItem($key));
$item = $this->pool->getItem($key);
// The cache hasn't been updated yet, even
// though the pool data has
$this->assertNotEquals($data[$key], $item->get());
}
}
public function testCommit()
{
$this->pool->clear();
// If there are no deferred items, this will return true
$this->assertTrue($this->pool->commit());
$data = [
'foo' => 'bar',
'bar' => 'baz',
'foobar' => 'foobarbaz'
];
$this->setupDeferredData($data);
// See that the data is returned by the pool
foreach($this->pool->getItems(array_keys($data)) as $key => $item)
{
$this->assertTrue($this->pool->hasItem($key));
// The cache hasn't been updated yet, even
// though the pool data has
$this->assertNotEquals($data[$key], $item->get());
}
$this->pool->commit();
// See that the data is saved in the cache backend
foreach($this->pool->getItems(array_keys($data)) as $key => $item)
{
$this->assertTrue($this->pool->hasItem($key));
$this->assertEquals($data[$key], $item->get());
}
}
protected function setupDeferredData($data)
{
foreach($data as $key => $val)
{
$item = $this->pool->getItem($key)
->set($val);
$this->assertTrue($this->pool->saveDeferred($item));
}
}
protected function setupDataInCache($data)
{
foreach($data as $key => $val)
{
$item = $this->pool->getItem($key)
->set($val);
$this->pool->save($item);
}
}
}