diff --git a/src/LiveComponent/composer.json b/src/LiveComponent/composer.json index 4623e619e39..0bdfd2169c2 100644 --- a/src/LiveComponent/composer.json +++ b/src/LiveComponent/composer.json @@ -41,7 +41,7 @@ "doctrine/doctrine-bundle": "^2.0", "doctrine/orm": "^2.7", "zenstruck/foundry": "^1.10", - "zenstruck/browser": "^0.5.0" + "zenstruck/browser": "^0.9.1" }, "extra": { "branch-alias": { diff --git a/src/LiveComponent/tests/ContainerBC.php b/src/LiveComponent/tests/ContainerBC.php new file mode 100644 index 00000000000..bdbf1e0f20b --- /dev/null +++ b/src/LiveComponent/tests/ContainerBC.php @@ -0,0 +1,26 @@ + + */ +trait ContainerBC +{ + protected static function getContainer(): ContainerInterface + { + if (!\method_exists(parent::class, 'getContainer')) { + if (!static::$booted) { + static::bootKernel(); + } + + return self::$container; + } + + return parent::getContainer(); + } +} diff --git a/src/LiveComponent/tests/Functional/EventListener/LiveComponentSubscriberTest.php b/src/LiveComponent/tests/Functional/EventListener/LiveComponentSubscriberTest.php index 1c652df12ad..b401780624d 100644 --- a/src/LiveComponent/tests/Functional/EventListener/LiveComponentSubscriberTest.php +++ b/src/LiveComponent/tests/Functional/EventListener/LiveComponentSubscriberTest.php @@ -14,6 +14,7 @@ use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\UX\LiveComponent\LiveComponentHydrator; +use Symfony\UX\LiveComponent\Tests\ContainerBC; use Symfony\UX\LiveComponent\Tests\Fixture\Component\Component1; use Symfony\UX\LiveComponent\Tests\Fixture\Component\Component2; use Symfony\UX\LiveComponent\Tests\Fixture\Entity\Entity1; @@ -29,19 +30,18 @@ */ final class LiveComponentSubscriberTest extends KernelTestCase { + use ContainerBC; use Factories; use HasBrowser; use ResetDatabase; public function testCanRenderComponentAsHtmlOrJson(): void { - self::bootKernel(); - /** @var LiveComponentHydrator $hydrator */ - $hydrator = self::$container->get('ux.live_component.component_hydrator'); + $hydrator = self::getContainer()->get('ux.live_component.component_hydrator'); /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); /** @var Component1 $component */ $component = $factory->create('component1', [ @@ -80,13 +80,11 @@ public function testCanRenderComponentAsHtmlOrJson(): void public function testCanExecuteComponentAction(): void { - self::bootKernel(); - /** @var LiveComponentHydrator $hydrator */ - $hydrator = self::$container->get('ux.live_component.component_hydrator'); + $hydrator = self::getContainer()->get('ux.live_component.component_hydrator'); /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); /** @var Component2 $component */ $component = $factory->create('component2'); @@ -183,13 +181,11 @@ public function testInvalidCsrfTokenForComponentActionFails(): void public function testBeforeReRenderHookOnlyExecutedDuringAjax(): void { - self::bootKernel(); - /** @var LiveComponentHydrator $hydrator */ - $hydrator = self::$container->get('ux.live_component.component_hydrator'); + $hydrator = self::getContainer()->get('ux.live_component.component_hydrator'); /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); /** @var Component2 $component */ $component = $factory->create('component2'); @@ -208,13 +204,11 @@ public function testBeforeReRenderHookOnlyExecutedDuringAjax(): void public function testCanRedirectFromComponentAction(): void { - self::bootKernel(); - /** @var LiveComponentHydrator $hydrator */ - $hydrator = self::$container->get('ux.live_component.component_hydrator'); + $hydrator = self::getContainer()->get('ux.live_component.component_hydrator'); /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); /** @var Component2 $component */ $component = $factory->create('component2'); diff --git a/src/LiveComponent/tests/Integration/LiveComponentHydratorTest.php b/src/LiveComponent/tests/Integration/LiveComponentHydratorTest.php index c6215b3606a..59e5aac7e64 100644 --- a/src/LiveComponent/tests/Integration/LiveComponentHydratorTest.php +++ b/src/LiveComponent/tests/Integration/LiveComponentHydratorTest.php @@ -13,6 +13,7 @@ use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\UX\LiveComponent\LiveComponentHydrator; +use Symfony\UX\LiveComponent\Tests\ContainerBC; use Symfony\UX\LiveComponent\Tests\Fixture\Component\Component1; use Symfony\UX\LiveComponent\Tests\Fixture\Component\Component2; use Symfony\UX\LiveComponent\Tests\Fixture\Component\Component3; @@ -27,18 +28,17 @@ */ final class LiveComponentHydratorTest extends KernelTestCase { + use ContainerBC; use Factories; use ResetDatabase; public function testCanDehydrateAndHydrateLiveComponent(): void { - self::bootKernel(); - /** @var LiveComponentHydrator $hydrator */ - $hydrator = self::$container->get('ux.live_component.component_hydrator'); + $hydrator = self::getContainer()->get('ux.live_component.component_hydrator'); /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); /** @var Component1 $component */ $component = $factory->create('component1', [ @@ -73,13 +73,11 @@ public function testCanDehydrateAndHydrateLiveComponent(): void public function testCanModifyWritableProps(): void { - self::bootKernel(); - /** @var LiveComponentHydrator $hydrator */ - $hydrator = self::$container->get('ux.live_component.component_hydrator'); + $hydrator = self::getContainer()->get('ux.live_component.component_hydrator'); /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); /** @var Component1 $component */ $component = $factory->create('component1', [ @@ -100,13 +98,11 @@ public function testCanModifyWritableProps(): void public function testCannotModifyReadonlyProps(): void { - self::bootKernel(); - /** @var LiveComponentHydrator $hydrator */ - $hydrator = self::$container->get('ux.live_component.component_hydrator'); + $hydrator = self::getContainer()->get('ux.live_component.component_hydrator'); /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); /** @var Component1 $component */ $component = $factory->create('component1', [ @@ -126,13 +122,11 @@ public function testCannotModifyReadonlyProps(): void public function testHydrationFailsIfChecksumMissing(): void { - self::bootKernel(); - /** @var LiveComponentHydrator $hydrator */ - $hydrator = self::$container->get('ux.live_component.component_hydrator'); + $hydrator = self::getContainer()->get('ux.live_component.component_hydrator'); /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); $this->expectException(\RuntimeException::class); $hydrator->hydrate($factory->get('component1'), []); @@ -140,13 +134,11 @@ public function testHydrationFailsIfChecksumMissing(): void public function testHydrationFailsOnChecksumMismatch(): void { - self::bootKernel(); - /** @var LiveComponentHydrator $hydrator */ - $hydrator = self::$container->get('ux.live_component.component_hydrator'); + $hydrator = self::getContainer()->get('ux.live_component.component_hydrator'); /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); $this->expectException(\RuntimeException::class); $hydrator->hydrate($factory->get('component1'), ['_checksum' => 'invalid']); @@ -154,13 +146,11 @@ public function testHydrationFailsOnChecksumMismatch(): void public function testPreDehydrateAndPostHydrateHooksCalled(): void { - self::bootKernel(); - /** @var LiveComponentHydrator $hydrator */ - $hydrator = self::$container->get('ux.live_component.component_hydrator'); + $hydrator = self::getContainer()->get('ux.live_component.component_hydrator'); /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); /** @var Component2 $component */ $component = $factory->create('component2'); @@ -187,13 +177,11 @@ public function testPreDehydrateAndPostHydrateHooksCalled(): void public function testDeletingEntityBetweenDehydrationAndHydrationSetsItToNull(): void { - self::bootKernel(); - /** @var LiveComponentHydrator $hydrator */ - $hydrator = self::$container->get('ux.live_component.component_hydrator'); + $hydrator = self::getContainer()->get('ux.live_component.component_hydrator'); /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); $entity = create(Entity1::class); @@ -225,13 +213,11 @@ public function testDeletingEntityBetweenDehydrationAndHydrationSetsItToNull(): public function testCorrectlyUsesCustomFrontendNameInDehydrateAndHydrate(): void { - self::bootKernel(); - /** @var LiveComponentHydrator $hydrator */ - $hydrator = self::$container->get('ux.live_component.component_hydrator'); + $hydrator = self::getContainer()->get('ux.live_component.component_hydrator'); /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); /** @var Component3 $component */ $component = $factory->create('component3', ['prop1' => 'value1', 'prop2' => 'value2']); diff --git a/src/TwigComponent/tests/Integration/ComponentExtensionTest.php b/src/TwigComponent/tests/Integration/ComponentExtensionTest.php index aa1d52942ab..22ce7ca6a4f 100644 --- a/src/TwigComponent/tests/Integration/ComponentExtensionTest.php +++ b/src/TwigComponent/tests/Integration/ComponentExtensionTest.php @@ -19,11 +19,11 @@ */ final class ComponentExtensionTest extends KernelTestCase { + use ContainerBC; + public function testCanRenderComponent(): void { - self::bootKernel(); - - $output = self::$container->get(Environment::class)->render('template_a.html.twig'); + $output = self::getContainer()->get(Environment::class)->render('template_a.html.twig'); $this->assertStringContainsString('propA: prop a value', $output); $this->assertStringContainsString('propB: prop b value', $output); @@ -32,9 +32,7 @@ public function testCanRenderComponent(): void public function testCanRenderTheSameComponentMultipleTimes(): void { - self::bootKernel(); - - $output = self::$container->get(Environment::class)->render('template_b.html.twig'); + $output = self::getContainer()->get(Environment::class)->render('template_b.html.twig'); $this->assertStringContainsString('propA: prop a value 1', $output); $this->assertStringContainsString('propB: prop b value 1', $output); @@ -45,18 +43,14 @@ public function testCanRenderTheSameComponentMultipleTimes(): void public function testCanCustomizeTemplateWithAttribute(): void { - self::bootKernel(); - - $output = self::$container->get(Environment::class)->render('template_b.html.twig'); + $output = self::getContainer()->get(Environment::class)->render('template_b.html.twig'); $this->assertStringContainsString('Custom template 1', $output); } public function testCanCustomizeTemplateWithServiceTag(): void { - self::bootKernel(); - - $output = self::$container->get(Environment::class)->render('template_c.html.twig'); + $output = self::getContainer()->get(Environment::class)->render('template_c.html.twig'); $this->assertStringContainsString('Custom template 2', $output); } diff --git a/src/TwigComponent/tests/Integration/ComponentFactoryTest.php b/src/TwigComponent/tests/Integration/ComponentFactoryTest.php index f27d8bb329f..cfd858b6a45 100644 --- a/src/TwigComponent/tests/Integration/ComponentFactoryTest.php +++ b/src/TwigComponent/tests/Integration/ComponentFactoryTest.php @@ -23,12 +23,12 @@ */ final class ComponentFactoryTest extends KernelTestCase { + use ContainerBC; + public function testCreatedComponentsAreNotShared(): void { - self::bootKernel(); - /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); /** @var ComponentA $componentA */ $componentA = $factory->create('component_a', ['propA' => 'A', 'propB' => 'B']); @@ -46,10 +46,8 @@ public function testCreatedComponentsAreNotShared(): void public function testNonAutoConfiguredCreatedComponentsAreNotShared(): void { - self::bootKernel(); - /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); /** @var ComponentB $componentA */ $componentA = $factory->create('component_b'); @@ -62,10 +60,8 @@ public function testNonAutoConfiguredCreatedComponentsAreNotShared(): void public function testCanGetUnmountedComponent(): void { - self::bootKernel(); - /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); /** @var ComponentA $component */ $component = $factory->get('component_a'); @@ -76,10 +72,8 @@ public function testCanGetUnmountedComponent(): void public function testMountCanHaveOptionalParameters(): void { - self::bootKernel(); - /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); /** @var ComponentC $component */ $component = $factory->create('component_c', [ @@ -104,10 +98,8 @@ public function testMountCanHaveOptionalParameters(): void public function testExceptionThrownIfRequiredMountParameterIsMissingFromPassedData(): void { - self::bootKernel(); - /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); $this->expectException(\LogicException::class); $this->expectExceptionMessage('Symfony\UX\TwigComponent\Tests\Fixture\Component\ComponentC::mount() has a required $propA parameter. Make sure this is passed or make give a default value.'); @@ -117,10 +109,8 @@ public function testExceptionThrownIfRequiredMountParameterIsMissingFromPassedDa public function testExceptionThrownIfUnableToWritePassedDataToProperty(): void { - self::bootKernel(); - /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); $this->expectException(\LogicException::class); $this->expectExceptionMessage('Unable to write "service" to component "Symfony\UX\TwigComponent\Tests\Fixture\Component\ComponentA". Make sure this is a writable property or create a mount() with a $service argument.'); @@ -138,10 +128,8 @@ public function testTwigComponentServiceTagMustHaveKey(): void public function testCanGetConfigForComponentByName(): void { - self::bootKernel(); - /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); $this->assertSame( [ @@ -157,10 +145,8 @@ public function testCanGetConfigForComponentByName(): void public function testCanGetConfigForComponentByObject(): void { - self::bootKernel(); - /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); $this->assertSame( [ @@ -176,10 +162,8 @@ public function testCanGetConfigForComponentByObject(): void public function testCanGetConfigForComponentByClass(): void { - self::bootKernel(); - /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); $this->assertSame( [ @@ -195,10 +179,8 @@ public function testCanGetConfigForComponentByClass(): void public function testCanGetConfigForSameComponentWithDifferentName(): void { - self::bootKernel(); - /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); $this->assertSame( [ @@ -214,10 +196,8 @@ public function testCanGetConfigForSameComponentWithDifferentName(): void public function testCannotGetConfigForComponentIfMultipleOfSameClass(): void { - self::bootKernel(); - /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); $this->expectException(\InvalidArgumentException::class); $this->expectDeprecationMessage(sprintf('2 "%s" components registered with names "component_b, component_d". Use the $name parameter to explicitly choose one.', ComponentB::class)); @@ -227,10 +207,8 @@ public function testCannotGetConfigForComponentIfMultipleOfSameClass(): void public function testCannotGetConfigByNameForNonRegisteredComponent(): void { - self::bootKernel(); - /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage('Unknown component "invalid". The registered components are: component_a, component_b, component_c, component_d'); @@ -240,10 +218,8 @@ public function testCannotGetConfigByNameForNonRegisteredComponent(): void public function testCannotGetConfigByClassForNonRegisteredComponent(): void { - self::bootKernel(); - /** @var ComponentFactory $factory */ - $factory = self::$container->get('ux.twig_component.component_factory'); + $factory = self::getContainer()->get('ux.twig_component.component_factory'); $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage('Unknown component class "Symfony\UX\TwigComponent\Tests\Integration\ComponentFactoryTest". The registered components are: component_a, component_b, component_c, component_d'); diff --git a/src/TwigComponent/tests/Integration/ContainerBC.php b/src/TwigComponent/tests/Integration/ContainerBC.php new file mode 100644 index 00000000000..2f623b12b84 --- /dev/null +++ b/src/TwigComponent/tests/Integration/ContainerBC.php @@ -0,0 +1,26 @@ + + */ +trait ContainerBC +{ + protected static function getContainer(): ContainerInterface + { + if (!\method_exists(parent::class, 'getContainer')) { + if (!static::$booted) { + static::bootKernel(); + } + + return self::$container; + } + + return parent::getContainer(); + } +}