* @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\{Item, ItemCollection, Pool}; use Aviat\Banker\Exception\InvalidArgumentException; use Monolog\Logger; use Monolog\Handler\SyslogHandler; use PHPUnit\Framework\TestCase; use Psr\Log\{LoggerInterface, NullLogger}; class PoolTest extends TestCase { protected $pool; public function setUp() { $this->pool = new Pool([ 'driver' => 'null', 'connection' => [] ]); } public function testGetDefaultLogger(): void { $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(): void { $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(): void { $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(): void { $item = $this->pool->getItem('foo'); $this->assertInstanceOf(Item::class, $item); } public function testItemBadKey(): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Cache key must be a string.'); $this->pool->getItem([]); } public function testGetItemsBadKey(): void { $this->expectException(InvalidArgumentException::class); $this->pool->getItems([1,3,2]); } public function testGetItems(): void { $collection = $this->pool->getItems(['foo', 'bar', 'baz']); $this->assertInstanceOf(ItemCollection::class, $collection); foreach($collection as $item) { $this->assertInstanceOf(Item::class, $item); } } public function testGetItemsDeferredItems(): void { $this->pool->clear(); $deferredValues = ['x' => 1, 'y' => 2, 'z' => 3]; $keys = ['x', 'y', 'z']; foreach ($deferredValues as $key => $value) { $item = $this->pool->getItem($key)->set($value); $this->pool->saveDeferred($item); } $collection = $this->pool->getItems($keys); foreach($collection as $key => $item) { $this->assertSame($deferredValues[$key], $item->get()); } $this->assertCount(3, $collection); } public function testEmptyGetItems(): void { $this->pool->clear(); $collection = $this->pool->getItems(); $this->assertInstanceOf(ItemCollection::class, $collection); $this->assertCount(0, $collection); } public function testHasItem(): void { $this->pool->clear(); // 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(): void { $this->pool->clear(); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Cache key must be a string.'); $this->pool->hasItem(34); } public function testClear(): void { // 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(): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage("Cache key must be a string."); $this->pool->deleteItem(34); } public function testDeleteItemThatDoesNotExist(): void { $this->pool->clear(); $this->assertFalse($this->pool->deleteItem('foo')); } public function testDeleteItem(): void { // 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(): void { $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(): void { $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); // Since the value has been deferred, // the pool will return the updated value, // even though the cache hasn't been updated yet $this->assertEquals($data[$key], $item->get()); } } public function testCommit(): void { $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)); $this->assertEquals($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): void { foreach($data as $key => $val) { $item = $this->pool->getItem($key) ->set($val); $this->assertTrue($this->pool->saveDeferred($item)); } } protected function setupDataInCache($data): void { foreach($data as $key => $val) { $item = $this->pool->getItem($key) ->set($val); $this->pool->save($item); } } }