From 8d2b46d26e6139b61527ff4a74c11cff8e5931fe Mon Sep 17 00:00:00 2001 From: webimpress Date: Tue, 20 Feb 2018 08:47:48 +0000 Subject: [PATCH 01/13] Invokable tests from common container test library --- test/ConfigTest.php | 35 ----------------------------------- test/ContainerTest.php | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 35 deletions(-) create mode 100644 test/ContainerTest.php diff --git a/test/ConfigTest.php b/test/ConfigTest.php index 297a447..da27acc 100644 --- a/test/ConfigTest.php +++ b/test/ConfigTest.php @@ -238,39 +238,4 @@ public function testFactoryGetsServiceName() self::assertSame($container, array_shift($args)); self::assertEquals('foo-bar', array_shift($args)); } - - public function testInvokableWithoutAlias() - { - $dependencies = [ - 'invokables' => [ - TestAsset\Service::class, - ], - ]; - - $container = $this->builder->newConfiguredInstance([new Config(['dependencies' => $dependencies])]); - - self::assertTrue($container->has(TestAsset\Service::class)); - $service = $container->get(TestAsset\Service::class); - self::assertInstanceOf(TestAsset\Service::class, $service); - self::assertTrue($container->has('0')); - } - - public function testInvokableWithAlias() - { - $dependencies = [ - 'invokables' => [ - 'alias' => TestAsset\Service::class, - ], - ]; - - $container = $this->builder->newConfiguredInstance([new Config(['dependencies' => $dependencies])]); - - self::assertTrue($container->has('alias')); - $service = $container->get('alias'); - self::assertInstanceOf(TestAsset\Service::class, $service); - self::assertTrue($container->has(TestAsset\Service::class)); - $originService = $container->get(TestAsset\Service::class); - self::assertInstanceOf(TestAsset\Service::class, $originService); - self::assertSame($service, $originService); - } } diff --git a/test/ContainerTest.php b/test/ContainerTest.php new file mode 100644 index 0000000..303bf81 --- /dev/null +++ b/test/ContainerTest.php @@ -0,0 +1,27 @@ + $config])); + } +} From 6cab1583b0b084e07b0bf2a38e89ce0db32a3791 Mon Sep 17 00:00:00 2001 From: webimpress Date: Tue, 20 Feb 2018 11:41:05 +0000 Subject: [PATCH 02/13] Added `aliases` and `invokables` SM support --- src/Config.php | 19 +++++++++-- test/ConfigTest.php | 72 +----------------------------------------- test/ContainerTest.php | 4 +++ 3 files changed, 21 insertions(+), 74 deletions(-) diff --git a/src/Config.php b/src/Config.php index 6e3c1f9..2830924 100644 --- a/src/Config.php +++ b/src/Config.php @@ -12,6 +12,7 @@ use ArrayObject; use Aura\Di\Container; use Aura\Di\ContainerConfigInterface; +use Aura\Di\Exception\ServiceNotFound; use function is_array; use function is_callable; @@ -92,10 +93,22 @@ public function define(Container $container) && is_array($dependencies['factories']) ) { foreach ($dependencies['factories'] as $service => $factory) { - if (! $container->has($factory)) { - $container->set($factory, $container->lazyNew($factory)); + if (is_callable($factory)) { + $container->set($service, $container->lazy($factory, $container, $service)); + continue; } - $container->set($service, $container->lazyGetCall($factory, '__invoke', $container, $service)); + + $container->set($service, $container->lazy(function ($container, $service) use ($factory) { + if (! class_exists($factory)) { + throw new ServiceNotFound(sprintf( + 'Service %s cannot be initialized by factory %s', + $service, + $factory + )); + } + + return (new $factory())($container, $service); + }, $container, $service)); } } diff --git a/test/ConfigTest.php b/test/ConfigTest.php index da27acc..f69ba2f 100644 --- a/test/ConfigTest.php +++ b/test/ConfigTest.php @@ -1,7 +1,7 @@ get('foo-bar')); } - public function testInjectServiceFactory() - { - $factory = new TestAsset\Factory(); - - $dependencies = [ - 'services' => [ - 'factory' => $factory, - ], - 'factories' => [ - 'foo-bar' => 'factory', - ], - ]; - - $container = $this->builder->newConfiguredInstance([new Config(['dependencies' => $dependencies])]); - - self::assertTrue($container->has('factory')); - self::assertTrue($container->has('foo-bar')); - self::assertInstanceOf(TestAsset\Service::class, $container->get('foo-bar')); - } - - public function testInjectInvokableFactory() - { - $dependencies = [ - 'factories' => [ - 'foo-bar' => TestAsset\Factory::class, - ], - ]; - - $container = $this->builder->newConfiguredInstance([new Config(['dependencies' => $dependencies])]); - - self::assertTrue($container->has('foo-bar')); - self::assertInstanceOf(TestAsset\Service::class, $container->get('foo-bar')); - } - - public function testInjectInvokable() - { - $dependencies = [ - 'invokables' => [ - 'foo-bar' => TestAsset\Service::class, - ], - ]; - - $container = $this->builder->newConfiguredInstance([new Config(['dependencies' => $dependencies])]); - - self::assertTrue($container->has('foo-bar')); - self::assertInstanceOf(TestAsset\Service::class, $container->get('foo-bar')); - } - public function testInjectAlias() { $myService = new TestAsset\Service(); @@ -217,25 +168,4 @@ public function testInjectMultipleDelegators() $service->injected ); } - - public function testFactoryGetsServiceName() - { - $factory = new FactoryWithName(); - - $dependencies = [ - 'services' => [ - 'factory' => $factory, - ], - 'factories' => [ - 'foo-bar' => 'factory', - ], - ]; - - $container = $this->builder->newConfiguredInstance([new Config(['dependencies' => $dependencies])]); - $args = $container->get('foo-bar'); - - self::assertCount(2, $args); - self::assertSame($container, array_shift($args)); - self::assertEquals('foo-bar', array_shift($args)); - } } diff --git a/test/ContainerTest.php b/test/ContainerTest.php index 303bf81..0cada63 100644 --- a/test/ContainerTest.php +++ b/test/ContainerTest.php @@ -12,10 +12,14 @@ use Psr\Container\ContainerInterface; use Zend\AuraDi\Config\Config; use Zend\AuraDi\Config\ContainerFactory; +use Zend\ContainerTest\AliasTestTrait; +use Zend\ContainerTest\FactoryTestTrait; use Zend\ContainerTest\InvokableTestTrait; class ContainerTest extends \Zend\ContainerTest\ContainerTest { + use AliasTestTrait; + use FactoryTestTrait; use InvokableTestTrait; protected function createContainer(array $config) : ContainerInterface From 3ee9eb6617f3e4f80837f7389fcba07a939e0bf2 Mon Sep 17 00:00:00 2001 From: webimpress Date: Wed, 21 Mar 2018 12:37:18 +0000 Subject: [PATCH 03/13] Removed redundant tests - use tests from zend-container-config-test repo --- composer.json | 9 +- composer.lock | 84 ++++++++++++++++- test/ConfigTest.php | 134 +-------------------------- test/ContainerTest.php | 12 +-- test/TestAsset/Delegator.php | 20 ---- test/TestAsset/Delegator1Factory.php | 23 ----- test/TestAsset/Delegator2Factory.php | 14 --- test/TestAsset/DelegatorFactory.php | 20 ---- test/TestAsset/Factory.php | 20 ---- test/TestAsset/FactoryWithName.php | 18 ---- test/TestAsset/Service.php | 25 ----- 11 files changed, 96 insertions(+), 283 deletions(-) delete mode 100644 test/TestAsset/Delegator.php delete mode 100644 test/TestAsset/Delegator1Factory.php delete mode 100644 test/TestAsset/Delegator2Factory.php delete mode 100644 test/TestAsset/DelegatorFactory.php delete mode 100644 test/TestAsset/Factory.php delete mode 100644 test/TestAsset/FactoryWithName.php delete mode 100644 test/TestAsset/Service.php diff --git a/composer.json b/composer.json index 639b3e3..6f6b0ab 100644 --- a/composer.json +++ b/composer.json @@ -23,8 +23,15 @@ }, "require-dev": { "phpunit/phpunit": "^7.0.2", - "zendframework/zend-coding-standard": "~1.0.0" + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-container-config-test": "dev-feature/review-tests" }, + "repositories": [ + { + "type": "git", + "url": "https://github.com/weierophinney/zend-container-config-test" + } + ], "conflict": { "container-interop/container-interop": "<1.2.0" }, diff --git a/composer.lock b/composer.lock index 6a18fb0..77edfbd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "344eb78193639204365909251b0b520b", + "content-hash": "a0097eb90ab337fd96144b559b77bf7b", "packages": [ { "name": "aura/di", @@ -1701,11 +1701,91 @@ "zf" ], "time": "2016-11-09T21:30:43+00:00" + }, + { + "name": "zendframework/zend-container-config-test", + "version": "dev-feature/review-tests", + "source": { + "type": "git", + "url": "https://github.com/weierophinney/zend-container-config-test", + "reference": "536e9f3a5d9c5ea86aec17ad172277d0afac6adb" + }, + "require": { + "php": "^7.1", + "psr/container": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0.2", + "zendframework/zend-auradi-config": "^1.0.0", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-pimple-config": "^1.0.0", + "zendframework/zend-servicemanager": "^3.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "files": [ + "src/TestAsset/factory.php", + "src/TestAsset/factory-with-name.php" + ], + "psr-4": { + "Zend\\ContainerConfigTest\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "ZendTest\\ContainerConfigTest\\": "test/" + } + }, + "scripts": { + "check": [ + "@cs-check", + "@test" + ], + "cs-check": [ + "phpcs" + ], + "cs-fix": [ + "phpcbf" + ], + "test": [ + "phpunit --colors=always" + ], + "test-coverage": [ + "phpunit --colors=always --coverage-clover clover.xml" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "description": "Expressive PSR-11 container configuration tests", + "keywords": [ + "container", + "expressive", + "psr-11", + "test", + "zendframework", + "zf" + ], + "support": { + "issues": "https://github.com/zendframework/zend-container-config-test/issues", + "source": "https://github.com/zendframework/zend-container-config-test", + "rss": "https://github.com/zendframework/zend-container-config-test/releases.atom", + "slack": "https://zendframework-slack.herokuapp.com", + "forum": "https://discourse.zendframework.com/c/questions/expressive" + }, + "time": "2018-03-20T20:47:31+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "zendframework/zend-container-config-test": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/test/ConfigTest.php b/test/ConfigTest.php index f69ba2f..881a329 100644 --- a/test/ConfigTest.php +++ b/test/ConfigTest.php @@ -9,12 +9,11 @@ namespace ZendTest\AuraDi\Config; +use ArrayObject; use Aura\Di\ContainerBuilder; use PHPUnit\Framework\TestCase; use Zend\AuraDi\Config\Config; -use function array_shift; - class ConfigTest extends TestCase { /** @var ContainerBuilder */ @@ -36,136 +35,7 @@ public function testInjectConfiguration() $container = $this->builder->newConfiguredInstance([new Config($config)]); self::assertTrue($container->has('config')); - self::assertInstanceOf(\ArrayObject::class, $container->get('config')); + self::assertInstanceOf(ArrayObject::class, $container->get('config')); self::assertSame($config, $container->get('config')->getArrayCopy()); } - - public function testInjectService() - { - $myService = new TestAsset\Service(); - $dependencies = [ - 'services' => [ - 'foo-bar' => $myService, - ], - ]; - - $container = $this->builder->newConfiguredInstance([new Config(['dependencies' => $dependencies])]); - - self::assertTrue($container->has('foo-bar')); - self::assertSame($myService, $container->get('foo-bar')); - } - - public function testInjectAlias() - { - $myService = new TestAsset\Service(); - - $dependencies = [ - 'services' => [ - 'foo-bar' => $myService, - ], - 'aliases' => [ - 'alias' => 'foo-bar', - ], - ]; - - $container = $this->builder->newConfiguredInstance([new Config(['dependencies' => $dependencies])]); - - self::assertTrue($container->has('alias')); - self::assertSame($myService, $container->get('alias')); - } - - public function testInjectDelegatorForInvokable() - { - $dependencies = [ - 'invokables' => [ - 'foo-bar' => TestAsset\Service::class, - ], - 'delegators' => [ - 'foo-bar' => [ - TestAsset\DelegatorFactory::class, - ], - ], - ]; - - $container = $this->builder->newConfiguredInstance([new Config(['dependencies' => $dependencies])]); - - self::assertTrue($container->has('foo-bar')); - $delegator = $container->get('foo-bar'); - self::assertInstanceOf(TestAsset\Delegator::class, $delegator); - $callback = $delegator->callback; - self::assertInstanceOf(TestAsset\Service::class, $callback()); - } - - public function testInjectDelegatorForService() - { - $myService = new TestAsset\Service(); - $dependencies = [ - 'services' => [ - 'foo-bar' => $myService, - ], - 'delegators' => [ - 'foo-bar' => [ - TestAsset\DelegatorFactory::class, - ], - ], - ]; - - $container = $this->builder->newConfiguredInstance([new Config(['dependencies' => $dependencies])]); - - self::assertTrue($container->has('foo-bar')); - $delegator = $container->get('foo-bar'); - self::assertInstanceOf(TestAsset\Delegator::class, $delegator); - $callback = $delegator->callback; - self::assertSame($myService, $callback()); - } - - public function testInjectDelegatorForFactory() - { - $dependencies = [ - 'factories' => [ - 'foo-bar' => TestAsset\Factory::class, - ], - 'delegators' => [ - 'foo-bar' => [ - TestAsset\DelegatorFactory::class, - ], - ], - ]; - - $container = $this->builder->newConfiguredInstance([new Config(['dependencies' => $dependencies])]); - - self::assertTrue($container->has('foo-bar')); - $delegator = $container->get('foo-bar'); - self::assertInstanceOf(TestAsset\Delegator::class, $delegator); - $callback = $delegator->callback; - self::assertInstanceOf(TestAsset\Service::class, $callback()); - } - - public function testInjectMultipleDelegators() - { - $dependencies = [ - 'invokables' => [ - 'foo-bar' => TestAsset\Service::class, - ], - 'delegators' => [ - 'foo-bar' => [ - TestAsset\Delegator1Factory::class, - TestAsset\Delegator2Factory::class, - ], - ], - ]; - - $container = $this->builder->newConfiguredInstance([new Config(['dependencies' => $dependencies])]); - - self::assertTrue($container->has('foo-bar')); - $service = $container->get('foo-bar'); - self::assertInstanceOf(TestAsset\Service::class, $service); - self::assertEquals( - [ - TestAsset\Delegator1Factory::class, - TestAsset\Delegator2Factory::class, - ], - $service->injected - ); - } } diff --git a/test/ContainerTest.php b/test/ContainerTest.php index 0cada63..a32eec2 100644 --- a/test/ContainerTest.php +++ b/test/ContainerTest.php @@ -1,7 +1,7 @@ callback = $callback; - } -} diff --git a/test/TestAsset/Delegator1Factory.php b/test/TestAsset/Delegator1Factory.php deleted file mode 100644 index 426a8c3..0000000 --- a/test/TestAsset/Delegator1Factory.php +++ /dev/null @@ -1,23 +0,0 @@ -inject(static::class); - - return $service; - } -} diff --git a/test/TestAsset/Delegator2Factory.php b/test/TestAsset/Delegator2Factory.php deleted file mode 100644 index ef70e9a..0000000 --- a/test/TestAsset/Delegator2Factory.php +++ /dev/null @@ -1,14 +0,0 @@ -injected[] = $name; - } -} From d3f0efd4da1e33dda322db6f42f845dfcb174d12 Mon Sep 17 00:00:00 2001 From: webimpress Date: Wed, 21 Mar 2018 13:18:05 +0000 Subject: [PATCH 04/13] Delegators do not operate on services --- src/Config.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/Config.php b/src/Config.php index 2830924..9260e27 100644 --- a/src/Config.php +++ b/src/Config.php @@ -1,7 +1,7 @@ $delegatorNames) { $factory = null; - if (isset($dependencies['services'][$service])) { - // Marshal from service - $instance = $dependencies['services'][$service]; - $factory = function () use ($instance) { - return $instance; - }; - unset($dependencies['services'][$service]); - } - if (isset($dependencies['factories'][$service])) { // Marshal from factory $serviceFactory = $dependencies['factories'][$service]; From a318363b019ce88c0fd6d312e493ac954ed3abbb Mon Sep 17 00:00:00 2001 From: webimpress Date: Wed, 21 Mar 2018 13:56:40 +0000 Subject: [PATCH 05/13] Aliased invokable delegators fix --- src/Config.php | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/Config.php b/src/Config.php index 9260e27..cf29f7f 100644 --- a/src/Config.php +++ b/src/Config.php @@ -14,6 +14,7 @@ use Aura\Di\ContainerConfigInterface; use Aura\Di\Exception\ServiceNotFound; +use function array_search; use function is_array; use function is_callable; @@ -163,16 +164,22 @@ private function marshalDelegators(Container $container, array $dependencies) : unset($dependencies['factories'][$service]); } - if (isset($dependencies['invokables'][$service])) { - // Marshal from invokable - $class = $dependencies['invokables'][$service]; - $factory = function () use ($class) { - return new $class(); - }; - unset($dependencies['invokables'][$service]); + if (isset($dependencies['invokables'])) { + while (false !== ($key = array_search($service, $dependencies['invokables'], true))) { + // Marshal from invokable + $class = $dependencies['invokables'][$key]; + $factory = function () use ($class) { + return new $class(); + }; + unset($dependencies['invokables'][$key]); + + if ($key !== $service) { + $dependencies['aliases'][$key] = $service; + } + } } - if (! is_callable($factory)) { + if (! $factory) { continue; } From 99532ddb840d8f627ac84451086f35d5e9e74e52 Mon Sep 17 00:00:00 2001 From: webimpress Date: Wed, 21 Mar 2018 17:17:34 +0000 Subject: [PATCH 06/13] Updated to work with latest test cases --- composer.lock | 4 ++-- src/Config.php | 29 ++++++++++++++++++++++++++++- src/DelegatorFactory.php | 18 +++++++++++++++++- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 77edfbd..7df10ca 100644 --- a/composer.lock +++ b/composer.lock @@ -1708,7 +1708,7 @@ "source": { "type": "git", "url": "https://github.com/weierophinney/zend-container-config-test", - "reference": "536e9f3a5d9c5ea86aec17ad172277d0afac6adb" + "reference": "eda19a31a53604ce0ca8a7c3e41f8c149d4de7b3" }, "require": { "php": "^7.1", @@ -1778,7 +1778,7 @@ "slack": "https://zendframework-slack.herokuapp.com", "forum": "https://discourse.zendframework.com/c/questions/expressive" }, - "time": "2018-03-20T20:47:31+00:00" + "time": "2018-03-21T17:06:59+00:00" } ], "aliases": [], diff --git a/src/Config.php b/src/Config.php index cf29f7f..a8b23b1 100644 --- a/src/Config.php +++ b/src/Config.php @@ -108,7 +108,17 @@ public function define(Container $container) )); } - return (new $factory())($container, $service); + $instance = new $factory(); + + if (! is_callable($instance)) { + throw new ServiceNotFound(sprintf( + 'Service %s cannot be initalized by non invokable factory %s', + $service, + $factory + )); + } + + return $instance($container, $service); }, $container, $service)); } } @@ -158,7 +168,24 @@ private function marshalDelegators(Container $container, array $dependencies) : // Marshal from factory $serviceFactory = $dependencies['factories'][$service]; $factory = function () use ($service, $serviceFactory, $container) { + if (! class_exists($serviceFactory)) { + throw new ServiceNotFound(sprintf( + 'Service %s cannot by initialized by factory %s; factory class does not exist', + $service, + $serviceFactory + )); + } + $factory = new $serviceFactory(); + + if (! is_callable($factory)) { + throw new ServiceNotFound(sprintf( + 'Service %s cannot by initalized by factory %s; factory is not callable', + $service, + $serviceFactory + )); + } + return $factory($container, $service); }; unset($dependencies['factories'][$service]); diff --git a/src/DelegatorFactory.php b/src/DelegatorFactory.php index a9c4bff..6da3792 100644 --- a/src/DelegatorFactory.php +++ b/src/DelegatorFactory.php @@ -12,6 +12,7 @@ use Aura\Di\Container; use function array_reduce; +use Aura\Di\Exception\ServiceNotFound; use function is_callable; /** @@ -68,7 +69,22 @@ public function build(Container $container, string $serviceName) return array_reduce( $this->delegators, function ($instance, $delegatorName) use ($serviceName, $container) { - $delegator = is_callable($delegatorName) ? $delegatorName : new $delegatorName(); + if (! class_exists($delegatorName)) { + throw new ServiceNotFound(sprintf( + 'Delegator class %s does not exist', + $delegatorName + )); + } + + $delegator = new $delegatorName(); + + if (! is_callable($delegator)) { + throw new ServiceNotFound(sprintf( + 'Delegator class %s is not callable', + $delegatorName + )); + } + return $delegator($container, $serviceName, function () use ($instance) { return $instance; }); From 540d7d68584c1c02cdca7b6e4c7e10576812ce1a Mon Sep 17 00:00:00 2001 From: webimpress Date: Thu, 22 Mar 2018 11:39:32 +0000 Subject: [PATCH 07/13] Updated to pass all container-config-test tests --- composer.json | 2 +- composer.lock | 12 +++++----- src/Config.php | 13 +++++++---- src/DelegatorFactory.php | 49 ++++++++++++++++++++-------------------- 4 files changed, 40 insertions(+), 36 deletions(-) diff --git a/composer.json b/composer.json index 6f6b0ab..47f8f31 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "require-dev": { "phpunit/phpunit": "^7.0.2", "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-container-config-test": "dev-feature/review-tests" + "zendframework/zend-container-config-test": "dev-improvements" }, "repositories": [ { diff --git a/composer.lock b/composer.lock index 7df10ca..2c3f9a4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "a0097eb90ab337fd96144b559b77bf7b", + "content-hash": "10fdbedf0f4103084a87cbcaaa09496b", "packages": [ { "name": "aura/di", @@ -1704,11 +1704,11 @@ }, { "name": "zendframework/zend-container-config-test", - "version": "dev-feature/review-tests", + "version": "dev-improvements", "source": { "type": "git", "url": "https://github.com/weierophinney/zend-container-config-test", - "reference": "eda19a31a53604ce0ca8a7c3e41f8c149d4de7b3" + "reference": "cd4554d22291eb2cf003a257f3088e0ff8e555c3" }, "require": { "php": "^7.1", @@ -1729,8 +1729,8 @@ }, "autoload": { "files": [ - "src/TestAsset/factory.php", - "src/TestAsset/factory-with-name.php" + "src/TestAsset/function-factory.php", + "src/TestAsset/function-factory-with-name.php" ], "psr-4": { "Zend\\ContainerConfigTest\\": "src/" @@ -1778,7 +1778,7 @@ "slack": "https://zendframework-slack.herokuapp.com", "forum": "https://discourse.zendframework.com/c/questions/expressive" }, - "time": "2018-03-21T17:06:59+00:00" + "time": "2018-03-22T10:57:39+00:00" } ], "aliases": [], diff --git a/src/Config.php b/src/Config.php index a8b23b1..eb1275c 100644 --- a/src/Config.php +++ b/src/Config.php @@ -15,8 +15,11 @@ use Aura\Di\Exception\ServiceNotFound; use function array_search; +use function class_exists; use function is_array; use function is_callable; +use function is_string; +use function sprintf; /** * Configuration for the Aura.Di container. @@ -100,7 +103,7 @@ public function define(Container $container) } $container->set($service, $container->lazy(function ($container, $service) use ($factory) { - if (! class_exists($factory)) { + if (is_string($factory) && ! class_exists($factory)) { throw new ServiceNotFound(sprintf( 'Service %s cannot be initialized by factory %s', $service, @@ -168,16 +171,18 @@ private function marshalDelegators(Container $container, array $dependencies) : // Marshal from factory $serviceFactory = $dependencies['factories'][$service]; $factory = function () use ($service, $serviceFactory, $container) { - if (! class_exists($serviceFactory)) { + if (is_callable($serviceFactory)) { + $factory = $serviceFactory; + } elseif (is_string($serviceFactory) && ! class_exists($serviceFactory)) { throw new ServiceNotFound(sprintf( 'Service %s cannot by initialized by factory %s; factory class does not exist', $service, $serviceFactory )); + } else { + $factory = new $serviceFactory(); } - $factory = new $serviceFactory(); - if (! is_callable($factory)) { throw new ServiceNotFound(sprintf( 'Service %s cannot by initalized by factory %s; factory is not callable', diff --git a/src/DelegatorFactory.php b/src/DelegatorFactory.php index 6da3792..3c70ded 100644 --- a/src/DelegatorFactory.php +++ b/src/DelegatorFactory.php @@ -10,9 +10,8 @@ namespace Zend\AuraDi\Config; use Aura\Di\Container; - -use function array_reduce; use Aura\Di\Exception\ServiceNotFound; +use function array_reduce; use function is_callable; /** @@ -65,31 +64,31 @@ public function __construct(array $delegators, callable $factory) */ public function build(Container $container, string $serviceName) { - $factory = $this->factory; - return array_reduce( - $this->delegators, - function ($instance, $delegatorName) use ($serviceName, $container) { - if (! class_exists($delegatorName)) { - throw new ServiceNotFound(sprintf( - 'Delegator class %s does not exist', - $delegatorName - )); - } + $callback = $this->factory; + + foreach ($this->delegators as $delegatorName) { + if (! class_exists($delegatorName)) { + throw new ServiceNotFound(sprintf( + 'Delegator class %s does not exist', + $delegatorName + )); + } + + $delegator = new $delegatorName(); - $delegator = new $delegatorName(); + if (! is_callable($delegator)) { + throw new ServiceNotFound(sprintf( + 'Delegator class %s is not callable', + $delegatorName + )); + } - if (! is_callable($delegator)) { - throw new ServiceNotFound(sprintf( - 'Delegator class %s is not callable', - $delegatorName - )); - } + $instance = $delegator($container, $serviceName, $callback); + $callback = function () use ($instance) { + return $instance; + }; + } - return $delegator($container, $serviceName, function () use ($instance) { - return $instance; - }); - }, - $factory() - ); + return $instance; } } From 266f462f33ec596a38c98884eb167795d56703f1 Mon Sep 17 00:00:00 2001 From: webimpress Date: Thu, 22 Mar 2018 13:28:28 +0000 Subject: [PATCH 08/13] Updated tests for non existing Invokbale class --- composer.lock | 4 ++-- src/Config.php | 58 +++++++++++++++++++++++++++++++------------------- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/composer.lock b/composer.lock index 2c3f9a4..31a8463 100644 --- a/composer.lock +++ b/composer.lock @@ -1708,7 +1708,7 @@ "source": { "type": "git", "url": "https://github.com/weierophinney/zend-container-config-test", - "reference": "cd4554d22291eb2cf003a257f3088e0ff8e555c3" + "reference": "5268853901e0313f35a30c7f31cff3d16883a88d" }, "require": { "php": "^7.1", @@ -1778,7 +1778,7 @@ "slack": "https://zendframework-slack.herokuapp.com", "forum": "https://discourse.zendframework.com/c/questions/expressive" }, - "time": "2018-03-22T10:57:39+00:00" + "time": "2018-03-22T13:16:03+00:00" } ], "aliases": [], diff --git a/src/Config.php b/src/Config.php index eb1275c..2c9f95f 100644 --- a/src/Config.php +++ b/src/Config.php @@ -13,6 +13,7 @@ use Aura\Di\Container; use Aura\Di\ContainerConfigInterface; use Aura\Di\Exception\ServiceNotFound; +use Psr\Container\ContainerInterface; use function array_search; use function class_exists; @@ -102,27 +103,30 @@ public function define(Container $container) continue; } - $container->set($service, $container->lazy(function ($container, $service) use ($factory) { - if (is_string($factory) && ! class_exists($factory)) { - throw new ServiceNotFound(sprintf( - 'Service %s cannot be initialized by factory %s', - $service, - $factory - )); - } - - $instance = new $factory(); - - if (! is_callable($instance)) { - throw new ServiceNotFound(sprintf( - 'Service %s cannot be initalized by non invokable factory %s', - $service, - $factory - )); - } - - return $instance($container, $service); - }, $container, $service)); + $container->set( + $service, + $container->lazy(function (ContainerInterface $container, string $service) use ($factory) { + if (is_string($factory) && ! class_exists($factory)) { + throw new ServiceNotFound(sprintf( + 'Service %s cannot be initialized by factory %s', + $service, + $factory + )); + } + + $instance = new $factory(); + + if (! is_callable($instance)) { + throw new ServiceNotFound(sprintf( + 'Service %s cannot be initalized by non invokable factory %s', + $service, + $factory + )); + } + + return $instance($container, $service); + }, $container, $service) + ); } } @@ -135,7 +139,13 @@ public function define(Container $container) $container->set($service, $container->lazyGet($class)); } - $container->set($class, $container->lazyNew($class)); + $container->set($class, $container->lazy(function () use ($class) { + if (! class_exists($class)) { + throw new ServiceNotFound(); + } + + return new $class(); + })); } } @@ -201,6 +211,10 @@ private function marshalDelegators(Container $container, array $dependencies) : // Marshal from invokable $class = $dependencies['invokables'][$key]; $factory = function () use ($class) { + if (! class_exists($class)) { + throw new ServiceNotFound(); + } + return new $class(); }; unset($dependencies['invokables'][$key]); From 26630f23fa1fb3711b69f62c18a99b4ddcede7d3 Mon Sep 17 00:00:00 2001 From: webimpress Date: Thu, 22 Mar 2018 13:35:29 +0000 Subject: [PATCH 09/13] Updated config for empty delegator list --- composer.lock | 4 ++-- src/DelegatorFactory.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.lock b/composer.lock index 31a8463..4b7456f 100644 --- a/composer.lock +++ b/composer.lock @@ -1708,7 +1708,7 @@ "source": { "type": "git", "url": "https://github.com/weierophinney/zend-container-config-test", - "reference": "5268853901e0313f35a30c7f31cff3d16883a88d" + "reference": "aea245490efc2347465a027cfe6e1afaefcf74ee" }, "require": { "php": "^7.1", @@ -1778,7 +1778,7 @@ "slack": "https://zendframework-slack.herokuapp.com", "forum": "https://discourse.zendframework.com/c/questions/expressive" }, - "time": "2018-03-22T13:16:03+00:00" + "time": "2018-03-22T13:33:42+00:00" } ], "aliases": [], diff --git a/src/DelegatorFactory.php b/src/DelegatorFactory.php index 3c70ded..68925db 100644 --- a/src/DelegatorFactory.php +++ b/src/DelegatorFactory.php @@ -89,6 +89,6 @@ public function build(Container $container, string $serviceName) }; } - return $instance; + return $instance ?? $callback(); } } From 01322a7e5d2890faf1c9305b4bff40975e3b24e2 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 10 Apr 2018 14:44:38 -0500 Subject: [PATCH 10/13] Updates to zend-container-config-test 0.1.0 Allows removing repository, pinning to a (semi-) stable version, and using the shipped abstract class. --- composer.json | 8 +----- composer.lock | 55 ++++++++++++------------------------------ test/ContainerTest.php | 6 ++--- 3 files changed, 18 insertions(+), 51 deletions(-) diff --git a/composer.json b/composer.json index 47f8f31..1a243b9 100644 --- a/composer.json +++ b/composer.json @@ -24,14 +24,8 @@ "require-dev": { "phpunit/phpunit": "^7.0.2", "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-container-config-test": "dev-improvements" + "zendframework/zend-container-config-test": "^0.1.0" }, - "repositories": [ - { - "type": "git", - "url": "https://github.com/weierophinney/zend-container-config-test" - } - ], "conflict": { "container-interop/container-interop": "<1.2.0" }, diff --git a/composer.lock b/composer.lock index 4b7456f..00b7c05 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "10fdbedf0f4103084a87cbcaaa09496b", + "content-hash": "a8e578a855b9f0c4b98ced5f2b82ac56", "packages": [ { "name": "aura/di", @@ -1704,11 +1704,17 @@ }, { "name": "zendframework/zend-container-config-test", - "version": "dev-improvements", + "version": "0.1.0", "source": { "type": "git", - "url": "https://github.com/weierophinney/zend-container-config-test", - "reference": "aea245490efc2347465a027cfe6e1afaefcf74ee" + "url": "https://github.com/zendframework/zend-container-config-test.git", + "reference": "eb351af9606a9b113bcb381eef9f7d19038eb1d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-container-config-test/zipball/eb351af9606a9b113bcb381eef9f7d19038eb1d1", + "reference": "eb351af9606a9b113bcb381eef9f7d19038eb1d1", + "shasum": "" }, "require": { "php": "^7.1", @@ -1736,56 +1742,25 @@ "Zend\\ContainerConfigTest\\": "src/" } }, - "autoload-dev": { - "psr-4": { - "ZendTest\\ContainerConfigTest\\": "test/" - } - }, - "scripts": { - "check": [ - "@cs-check", - "@test" - ], - "cs-check": [ - "phpcs" - ], - "cs-fix": [ - "phpcbf" - ], - "test": [ - "phpunit --colors=always" - ], - "test-coverage": [ - "phpunit --colors=always --coverage-clover clover.xml" - ] - }, + "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "description": "Expressive PSR-11 container configuration tests", "keywords": [ + "PSR-11", + "ZendFramework", "container", "expressive", - "psr-11", "test", - "zendframework", "zf" ], - "support": { - "issues": "https://github.com/zendframework/zend-container-config-test/issues", - "source": "https://github.com/zendframework/zend-container-config-test", - "rss": "https://github.com/zendframework/zend-container-config-test/releases.atom", - "slack": "https://zendframework-slack.herokuapp.com", - "forum": "https://discourse.zendframework.com/c/questions/expressive" - }, - "time": "2018-03-22T13:33:42+00:00" + "time": "2018-04-10T19:28:48+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "zendframework/zend-container-config-test": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/test/ContainerTest.php b/test/ContainerTest.php index a32eec2..200178c 100644 --- a/test/ContainerTest.php +++ b/test/ContainerTest.php @@ -12,12 +12,10 @@ use Psr\Container\ContainerInterface; use Zend\AuraDi\Config\Config; use Zend\AuraDi\Config\ContainerFactory; -use Zend\ContainerConfigTest\AllTestTrait; +use Zend\ContainerConfigTest\AbstractExpressiveContainerConfigTest; -class ContainerTest extends \Zend\ContainerConfigTest\ContainerTest +class ContainerTest extends AbstractExpressiveContainerConfigTest { - use AllTestTrait; - protected function createContainer(array $config) : ContainerInterface { $factory = new ContainerFactory(); From 8df4fe02964b567a7c32b18b3f4f22df1fc91935 Mon Sep 17 00:00:00 2001 From: webimpress Date: Wed, 11 Apr 2018 15:03:22 +0100 Subject: [PATCH 11/13] Updated configuration to conform all common tests --- src/Config.php | 22 +++++++++++++--------- src/DelegatorFactory.php | 9 ++++++--- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/Config.php b/src/Config.php index 2c9f95f..ca6b96b 100644 --- a/src/Config.php +++ b/src/Config.php @@ -21,6 +21,7 @@ use function is_callable; use function is_string; use function sprintf; +use function var_export; /** * Configuration for the Aura.Di container. @@ -40,9 +41,6 @@ class Config implements ContainerConfigInterface */ private $config; - /** - * @param array $config - */ public function __construct(array $config) { $this->config = $config; @@ -106,11 +104,11 @@ public function define(Container $container) $container->set( $service, $container->lazy(function (ContainerInterface $container, string $service) use ($factory) { - if (is_string($factory) && ! class_exists($factory)) { + if (! is_string($factory) || ! class_exists($factory)) { throw new ServiceNotFound(sprintf( 'Service %s cannot be initialized by factory %s', $service, - $factory + is_string($factory) ? $factory : var_export($factory, true) )); } @@ -140,8 +138,11 @@ public function define(Container $container) } $container->set($class, $container->lazy(function () use ($class) { - if (! class_exists($class)) { - throw new ServiceNotFound(); + if (! is_string($class) || ! class_exists($class)) { + throw new ServiceNotFound(sprintf( + 'Service %s cannot be created', + is_string($class) ? $class : var_export($class, true) + )); } return new $class(); @@ -211,8 +212,11 @@ private function marshalDelegators(Container $container, array $dependencies) : // Marshal from invokable $class = $dependencies['invokables'][$key]; $factory = function () use ($class) { - if (! class_exists($class)) { - throw new ServiceNotFound(); + if (! is_string($class) || ! class_exists($class)) { + throw new ServiceNotFound(sprintf( + 'Service %s cannot be created', + is_string($class) ? $class : var_export($class, true) + )); } return new $class(); diff --git a/src/DelegatorFactory.php b/src/DelegatorFactory.php index 68925db..a2343a6 100644 --- a/src/DelegatorFactory.php +++ b/src/DelegatorFactory.php @@ -1,7 +1,7 @@ delegators = $delegators; - $this->factory = $factory; + $this->factory = $factory; } /** * Build the instance, invoking each delegator with the result of the previous. * * @return mixed + * @throws ServiceNotFound */ public function build(Container $container, string $serviceName) { From 67d27eeab8c562b348d7e5f579fa6b16a960d33a Mon Sep 17 00:00:00 2001 From: webimpress Date: Wed, 11 Apr 2018 15:19:47 +0100 Subject: [PATCH 12/13] Updated dependencies - pin to zend-container-config-test ^0.2 || ^1.0 --- composer.json | 4 ++-- composer.lock | 52 +++++++++++++++++++++++++-------------------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/composer.json b/composer.json index 1a243b9..8558a79 100644 --- a/composer.json +++ b/composer.json @@ -22,9 +22,9 @@ "aura/di": "^3.4" }, "require-dev": { - "phpunit/phpunit": "^7.0.2", + "phpunit/phpunit": "^7.1.2", "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-container-config-test": "^0.1.0" + "zendframework/zend-container-config-test": "^0.2 || ^1.0" }, "conflict": { "container-interop/container-interop": "<1.2.0" diff --git a/composer.lock b/composer.lock index 00b7c05..941722d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "a8e578a855b9f0c4b98ced5f2b82ac56", + "content-hash": "b400b21f3bacb1e84cc7f0f9e9633977", "packages": [ { "name": "aura/di", @@ -559,16 +559,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "6.0.1", + "version": "6.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f8ca4b604baf23dab89d87773c28cc07405189ba" + "reference": "774a82c0c5da4c1c7701790c262035d235ab7856" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f8ca4b604baf23dab89d87773c28cc07405189ba", - "reference": "f8ca4b604baf23dab89d87773c28cc07405189ba", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/774a82c0c5da4c1c7701790c262035d235ab7856", + "reference": "774a82c0c5da4c1c7701790c262035d235ab7856", "shasum": "" }, "require": { @@ -579,7 +579,7 @@ "phpunit/php-text-template": "^1.2.1", "phpunit/php-token-stream": "^3.0", "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.0", + "sebastian/environment": "^3.1", "sebastian/version": "^2.0.1", "theseer/tokenizer": "^1.1" }, @@ -618,7 +618,7 @@ "testing", "xunit" ], - "time": "2018-02-02T07:01:41+00:00" + "time": "2018-04-06T15:39:20+00:00" }, { "name": "phpunit/php-file-iterator", @@ -808,16 +808,16 @@ }, { "name": "phpunit/phpunit", - "version": "7.0.2", + "version": "7.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "e2f8aa21bc54b6ba218bdd4f9e0dac1e9bc3b4e9" + "reference": "6a17c170fb92845896e1b3b00fcb462cd4b3c017" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e2f8aa21bc54b6ba218bdd4f9e0dac1e9bc3b4e9", - "reference": "e2f8aa21bc54b6ba218bdd4f9e0dac1e9bc3b4e9", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6a17c170fb92845896e1b3b00fcb462cd4b3c017", + "reference": "6a17c170fb92845896e1b3b00fcb462cd4b3c017", "shasum": "" }, "require": { @@ -831,11 +831,11 @@ "phar-io/version": "^1.0", "php": "^7.1", "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^6.0", + "phpunit/php-code-coverage": "^6.0.1", "phpunit/php-file-iterator": "^1.4.3", "phpunit/php-text-template": "^1.2.1", "phpunit/php-timer": "^2.0", - "phpunit/phpunit-mock-objects": "^6.0", + "phpunit/phpunit-mock-objects": "^6.1", "sebastian/comparator": "^2.1", "sebastian/diff": "^3.0", "sebastian/environment": "^3.1", @@ -858,7 +858,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "7.0-dev" + "dev-master": "7.1-dev" } }, "autoload": { @@ -884,20 +884,20 @@ "testing", "xunit" ], - "time": "2018-02-26T07:03:12+00:00" + "time": "2018-04-10T11:40:22+00:00" }, { "name": "phpunit/phpunit-mock-objects", - "version": "6.0.1", + "version": "6.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "e3249dedc2d99259ccae6affbc2684eac37c2e53" + "reference": "70c740bde8fd9ea9ea295be1cd875dd7b267e157" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/e3249dedc2d99259ccae6affbc2684eac37c2e53", - "reference": "e3249dedc2d99259ccae6affbc2684eac37c2e53", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/70c740bde8fd9ea9ea295be1cd875dd7b267e157", + "reference": "70c740bde8fd9ea9ea295be1cd875dd7b267e157", "shasum": "" }, "require": { @@ -915,7 +915,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "6.0.x-dev" + "dev-master": "6.1-dev" } }, "autoload": { @@ -940,7 +940,7 @@ "mock", "xunit" ], - "time": "2018-02-15T05:27:38+00:00" + "time": "2018-04-11T04:50:36+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -1704,16 +1704,16 @@ }, { "name": "zendframework/zend-container-config-test", - "version": "0.1.0", + "version": "0.2.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-container-config-test.git", - "reference": "eb351af9606a9b113bcb381eef9f7d19038eb1d1" + "reference": "64a73e2cfc12cb07103e8936dfb25c136ba0496f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-container-config-test/zipball/eb351af9606a9b113bcb381eef9f7d19038eb1d1", - "reference": "eb351af9606a9b113bcb381eef9f7d19038eb1d1", + "url": "https://api.github.com/repos/zendframework/zend-container-config-test/zipball/64a73e2cfc12cb07103e8936dfb25c136ba0496f", + "reference": "64a73e2cfc12cb07103e8936dfb25c136ba0496f", "shasum": "" }, "require": { @@ -1755,7 +1755,7 @@ "test", "zf" ], - "time": "2018-04-10T19:28:48+00:00" + "time": "2018-04-11T14:09:33+00:00" } ], "aliases": [], From c073e15b7188f0da4478430918a4ccc13576b82d Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Wed, 11 Apr 2018 12:42:35 -0500 Subject: [PATCH 13/13] Adds CHANGELOG entries for #10 --- CHANGELOG.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60e5e57..927d1af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,14 @@ Versions prior to 0.2.0 were released as the package "webimpress/zend-auradi-con ### Fixed -- Nothing. +- [#10](https://github.com/zendframework/zend-auradi-config/pull/10) fixes + support for invokables configuration. Invokables will be instantiated on + first request. If the key name does not match the class name, an alias will be + created mapping the key to the target class as well. + +- [#10](https://github.com/zendframework/zend-auradi-config/pull/10) fixes + support for delegators, ensuring they operate for both invokables and + factory-based services, and always on the canonical name. ## 1.0.0 - 2018-03-15