From 60c700428b3794e5b45e7a0d23edfb3e04306ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Poirier=20Th=C3=A9or=C3=AAt?= Date: Sun, 11 Aug 2024 13:42:20 -0400 Subject: [PATCH] [TesterBundle] EventDispatcherTesterTrait --- composer.json | 1 + .../EventDispatcherTesterTrait.php | 88 ++++++ packages/tester-bundle/README.md | 47 ++- packages/tester-bundle/composer.json | 1 + tests/AppKernelTest.php | 18 ++ .../event_dispatcher.xml | 280 ++++++++++++++++++ 6 files changed, 420 insertions(+), 15 deletions(-) create mode 100644 packages/tester-bundle/EventDispatcher/EventDispatcherTesterTrait.php create mode 100644 tests/AppKernelTest.php create mode 100644 tests/fixtures/AppKernelTest/testEventDispatcherConfiguration/event_dispatcher.xml diff --git a/composer.json b/composer.json index 17e9ed9c0..8137c5e9d 100644 --- a/composer.json +++ b/composer.json @@ -19,6 +19,7 @@ "doctrine/persistence": "^2.2 || ^3.0", "dragonmantank/cron-expression": "^3.3", "ext-ctype": "*", + "ext-dom": "*", "ext-iconv": "*", "ext-json": "*", "ext-mongodb": "*", diff --git a/packages/tester-bundle/EventDispatcher/EventDispatcherTesterTrait.php b/packages/tester-bundle/EventDispatcher/EventDispatcherTesterTrait.php new file mode 100644 index 000000000..50b8ae8ae --- /dev/null +++ b/packages/tester-bundle/EventDispatcher/EventDispatcherTesterTrait.php @@ -0,0 +1,88 @@ + + * + * By Removing the unique string pattern in the class attribute using DomDocument. + * + * The result after cleaning will be: + * + * + * + * Clean when the class name contains Container and Ghost in its name. + */ + public static function cleanEventDispatcherFileContainerReference(string $filePath): void + { + $dom = new \DOMDocument(); + $dom->load($filePath); + + $xpath = new \DOMXPath($dom); + + $nodes = $xpath->query('//callable[@class]'); + + foreach ($nodes as $node) { + \assert($node instanceof \DOMElement); + $class = $node->getAttribute('class'); + if (preg_match('/Container.*Ghost/', $class)) { + // Use regex to match only the alphanumeric patterns that follow "Container" and "Ghost" + $class = preg_replace('/(?<=Container)[A-Za-z0-9]+|(?<=Ghost)[A-Za-z0-9]+/', '__cleaned__', $class); + $node->setAttribute('class', $class); + } + } + + $dom->save($filePath); + } + + public static function assertEventDispatcherConfiguration(string $expectedFilePath, string $dispatcherName = 'event_dispatcher'): void + { + $commandTester = new CommandTester( + static::getContainer()->get('console.command.event_dispatcher_debug') + ); + + $commandTester->execute([ + '--dispatcher' => $dispatcherName, + '--format' => 'xml', + ]); + + $display = $commandTester->getDisplay(); + + $resultFilePath = tempnam(sys_get_temp_dir(), 'event_dispatcher_configuration'); + + file_put_contents($resultFilePath, $display); + + static::cleanEventDispatcherFile($resultFilePath); + + register_shutdown_function('unlink', $resultFilePath); + + if (!file_exists($expectedFilePath)) { + copy($resultFilePath, $expectedFilePath); + + TestCase::fail($dispatcherName.' configuration file created at '.$expectedFilePath.'. Please review it and commit it.'); + } + + TestCase::assertXmlFileEqualsXmlFile( + $expectedFilePath, + $resultFilePath, + ); + } +} diff --git a/packages/tester-bundle/README.md b/packages/tester-bundle/README.md index 64754f830..47483d8fd 100644 --- a/packages/tester-bundle/README.md +++ b/packages/tester-bundle/README.md @@ -3,29 +3,46 @@ Draw Tester Bundle This bundle integrate the Draw Tester Component. -To use the HttpTesterTrait in a KernelTestCase you must simply do this: +It also provides test helpers to make it easier to test your Symfony application. -```PHP -getContainer()->get('test.client'); + $this->assertEventDispatcherConfiguration( + __DIR__.'/fixtures/AppKernelTest/testEventDispatcherConfiguration/event_dispatcher.xml', + 'event_dispatcher' // This is the default value, same as the debug:event-dispatcher command + ); } } ``` -As you can see we are using the **HttpTesterTrait** of the **Bundle** instead of the **Component**. -This is because it as the implementation of the implementation of the **createHttpTesterClient** method. +The first time you run this test it will fail and dump the current configuration in the `event_dispatcher.xml` file. + +Commit this file, next time your rune this test you will be able to validate that the configuration is still valid. + +If you change the listener in your code or change your dependencies you can run the test again and see the diff. -Also you can see that we are booting a new kernel every time. It's to make sure we are using a new container -on each request like the behaviour of a normal client request will do. +This will allow you to see if some external listeners changed at the same time. \ No newline at end of file diff --git a/packages/tester-bundle/composer.json b/packages/tester-bundle/composer.json index fdbda647e..0200556a3 100644 --- a/packages/tester-bundle/composer.json +++ b/packages/tester-bundle/composer.json @@ -11,6 +11,7 @@ "integration test" ], "require": { + "ext-dom": "*", "draw/core": "^0.11", "draw/tester": "^0.11", "symfony/browser-kit": "^6.4.0", diff --git a/tests/AppKernelTest.php b/tests/AppKernelTest.php new file mode 100644 index 000000000..0ab59510b --- /dev/null +++ b/tests/AppKernelTest.php @@ -0,0 +1,18 @@ +assertEventDispatcherConfiguration( + __DIR__.'/fixtures/AppKernelTest/testEventDispatcherConfiguration/event_dispatcher.xml' + ); + } +} diff --git a/tests/fixtures/AppKernelTest/testEventDispatcherConfiguration/event_dispatcher.xml b/tests/fixtures/AppKernelTest/testEventDispatcherConfiguration/event_dispatcher.xml new file mode 100644 index 000000000..42149d9a3 --- /dev/null +++ b/tests/fixtures/AppKernelTest/testEventDispatcherConfiguration/event_dispatcher.xml @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +