Skip to content

Commit

Permalink
Merge pull request #2 from alex-patterson-webdev/feature/1.0.0
Browse files Browse the repository at this point in the history
Additional unit test coverage for ApplicationOptionsProviderTrait.
  • Loading branch information
alex-patterson-webdev authored Apr 14, 2020
2 parents 153a9af + b362d86 commit 1199678
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/ApplicationOptionsProviderTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Arp\LaminasFactory\Exception\ServiceNotCreatedException;
use Arp\LaminasFactory\Exception\ServiceNotFoundException;
use Laminas\ServiceManager\AbstractPluginManager;
use Psr\Container\ContainerInterface;

/**
Expand Down
35 changes: 19 additions & 16 deletions src/ServiceOptionsProviderTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Arp\LaminasFactory;

use Arp\LaminasFactory\Exception\ServiceNotCreatedException;
use Laminas\ServiceManager\AbstractPluginManager;
use Psr\Container\ContainerInterface;

/**
Expand Down Expand Up @@ -37,18 +38,13 @@ trait ServiceOptionsProviderTrait
public function getServiceOptions(ContainerInterface $container, string $requestedName, $key = null): array
{
$applicationOptions = $this->getApplicationOptions($container);
$serviceOptionsKey = $this->getServiceOptionsKey($key);

if (null !== $key) {
$this->setServiceOptionsKey($key);
}

$key = $this->serviceOptionsKey;

if (!array_key_exists($key, $applicationOptions)) {
if (!array_key_exists($serviceOptionsKey, $applicationOptions)) {
throw new ServiceNotCreatedException(
sprintf(
'Unable to find a configuration key for service of type \'%s\' while creating service \'%s\'.',
$key,
$serviceOptionsKey,
$requestedName
)
);
Expand All @@ -58,29 +54,36 @@ public function getServiceOptions(ContainerInterface $container, string $request
? $this->factoryOptions
: [];

if (isset($applicationOptions[$key][$requestedName])) {
if (!is_array($applicationOptions[$key][$requestedName])) {
if (isset($applicationOptions[$serviceOptionsKey][$requestedName])) {
if (!is_array($applicationOptions[$serviceOptionsKey][$requestedName])) {
throw new ServiceNotCreatedException(
sprintf(
'The configuration options must be of type \'array\'; \'%s\' provided for service \'%s\'.',
gettype($applicationOptions[$key][$requestedName]),
gettype($applicationOptions[$serviceOptionsKey][$requestedName]),
$requestedName
)
);
}
$serviceOptions = array_replace_recursive($serviceOptions, $applicationOptions[$key][$requestedName]);
$serviceOptions = array_replace_recursive(
$serviceOptions,
$applicationOptions[$serviceOptionsKey][$requestedName]
);
}

return $serviceOptions;
}

/**
* Set the key used to load the service options.
* @param string|null $key
*
* @param string $serviceOptionsKey
* @return string
*/
public function setServiceOptionsKey(string $serviceOptionsKey): void
private function getServiceOptionsKey(?string $key): string
{
$this->serviceOptionsKey = $serviceOptionsKey;
if (null === $key) {
return $this->serviceOptionsKey;
}

return $key;
}
}
116 changes: 112 additions & 4 deletions test/phpunit/ApplicationOptionsProviderTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace ArpTest\LaminasFactory;

use Arp\LaminasFactory\ApplicationOptionsProviderTrait;
use Arp\LaminasFactory\Exception\ServiceNotCreatedException;
use Arp\LaminasFactory\Exception\ServiceNotFoundException;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
Expand All @@ -24,23 +25,26 @@ final class ApplicationOptionsProviderTraitTest extends TestCase
/**
* @var string
*/
private $optionsService;
private $optionsKey = 'arp';

/**
* @var string
*/
private $optionsService = 'config';

/**
* Setup the test dependencies.
*/
public function setUp(): void
{
$this->optionsService = 'config';

$this->container = $this->getMockForAbstractClass(ContainerInterface::class);
}

/**
* Assert that the getApplicationOptions() method will throw a ServiceNotFoundException if the configured
* application service cannot be found within the container.
*/
public function testWillThrowServiceNotFoundExceptionIfTheApplicationServiceCannotBeFound(): void
public function testWillThrowServiceNotFoundExceptionIfTheOptionsServiceCannotBeFound(): void
{
/** @var ApplicationOptionsProviderTrait|MockObject $subject */
$subject = $this->getMockForTrait(ApplicationOptionsProviderTrait::class);
Expand All @@ -62,4 +66,108 @@ public function testWillThrowServiceNotFoundExceptionIfTheApplicationServiceCann

$subject->getApplicationOptions($this->container);
}

/**
* Assert that a ServiceNotCreatedException is thrown when the returned ApplicationOptionsService is not of
* type array.
*/
public function testWillThrowServiceNotCreatedExceptionIfTheReturnedOptionsServiceIsNotAnArray(): void
{
/** @var ApplicationOptionsProviderTrait|MockObject $subject */
$subject = $this->getMockForTrait(ApplicationOptionsProviderTrait::class);

$this->container->expects($this->once())
->method('has')
->with($this->optionsService)
->willReturn(true);

$invalid = false; // non-array value

$this->container->expects($this->once())
->method('get')
->with($this->optionsService)
->willReturn($invalid);

$this->expectException(ServiceNotCreatedException::class);
$this->expectExceptionMessage(
sprintf(
'The application key \'%s\' could not be found within the application options service \'%s\'.',
$this->optionsKey,
$this->optionsService
)
);

$subject->getApplicationOptions($this->container);
}

/**
* Assert that a ServiceNotCreatedException is thrown when the returned ApplicationOptionsService does not
* container a array key matching the options key.
*/
public function testWillThrowServiceNotCreatedExceptionIfTheReturnedOptionsServiceIsMissingOptionsKey(): void
{
/** @var ApplicationOptionsProviderTrait|MockObject $subject */
$subject = $this->getMockForTrait(ApplicationOptionsProviderTrait::class);

$this->container->expects($this->once())
->method('has')
->with($this->optionsService)
->willReturn(true);

$invalid = [
'foo' => 123,
];

$this->container->expects($this->once())
->method('get')
->with($this->optionsService)
->willReturn($invalid);

$this->expectException(ServiceNotCreatedException::class);
$this->expectExceptionMessage(
sprintf(
'The application key \'%s\' could not be found within the application options service \'%s\'.',
$this->optionsKey,
$this->optionsService
)
);

$subject->getApplicationOptions($this->container);
}

/**
* Assert that a ServiceNotCreatedException is thrown when the resolved service options are not of type array.
*/
public function testWillThrowServiceNotCreatedExceptionIfTheServiceOptionsAreNotOfTypeArray(): void
{
/** @var ApplicationOptionsProviderTrait|MockObject $subject */
$subject = $this->getMockForTrait(ApplicationOptionsProviderTrait::class);

$this->container->expects($this->once())
->method('has')
->with($this->optionsService)
->willReturn(true);

$invalid = [
$this->optionsKey => false, // invalid options type!
];

$this->container->expects($this->once())
->method('get')
->with($this->optionsService)
->willReturn($invalid);

$this->expectException(ServiceNotCreatedException::class);
$this->expectExceptionMessage(
sprintf(
'The application options must be an \'array\' or object of type \'%s\'; \'%s\' provided in \'%s::%s\'.',
\Traversable::class,
gettype($invalid[$this->optionsKey]),
ApplicationOptionsProviderTrait::class,
'getApplicationOptions'
)
);

$subject->getApplicationOptions($this->container);
}
}

0 comments on commit 1199678

Please sign in to comment.