From b63a1e371ab9d4db408ff8614f0c29a7c8233392 Mon Sep 17 00:00:00 2001 From: Bilge Date: Tue, 20 Jun 2017 00:12:02 +0100 Subject: [PATCH] Refactored Porter to no longer be a repository of providers. Added Porter constructor that receives a container of providers. Removed provider tags. --- composer.json | 1 + src/Porter.php | 89 ++++--------- src/Provider/Resource/StaticResource.php | 5 - src/Specification/ImportSpecification.php | 20 +-- test/Integration/Porter/PorterTest.php | 122 +++++++----------- .../StaticDataImportSpecificationTest.php | 4 +- test/Unit/Porter/ImportSpecificationTest.php | 2 +- 7 files changed, 85 insertions(+), 158 deletions(-) diff --git a/composer.json b/composer.json index 8723548..8fdd418 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,7 @@ "scriptfusion/retry": "^1.1", "scriptfusion/retry-exception-handlers": "^1", "eloquent/enumeration": "^5", + "psr/container": "^1", "psr/cache": "^1", "zendframework/zend-uri": "^2" }, diff --git a/src/Porter.php b/src/Porter.php index feb6767..4164d01 100644 --- a/src/Porter.php +++ b/src/Porter.php @@ -1,6 +1,7 @@ providers = $providers; + } + /** * Imports data according to the design of the specified import specification. * @@ -47,7 +58,7 @@ public function import(ImportSpecification $specification) $records = $this->fetch( $specification->getResource(), - $specification->getProviderTag(), + $specification->getProviderName(), $specification->getCacheAdvice(), $specification->getMaxFetchAttempts(), $specification->getFetchExceptionHandler() @@ -90,12 +101,12 @@ public function importOne(ImportSpecification $specification) private function fetch( ProviderResource $resource, - $providerTag, + $providerName, CacheAdvice $cacheAdvice, $fetchAttempts, $fetchExceptionHandler ) { - $provider = $this->getProvider($resource->getProviderClassName(), $providerTag); + $provider = $this->getProvider($providerName ?: $resource->getProviderClassName()); $this->applyCacheAdvice($provider, $cacheAdvice); @@ -189,81 +200,25 @@ private function applyCacheAdvice(Provider $provider, CacheAdvice $cacheAdvice) } /** - * Registers the specified provider optionally identified by the specified tag. - * - * @param Provider $provider Provider. - * @param string|null $tag Optional. Provider tag. - * - * @return $this - * - * @throws ProviderAlreadyRegisteredException The specified provider is already registered. - */ - public function registerProvider(Provider $provider, $tag = null) - { - if ($this->hasProvider($name = get_class($provider), $tag)) { - throw new ProviderAlreadyRegisteredException("Provider already registered: \"$name\" with tag \"$tag\"."); - } - - $this->providers[$this->hashProviderName($name, $tag)] = $provider; - - return $this; - } - - /** - * Gets the provider matching the specified class name and optionally a tag. + * Gets the provider matching the specified name. * - * @param string $name Provider class name. - * @param string|null $tag Optional. Provider tag. + * @param string $name Provider name. * * @return Provider * * @throws ProviderNotFoundException The specified provider was not found. */ - public function getProvider($name, $tag = null) + private function getProvider($name) { - if ($this->hasProvider($name, $tag)) { - return $this->providers[$this->hashProviderName($name, $tag)]; + if ($this->providers->has($name)) { + return $this->providers->get($name); } try { - // Tags are not supported for lazy-loaded providers because every instance would be the same. - if ($tag === null) { - $this->registerProvider($provider = $this->getOrCreateProviderFactory()->createProvider("$name")); - - return $provider; - } + return $this->getOrCreateProviderFactory()->createProvider("$name"); } catch (ObjectNotCreatedException $exception) { - // We will throw our own exception. + throw new ProviderNotFoundException("No such provider registered: \"$name\".", $exception); } - - throw new ProviderNotFoundException( - "No such provider registered: \"$name\" with tag \"$tag\".", - isset($exception) ? $exception : null - ); - } - - /** - * Gets a value indicating whether the specified provider is registered. - * - * @param string $name Provider class name. - * @param string|null $tag Optional. Provider tag. - * - * @return bool True if the specified provider is registered, otherwise false. - */ - public function hasProvider($name, $tag = null) - { - return isset($this->providers[$this->hashProviderName($name, $tag)]); - } - - /** - * @param string $name Provider class name. - * @param string|null $tag Provider tag. - * - * @return string Provider identifier hash. - */ - private function hashProviderName($name, $tag) - { - return "$name#$tag"; } private function getOrCreateProviderFactory() diff --git a/src/Provider/Resource/StaticResource.php b/src/Provider/Resource/StaticResource.php index a969af9..7626b3b 100644 --- a/src/Provider/Resource/StaticResource.php +++ b/src/Provider/Resource/StaticResource.php @@ -19,11 +19,6 @@ public function getProviderClassName() return StaticDataProvider::class; } - public function getProviderTag() - { - return; - } - public function fetch(Connector $connector, EncapsulatedOptions $options = null) { return $this->data; diff --git a/src/Specification/ImportSpecification.php b/src/Specification/ImportSpecification.php index ffe3fce..09452f9 100644 --- a/src/Specification/ImportSpecification.php +++ b/src/Specification/ImportSpecification.php @@ -21,7 +21,7 @@ class ImportSpecification /** * @var string */ - private $providerTag; + private $providerName; /** * @var Transformer[] @@ -86,30 +86,32 @@ final public function getResource() } /** - * Gets the provider identifier tag. + * Gets the provider name. * - * @return string Provider tag. + * @return string Provider name. */ - final public function getProviderTag() + final public function getProviderName() { - return $this->providerTag; + return $this->providerName; } /** - * Sets the provider identifier tag. + * Sets the provider name. * - * @param string $tag Provider tag. + * @param string $tag Provider name. * * @return $this */ - final public function setProviderTag($tag) + final public function setProviderName($tag) { - $this->providerTag = "$tag"; + $this->providerName = "$tag"; return $this; } /** + * Gets the ordered list of transformers. + * * @return Transformer[] */ final public function getTransformers() diff --git a/test/Integration/Porter/PorterTest.php b/test/Integration/Porter/PorterTest.php index bdf3df4..d663db6 100644 --- a/test/Integration/Porter/PorterTest.php +++ b/test/Integration/Porter/PorterTest.php @@ -3,6 +3,7 @@ use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; use Mockery\MockInterface; +use Psr\Container\ContainerInterface; use ScriptFUSION\Porter\Cache\CacheAdvice; use ScriptFUSION\Porter\Cache\CacheToggle; use ScriptFUSION\Porter\Cache\CacheUnavailableException; @@ -16,8 +17,6 @@ use ScriptFUSION\Porter\PorterAware; use ScriptFUSION\Porter\Provider\Provider; use ScriptFUSION\Porter\Provider\Resource\ProviderResource; -use ScriptFUSION\Porter\Provider\StaticDataProvider; -use ScriptFUSION\Porter\ProviderAlreadyRegisteredException; use ScriptFUSION\Porter\ProviderNotFoundException; use ScriptFUSION\Porter\Specification\ImportSpecification; use ScriptFUSION\Porter\Specification\StaticDataImportSpecification; @@ -31,21 +30,36 @@ final class PorterTest extends \PHPUnit_Framework_TestCase { use MockeryPHPUnitIntegration; - /** @var Porter */ + /** + * @var Porter + */ private $porter; - /** @var Provider|MockInterface */ + /** + * @var Provider|MockInterface + */ private $provider; - /** @var ProviderResource */ + /** + * @var ProviderResource + */ private $resource; - /** @var ImportSpecification */ + /** + * @var ImportSpecification + */ private $specification; + /** + * @var ContainerInterface|MockInterface + */ + private $container; + protected function setUp() { - $this->porter = (new Porter)->registerProvider( + $this->porter = new Porter($this->container = $container = \Mockery::spy(ContainerInterface::class)); + + $this->registerProvider( $this->provider = \Mockery::mock(Provider::class) ->shouldReceive('fetch') @@ -60,69 +74,6 @@ protected function setUp() $this->specification = new ImportSpecification($this->resource); } - #region Providers - - public function testGetProvider() - { - self::assertSame($this->provider, $this->porter->getProvider(get_class($this->provider))); - } - - public function testRegisterSameProvider() - { - $this->setExpectedException(ProviderAlreadyRegisteredException::class); - - $this->porter->registerProvider($this->provider); - } - - public function testRegisterSameProviderType() - { - $this->setExpectedException(ProviderAlreadyRegisteredException::class); - - $this->porter->registerProvider(clone $this->provider); - } - - public function testRegisterProviderTag() - { - $this->porter->registerProvider($provider = clone $this->provider, 'foo'); - - self::assertSame($provider, $this->porter->getProvider(get_class($this->provider), 'foo')); - } - - public function testGetStaticProvider() - { - self::assertInstanceOf(StaticDataProvider::class, $this->porter->getProvider(StaticDataProvider::class)); - } - - public function testGetInvalidProvider() - { - $this->setExpectedException(ProviderNotFoundException::class); - - $this->porter->getProvider('foo'); - } - - public function testGetInvalidTag() - { - $this->setExpectedException(ProviderNotFoundException::class); - - $this->porter->getProvider(get_class($this->provider), 'foo'); - } - - public function testGetStaticProviderTag() - { - $this->setExpectedException(ProviderNotFoundException::class); - - $this->porter->getProvider(StaticDataProvider::class, 'foo'); - } - - public function testHasProvider() - { - self::assertTrue($this->porter->hasProvider(get_class($this->provider))); - self::assertFalse($this->porter->hasProvider(get_class($this->provider), 'foo')); - self::assertFalse($this->porter->hasProvider('foo')); - } - - #endregion - #region Import public function testImport() @@ -192,18 +143,22 @@ public function testPorterAwareTransformer() ); } - public function testImportTaggedResource() + /** + * Tests that when provider name is specified in an import specification its value is used instead of the default + * provider class name of the resource. + */ + public function testImportCustomProviderName() { - $this->porter->registerProvider( + $this->registerProvider( $provider = \Mockery::mock(Provider::class) ->shouldReceive('fetch') ->andReturn(new \ArrayIterator([$output = 'bar'])) ->getMock(), - $tag = 'foo' + $providerName = 'foo' ); $records = $this->porter->import( - (new ImportSpecification(MockFactory::mockResource($provider)))->setProviderTag($tag) + (new ImportSpecification(MockFactory::mockResource($provider)))->setProviderName($providerName) ); self::assertSame($output, $records->current()); @@ -217,6 +172,13 @@ public function testImportFailure() $this->porter->import($this->specification); } + public function testImportUnregisteredProvider() + { + $this->setExpectedException(ProviderNotFoundException::class); + + $this->porter->import((new ImportSpecification($this->resource))->setProviderName('foo')); + } + #endregion #region Import one @@ -337,7 +299,7 @@ public function testFilter() public function testApplyCacheAdvice() { - $this->porter->registerProvider( + $this->registerProvider( $provider = \Mockery::mock(implode(',', [Provider::class, CacheToggle::class])) ->shouldReceive('fetch')->andReturn(new \EmptyIterator) ->shouldReceive('disableCache')->once() @@ -355,4 +317,14 @@ public function testCacheUnavailable() $this->porter->import($this->specification->setCacheAdvice(CacheAdvice::MUST_CACHE())); } + + private function registerProvider(Provider $provider, $name = null) + { + $name = $name ?: get_class($provider); + + $this->container + ->shouldReceive('has')->with($name)->andReturn(true) + ->shouldReceive('get')->with($name)->andReturn($provider) + ; + } } diff --git a/test/Integration/Porter/Specification/StaticDataImportSpecificationTest.php b/test/Integration/Porter/Specification/StaticDataImportSpecificationTest.php index 9c7db13..4bebb02 100644 --- a/test/Integration/Porter/Specification/StaticDataImportSpecificationTest.php +++ b/test/Integration/Porter/Specification/StaticDataImportSpecificationTest.php @@ -1,6 +1,7 @@ import(new StaticDataImportSpecification(new \ArrayIterator(['foo']))); + $records = (new Porter(\Mockery::spy(ContainerInterface::class))) + ->import(new StaticDataImportSpecification(new \ArrayIterator(['foo']))); self::assertSame('foo', $records->current()); } diff --git a/test/Unit/Porter/ImportSpecificationTest.php b/test/Unit/Porter/ImportSpecificationTest.php index 9a5302b..f944f02 100644 --- a/test/Unit/Porter/ImportSpecificationTest.php +++ b/test/Unit/Porter/ImportSpecificationTest.php @@ -56,7 +56,7 @@ public function testProviderData() public function testProviderTag() { - self::assertSame($tag = 'foo', $this->specification->setProviderTag($tag)->getProviderTag()); + self::assertSame($tag = 'foo', $this->specification->setProviderName($tag)->getProviderName()); } public function testAddTransformer()