From b08f3cddc9f7537072ba6ef5b86b1a53cc493f58 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 19 Jun 2023 17:55:45 +0200 Subject: [PATCH] [FrameworkBundle] Fix setting decorated services during tests --- .../TestServiceContainerRealRefPass.php | 3 + .../TestServiceContainer/PrivateService.php | 1 + .../Tests/Functional/KernelTestCaseTest.php | 61 ------------------- .../Functional/TestServiceContainerTest.php | 28 +++++++++ .../app/TestServiceContainer/services.yml | 10 +++ .../Bundle/FrameworkBundle/composer.json | 2 +- .../Compiler/DecoratorServicePass.php | 4 +- .../Compiler/DecoratorServicePassTest.php | 14 ++--- .../Fixtures/config/anonymous.expected.yml | 2 +- .../Tests/Fixtures/config/child.expected.yml | 2 +- 10 files changed, 55 insertions(+), 72 deletions(-) delete mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Functional/KernelTestCaseTest.php diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TestServiceContainerRealRefPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TestServiceContainerRealRefPass.php index 09f272daa940e..aed3b13404bd5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TestServiceContainerRealRefPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TestServiceContainerRealRefPass.php @@ -41,6 +41,9 @@ public function process(ContainerBuilder $container) if ($id !== $target) { $renamedIds[$id] = $target; } + if ($inner = $definitions[$target]->getTag('container.decorator')[0]['inner'] ?? null) { + $renamedIds[$id] = $inner; + } } else { unset($privateServices[$id]); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestServiceContainer/PrivateService.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestServiceContainer/PrivateService.php index 6a244cb40ce54..51168b7ea6c24 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestServiceContainer/PrivateService.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestServiceContainer/PrivateService.php @@ -13,4 +13,5 @@ class PrivateService { + public $inner; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/KernelTestCaseTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/KernelTestCaseTest.php deleted file mode 100644 index aa12467829ed1..0000000000000 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/KernelTestCaseTest.php +++ /dev/null @@ -1,61 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\FrameworkBundle\Tests\Functional; - -use Symfony\Bundle\FrameworkBundle\Test\TestContainer; -use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\NonPublicService; -use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\PrivateService; -use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\PublicService; -use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\UnusedPrivateService; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; - -class KernelTestCaseTest extends AbstractWebTestCase -{ - public function testThatPrivateServicesAreUnavailableIfTestConfigIsDisabled() - { - static::bootKernel(['test_case' => 'TestServiceContainer', 'root_config' => 'test_disabled.yml', 'environment' => 'test_disabled']); - - $this->expectException(\LogicException::class); - static::getContainer(); - } - - public function testThatPrivateServicesAreAvailableIfTestConfigIsEnabled() - { - static::bootKernel(['test_case' => 'TestServiceContainer']); - - $container = static::getContainer(); - $this->assertInstanceOf(ContainerInterface::class, $container); - $this->assertInstanceOf(TestContainer::class, $container); - $this->assertTrue($container->has(PublicService::class)); - $this->assertTrue($container->has(NonPublicService::class)); - $this->assertTrue($container->has(PrivateService::class)); - $this->assertTrue($container->has('private_service')); - $this->assertFalse($container->has(UnusedPrivateService::class)); - } - - public function testThatPrivateServicesCanBeSetIfTestConfigIsEnabled() - { - static::bootKernel(['test_case' => 'TestServiceContainer']); - - $container = static::getContainer(); - - $service = new \stdClass(); - - $container->set('private_service', $service); - $this->assertSame($service, $container->get('private_service')); - - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('The "private_service" service is already initialized, you cannot replace it.'); - $container->set('private_service', new \stdClass()); - } -} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/TestServiceContainerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/TestServiceContainerTest.php index 76a373c0c05a9..fe7093081509f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/TestServiceContainerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/TestServiceContainerTest.php @@ -16,6 +16,7 @@ use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\PrivateService; use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\PublicService; use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\UnusedPrivateService; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; class TestServiceContainerTest extends AbstractWebTestCase { @@ -40,6 +41,33 @@ public function testThatPrivateServicesAreAvailableIfTestConfigIsEnabled() $this->assertFalse(static::getContainer()->has(UnusedPrivateService::class)); } + public function testThatPrivateServicesCanBeSetIfTestConfigIsEnabled() + { + static::bootKernel(['test_case' => 'TestServiceContainer']); + + $container = static::getContainer(); + + $service = new \stdClass(); + + $container->set('private_service', $service); + $this->assertSame($service, $container->get('private_service')); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('The "private_service" service is already initialized, you cannot replace it.'); + $container->set('private_service', new \stdClass()); + } + + public function testSetDecoratedService() + { + static::bootKernel(['test_case' => 'TestServiceContainer']); + + $container = static::getContainer(); + + $service = new PrivateService(); + $container->set('decorated', $service); + $this->assertSame($service, $container->get('decorated')->inner); + } + /** * @doesNotPerformAssertions */ diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/TestServiceContainer/services.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/TestServiceContainer/services.yml index 523cca58d0b63..46cb7be6a8f6f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/TestServiceContainer/services.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/TestServiceContainer/services.yml @@ -8,8 +8,18 @@ services: private_service: '@Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\PrivateService' + decorated: + class: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\PrivateService + Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\PublicService: public: true arguments: - '@Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\NonPublicService' - '@Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\PrivateService' + - '@decorated' + + decorator: + class: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestServiceContainer\PrivateService + decorates: decorated + properties: + inner: '@.inner' diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 9f594f254f035..0fcc602c3975d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -21,7 +21,7 @@ "ext-xml": "*", "symfony/cache": "^5.4|^6.0", "symfony/config": "^6.1", - "symfony/dependency-injection": "^6.3", + "symfony/dependency-injection": "^6.3.1", "symfony/deprecation-contracts": "^2.5|^3", "symfony/error-handler": "^6.1", "symfony/event-dispatcher": "^5.4|^6.0", diff --git a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php index c38bfa7744502..d05878fe85611 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php @@ -42,6 +42,7 @@ public function process(ContainerBuilder $container) $definitions->insert([$id, $definition], [$decorated[2], --$order]); } $decoratingDefinitions = []; + $decoratedIds = []; $tagsToKeep = $container->hasParameter('container.behavior_describing_tags') ? $container->getParameter('container.behavior_describing_tags') @@ -58,6 +59,7 @@ public function process(ContainerBuilder $container) $renamedId = $id.'.inner'; } + $decoratedIds[$inner] ??= $renamedId; $this->currentId = $renamedId; $this->processValue($definition); @@ -114,7 +116,7 @@ public function process(ContainerBuilder $container) } foreach ($decoratingDefinitions as $inner => $definition) { - $definition->addTag('container.decorator', ['id' => $inner]); + $definition->addTag('container.decorator', ['id' => $inner, 'inner' => $decoratedIds[$inner]]); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php index 8c8a158a76327..48ed32df6d63d 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php @@ -161,7 +161,7 @@ public function testProcessWithInvalidDecorated() public function testProcessNoInnerAliasWithInvalidDecorated() { $container = new ContainerBuilder(); - $decoratorDefinition = $container + $container ->register('decorator') ->setDecoratedService('unknown_decorated', null, 0, ContainerInterface::NULL_ON_INVALID_REFERENCE) ; @@ -173,7 +173,7 @@ public function testProcessNoInnerAliasWithInvalidDecorated() public function testProcessWithInvalidDecoratedAndWrongBehavior() { $container = new ContainerBuilder(); - $decoratorDefinition = $container + $container ->register('decorator') ->setDecoratedService('unknown_decorated', null, 0, 12) ; @@ -198,7 +198,7 @@ public function testProcessMovesTagsFromDecoratedDefinitionToDecoratingDefinitio $this->process($container); $this->assertEmpty($container->getDefinition('baz.inner')->getTags()); - $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar'], 'container.decorator' => [['id' => 'foo']]], $container->getDefinition('baz')->getTags()); + $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar'], 'container.decorator' => [['id' => 'foo', 'inner' => 'baz.inner']]], $container->getDefinition('baz')->getTags()); } public function testProcessMovesTagsFromDecoratedDefinitionToDecoratingDefinitionMultipleTimes() @@ -221,7 +221,7 @@ public function testProcessMovesTagsFromDecoratedDefinitionToDecoratingDefinitio $this->process($container); $this->assertEmpty($container->getDefinition('deco1')->getTags()); - $this->assertEquals(['bar' => ['attr' => 'baz'], 'container.decorator' => [['id' => 'foo']]], $container->getDefinition('deco2')->getTags()); + $this->assertEquals(['bar' => ['attr' => 'baz'], 'container.decorator' => [['id' => 'foo', 'inner' => 'deco1.inner']]], $container->getDefinition('deco2')->getTags()); } public function testProcessLeavesServiceLocatorTagOnOriginalDefinition() @@ -240,7 +240,7 @@ public function testProcessLeavesServiceLocatorTagOnOriginalDefinition() $this->process($container); $this->assertEquals(['container.service_locator' => [0 => []]], $container->getDefinition('baz.inner')->getTags()); - $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar'], 'container.decorator' => [['id' => 'foo']]], $container->getDefinition('baz')->getTags()); + $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar'], 'container.decorator' => [['id' => 'foo', 'inner' => 'baz.inner']]], $container->getDefinition('baz')->getTags()); } public function testProcessLeavesServiceSubscriberTagOnOriginalDefinition() @@ -259,7 +259,7 @@ public function testProcessLeavesServiceSubscriberTagOnOriginalDefinition() $this->process($container); $this->assertEquals(['container.service_subscriber' => [], 'container.service_subscriber.locator' => []], $container->getDefinition('baz.inner')->getTags()); - $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar'], 'container.decorator' => [['id' => 'foo']]], $container->getDefinition('baz')->getTags()); + $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar'], 'container.decorator' => [['id' => 'foo', 'inner' => 'baz.inner']]], $container->getDefinition('baz')->getTags()); } public function testProcessLeavesProxyTagOnOriginalDefinition() @@ -278,7 +278,7 @@ public function testProcessLeavesProxyTagOnOriginalDefinition() $this->process($container); $this->assertEquals(['proxy' => 'foo'], $container->getDefinition('baz.inner')->getTags()); - $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar'], 'container.decorator' => [['id' => 'foo']]], $container->getDefinition('baz')->getTags()); + $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar'], 'container.decorator' => [['id' => 'foo', 'inner' => 'baz.inner']]], $container->getDefinition('baz')->getTags()); } public function testCannotDecorateSyntheticService() diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/anonymous.expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/anonymous.expected.yml index 9b1213fbcab8e..7f36de38b0015 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/anonymous.expected.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/anonymous.expected.yml @@ -16,5 +16,5 @@ services: class: Symfony\Component\DependencyInjection\Tests\Fixtures\StdClassDecorator public: true tags: - - container.decorator: { id: decorated } + - container.decorator: { id: decorated, inner: decorator42 } arguments: [!service { class: stdClass }] diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/child.expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/child.expected.yml index a4e4eb995c4be..44dbbd571b788 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/child.expected.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/child.expected.yml @@ -8,7 +8,7 @@ services: class: Class2 public: true tags: - - container.decorator: { id: bar } + - container.decorator: { id: bar, inner: b } file: file.php lazy: true arguments: [!service { class: Class1 }] pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy