From 40ad332e103314f5bafe0661435254dae15ba9aa Mon Sep 17 00:00:00 2001 From: Oleksii Bulba Date: Mon, 9 Jan 2023 16:02:17 +0400 Subject: [PATCH 1/3] Fix: Decorators with the same priority - Fixed the issue when only one decorator was applied when several decorators had the same priority; Signed-off-by: Oleksii Bulba --- .gitignore | 1 + src/Container.php | 17 +++++++---------- tests/unit/ContainerTest.php | 31 +++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 3d7e132..a8fea06 100755 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ vendor/ composer.lock .phpunit.result.cache +test-coverage-report/ diff --git a/src/Container.php b/src/Container.php index 6133f6c..36180d2 100755 --- a/src/Container.php +++ b/src/Container.php @@ -60,11 +60,7 @@ public function register(string $id, \Closure $service): void */ public function decorate(string $id, \Closure $service, int $priority = 0): void { - if(!array_key_exists($id, $this->decorators)) { - $this->decorators[$id] = []; - } - - $this->decorators[$id][$priority] = $service; + $this->decorators[$id][$priority][] = $service; } /** @@ -100,12 +96,13 @@ protected function initializeService(string $serviceId): void return; } - $decorators = $this->decorators[$serviceId]; - - ksort($decorators); + $decoratorsByPriority = $this->decorators[$serviceId]; + ksort($decoratorsByPriority); - foreach ($decorators as $decorator) { - $this->services[$serviceId] = $decorator($this->services[$serviceId], $this); + foreach ($decoratorsByPriority as $decorators) { + foreach ($decorators as $decorator) { + $this->services[$serviceId] = $decorator($this->services[$serviceId], $this); + } } } } diff --git a/tests/unit/ContainerTest.php b/tests/unit/ContainerTest.php index dacca27..d5e8510 100755 --- a/tests/unit/ContainerTest.php +++ b/tests/unit/ContainerTest.php @@ -73,6 +73,37 @@ public function testDecorateService(): void $this->assertInstanceOf(NamedInterface::class, $result); $this->assertEquals('ABCD', $result->getName()); } + + public function testDecoratorsWithSamePriority(): void + { + $container = new Container(); + + $container->register('test', function () { + return new NamedService('E'); + }); + + $container->decorate('test', function (NamedInterface $decorated) { + return new NamedServiceDecorator($decorated, 'D'); + }); + + $container->decorate('test', function (NamedInterface $decorated) { + return new NamedServiceDecorator($decorated, 'B'); + }, 10); + + $container->decorate('test', function (NamedInterface $decorated) { + return new NamedServiceDecorator($decorated, 'C'); + }); + + $container->decorate('test', function (NamedInterface $decorated) { + return new NamedServiceDecorator($decorated, 'A'); + }, 10); + + /** @var NamedInterface $result */ + $result = $container->get('test'); + $this->assertInstanceOf(NamedServiceDecorator::class, $result); + $this->assertInstanceOf(NamedInterface::class, $result); + $this->assertEquals('ABCDE', $result->getName()); + } } interface NamedInterface From 69be1a5f4d2b35c9268ba679e5034791a502e2f4 Mon Sep 17 00:00:00 2001 From: Oleksii Bulba Date: Mon, 9 Jan 2023 16:05:17 +0400 Subject: [PATCH 2/3] Fix: Decorators with the same priority - Added unset service decorators when the service is initialized; Signed-off-by: Oleksii Bulba --- src/Container.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Container.php b/src/Container.php index 36180d2..33328a1 100755 --- a/src/Container.php +++ b/src/Container.php @@ -104,5 +104,7 @@ protected function initializeService(string $serviceId): void $this->services[$serviceId] = $decorator($this->services[$serviceId], $this); } } + + unset($this->decorators[$serviceId]); } } From 953e82c828e82c551004c7c8ca29073ca0f9baf8 Mon Sep 17 00:00:00 2001 From: Oleksii Bulba Date: Mon, 9 Jan 2023 16:25:17 +0400 Subject: [PATCH 3/3] Fix: Decorators with the same priority - Fix unit tests; Signed-off-by: Oleksii Bulba --- src/Container.php | 2 +- tests/unit/ContainerTest.php | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Container.php b/src/Container.php index 33328a1..9d0ecb4 100755 --- a/src/Container.php +++ b/src/Container.php @@ -97,7 +97,7 @@ protected function initializeService(string $serviceId): void } $decoratorsByPriority = $this->decorators[$serviceId]; - ksort($decoratorsByPriority); + krsort($decoratorsByPriority); foreach ($decoratorsByPriority as $decorators) { foreach ($decorators as $decorator) { diff --git a/tests/unit/ContainerTest.php b/tests/unit/ContainerTest.php index d5e8510..a1752d1 100755 --- a/tests/unit/ContainerTest.php +++ b/tests/unit/ContainerTest.php @@ -52,19 +52,19 @@ public function testDecorateService(): void $container = new Container(); $container->register('test', function () { - return new NamedService('D'); + return new NamedService('A'); }); $container->decorate('test', function (NamedInterface $decorated) { - return new NamedServiceDecorator($decorated, 'C'); + return new NamedServiceDecorator($decorated, 'D'); }); $container->decorate('test', function (NamedInterface $decorated) { - return new NamedServiceDecorator($decorated, 'A'); + return new NamedServiceDecorator($decorated, 'B'); }, 10); $container->decorate('test', function (NamedInterface $decorated) { - return new NamedServiceDecorator($decorated, 'B'); + return new NamedServiceDecorator($decorated, 'C'); }, 5); /** @var NamedInterface $result */ @@ -79,11 +79,7 @@ public function testDecoratorsWithSamePriority(): void $container = new Container(); $container->register('test', function () { - return new NamedService('E'); - }); - - $container->decorate('test', function (NamedInterface $decorated) { - return new NamedServiceDecorator($decorated, 'D'); + return new NamedService('A'); }); $container->decorate('test', function (NamedInterface $decorated) { @@ -91,11 +87,15 @@ public function testDecoratorsWithSamePriority(): void }, 10); $container->decorate('test', function (NamedInterface $decorated) { - return new NamedServiceDecorator($decorated, 'C'); + return new NamedServiceDecorator($decorated, 'D'); }); $container->decorate('test', function (NamedInterface $decorated) { - return new NamedServiceDecorator($decorated, 'A'); + return new NamedServiceDecorator($decorated, 'E'); + }); + + $container->decorate('test', function (NamedInterface $decorated) { + return new NamedServiceDecorator($decorated, 'C'); }, 10); /** @var NamedInterface $result */ @@ -133,6 +133,6 @@ public function __construct( public function getName(): string { - return $this->name.$this->decorated->getName(); + return $this->decorated->getName().$this->name; } }