Skip to content

Commit

Permalink
Refactor ClassBuilder Tests
Browse files Browse the repository at this point in the history
Changed:
- Improved routine in `CacheBuilder::resolveOneDriver()`
- Replaced `expectException()` methods with `@expectedException` comment tags
- Improved unit tests

Fixed:
- Comments for `CacheBuilder`
  • Loading branch information
mcaskill committed May 7, 2018
1 parent 3908f78 commit d4fb6c5
Show file tree
Hide file tree
Showing 8 changed files with 361 additions and 155 deletions.
63 changes: 39 additions & 24 deletions src/Charcoal/Cache/CacheBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
use Stash\Pool;

/**
* Model Loader Builder.
* Cache Pool Builder
*
* Build custom ModelLoader objects with a certain obj type / optional obj key.
* Build custom PSR-6 cache pools using Stash drivers.
*/
final class CacheBuilder
{
Expand All @@ -27,7 +27,7 @@ final class CacheBuilder
private $drivers;

/**
* Defaultlogger instance.
* Default logger instance.
*
* @var \Psr\Log\LoggerInterface|null
*/
Expand Down Expand Up @@ -207,7 +207,7 @@ private function resolveDriver($driver)
*
* @param mixed $driver The name of a registered cache driver,
* the class name or instance of a {@see DriverInterface cache driver}.
* @throws InvalidArgumentException When passed invalid or nonexistant driver name, class name, or object.
* @throws InvalidArgumentException When passed an invalid or nonexistant driver name, class name, or object.
* @return DriverInterface
*/
private function resolveOneDriver($driver)
Expand All @@ -218,34 +218,49 @@ private function resolveOneDriver($driver)
);
}

$isObj = is_object($driver);
if (is_object($driver)) {
if ($driver instanceof DriverInterface) {
return $driver;
} else {
throw new InvalidArgumentException(sprintf(
'Driver class %s must implement %s',
get_class($driver),
DriverInterface::class
));
}
}

$name = $driver;
if (isset($this->drivers[$name])) {
$driver = $this->drivers[$name];

if (empty($driver)) {
throw new InvalidArgumentException(
sprintf('Driver "%s" does not exist', $name)
);
}

if (!$isObj) {
$name = $driver;
if (isset($this->drivers[$name])) {
$driver = $this->drivers[$name];
if (empty($driver)) {
if (is_object($driver)) {
if ($driver instanceof DriverInterface) {
return $driver;
} else {
throw new InvalidArgumentException(sprintf(
'Driver "%s" does not exist',
$name
'Driver "%s": Class %s must implement %s',
$name,
get_class($driver),
DriverInterface::class
));
}
$isObj = is_object($driver);
}
}

if (is_a($driver, DriverInterface::class, true)) {
return $isObj ? $driver : new $driver();
return new $driver();
}

throw new InvalidArgumentException(sprintf(
'Unsupported driver "%s"',
(is_object($driver)
? get_class($driver)
: (is_string($driver)
? $driver
: gettype($driver)))
));
throw new InvalidArgumentException(
sprintf('Driver "%s" cannot be resolved', $name)
);
}

/**
Expand Down Expand Up @@ -311,7 +326,7 @@ private function setNamespace($namespace)
* Using this function developers can have the builder generate custom Pool objects.
*
* @param string $class The pool class name.
* @throws InvalidArgumentException When passed invalid or nonexistant class.
* @throws InvalidArgumentException When passed an invalid or nonexistant class.
* @return void
*/
private function setPoolClass($class)
Expand Down Expand Up @@ -341,7 +356,7 @@ private function setPoolClass($class)
* Using this function developers can have the pool class generate custom Item objects.
*
* @param string $class The item class name.
* @throws InvalidArgumentException When passed invalid or nonexistant class.
* @throws InvalidArgumentException When passed an invalid or nonexistant class.
* @return void
*/
private function setItemClass($class)
Expand Down
6 changes: 3 additions & 3 deletions src/Charcoal/Cache/CacheConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ public function setDefaultTtl($ttl)
{
if (!is_numeric($ttl)) {
throw new InvalidArgumentException(
'TTL must be an integer (seconds).'
'TTL must be an integer (seconds)'
);
}

Expand Down Expand Up @@ -209,14 +209,14 @@ public function setPrefix($prefix)
{
if (!is_string($prefix)) {
throw new InvalidArgumentException(
'Prefix must be a string.'
'Prefix must be a string'
);
}

/** @see \Stash\Pool\::setNamespace */
if (!ctype_alnum($prefix)) {
throw new InvalidArgumentException(
'Prefix must be alphanumeric.'
'Prefix must be alphanumeric'
);
}

Expand Down
42 changes: 29 additions & 13 deletions tests/Charcoal/Cache/CacheConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public function testActive()
* @covers ::setTypes
* @covers ::types
*/
public function testReplaceTypes()
public function testReplaceDrivers()
{
// Chainable
$that = $this->cfg->setTypes([ 'memcache', 'noop' ]);
Expand All @@ -104,7 +104,7 @@ public function testReplaceTypes()
* @covers ::addType
* @covers ::types
*/
public function testAddTypes()
public function testAddDrivers()
{
// Chainable
$that = $this->cfg->addTypes([ 'memcache', 'noop' ]);
Expand All @@ -118,13 +118,14 @@ public function testAddTypes()
}

/**
* @expectedException InvalidArgumentException
* @expectedExceptionMessage Invalid cache type: "foobar"
*
* @covers ::validTypes
* @covers ::addType
*/
public function testUnsupportedType()
public function testAddDriverOnInvalidType()
{
// Bad Value
$this->expectException(InvalidArgumentException::class);
$this->cfg->addType('foobar');
}

Expand All @@ -140,37 +141,52 @@ public function testDefaultTtl()

// Mutated State
$this->assertEquals(42, $this->cfg->defaultTtl());
}

// Bad Value
$this->expectException(InvalidArgumentException::class);
/**
* @expectedException InvalidArgumentException
* @expectedExceptionMessage TTL must be an integer (seconds)
*
* @covers ::setDefaultTtl
*/
public function testSetDefaultTtlOnInvalidType()
{
$this->cfg->setDefaultTtl('foo');
}

/**
* @covers ::setPrefix
* @covers ::prefix
*/
public function testPrefix1()
public function testPrefix()
{
// Chainable
$that = $this->cfg->setPrefix('foo');
$this->assertSame($this->cfg, $that);

// Mutated State
$this->assertEquals('foo', $this->cfg->prefix());
}

// Bad Value
$this->expectException(InvalidArgumentException::class);
/**
* @expectedException InvalidArgumentException
* @expectedExceptionMessage Prefix must be a string
*
* @covers ::setPrefix
*/
public function testSetPrefixOnInvalidType()
{
$this->cfg->setPrefix(false);
}

/**
* @expectedException InvalidArgumentException
* @expectedExceptionMessage Prefix must be alphanumeric
*
* @covers ::setPrefix
*/
public function testPrefix2()
public function testSetPrefixOnInvalidValue()
{
// Bad Value
$this->expectException(InvalidArgumentException::class);
$this->cfg->setPrefix('foo!#$bar');
}
}
5 changes: 3 additions & 2 deletions tests/Charcoal/Cache/CachePoolAwareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ public function testCachePool()
}

/**
* @expectedException RuntimeException
* @expectedExceptionMessage Cache Pool is not defined for "Charcoal\Tests\Mocks\CachePoolAware"
*
* @covers ::cachePool
*/
public function testMissingPool()
{
$this->expectException(\RuntimeException::class);

$obj = new CachePoolAware();
$obj->cachePool();
}
Expand Down
86 changes: 86 additions & 0 deletions tests/Charcoal/Cache/Factory/AbstractCacheBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,19 @@ public function createBuilder(array $args = [])
return new CacheBuilder($args);
}

/**
* Create a new cache driver for a specific driver name.
*
* @param string $name Cache driver name.
* @param array $options Cache driver options.
* @return DriverInterface
*/
public function createDriver($name, array $options = [])
{
$class = DriverList::getDriverClass($name);
return new $class($options);
}

/**
* Returns a list of cache drivers that are also supported by this system.
*
Expand All @@ -57,4 +70,77 @@ public function getDriverClassNames()
unset($drivers['Composite']);
return $drivers;
}

/**
* Create a new cache driver for a specific driver name.
*
* @param string $name Cache driver name.
* @return string
*/
public function getDriverClass($name)
{
return DriverList::getDriverClass($name);
}

/**
* Returns the default attributes of the CacheBuilder.
*
* @return array
*/
public function getDefaultBuilderAttributes()
{
return [
'pool_class' => Pool::class,
'item_class' => null,
'namespace' => null,
'logger' => null,
];
}

/**
* Returns the default attributes of the Stash Pool.
*
* @return array
*/
public function getDefaultPoolAttributes()
{
return [
'item_class' => '\Stash\Item',
'namespace' => null,
'logger' => null,
];
}

/**
* Reports an error if $builder does not use the default options.
*
* @param CacheBuilder $builder The cache builder to test.
* @return void
*/
public function assertCacheBuilderHasDefaultAttributes(CacheBuilder $builder)
{
$builderDefaults = $this->getDefaultBuilderAttributes();

$this->assertAttributeEquals($builderDefaults['pool_class'], 'poolClass', $builder);
$this->assertAttributeEquals($builderDefaults['item_class'], 'itemClass', $builder);
$this->assertAttributeEquals($builderDefaults['namespace'], 'namespace', $builder);
$this->assertAttributeEquals($builderDefaults['logger'], 'logger', $builder);
}

/**
* Reports an error if $pool does not use the default options.
*
* @param PoolInterface $pool The cache pool to test.
* @return void
*/
public function assertCachePoolHasDefaultAttributes(PoolInterface $pool)
{
$builderDefaults = $this->getDefaultBuilderAttributes();
$poolDefaults = $this->getDefaultPoolAttributes();

$this->assertInstanceOf($builderDefaults['pool_class'], $pool);
$this->assertAttributeEquals($poolDefaults['item_class'], 'itemClass', $pool);
$this->assertAttributeEquals($poolDefaults['namespace'], 'namespace', $pool);
$this->assertAttributeEquals($poolDefaults['logger'], 'logger', $pool);
}
}
Loading

0 comments on commit d4fb6c5

Please sign in to comment.