diff --git a/.github/workflows/test-application.yaml b/.github/workflows/test-application.yaml index 84c1c155..31221a6b 100644 --- a/.github/workflows/test-application.yaml +++ b/.github/workflows/test-application.yaml @@ -28,10 +28,11 @@ jobs: - php-version: '8.3' - php-version: '8.4' - php-version: '8.5' + symfony-version: '8.*' steps: - name: Checkout project - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install and configure PHP uses: shivammathur/setup-php@v2 @@ -46,8 +47,5 @@ jobs: dependency-versions: ${{ matrix.dependencies }} composer-options: --prefer-dist - - name: Prepare phpunit - run: vendor/bin/simple-phpunit install - - name: Execute test cases run: make test diff --git a/CHANGELOG.md b/CHANGELOG.md index d8fd2fb6..9df75ce5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ Changelog ========= +3.2.0 +----- + +* Support Symfony 8. + * Rewrote service configurations from XML to PHP. + 3.1.2 ----- diff --git a/Makefile b/Makefile index d27173c0..06cf0d08 100644 --- a/Makefile +++ b/Makefile @@ -27,9 +27,43 @@ list: @echo 'functional_tests_phpcr: will run functional tests with PHPCR' @echo 'functional_tests_orm: will run functional tests with ORM' -include ${TESTING_SCRIPTS_DIR}/make/unit_tests.mk -include ${TESTING_SCRIPTS_DIR}/make/functional_tests_phpcr.mk -include ${TESTING_SCRIPTS_DIR}/make/functional_tests_orm.mk +unit_tests: + @echo + @echo '+++ run unit tests +++' +ifeq ($(HAS_XDEBUG), 0) + @vendor/bin/phpunit --coverage-clover build/logs/clover.xml --testsuite "unit tests" +else + @vendor/bin/phpunit --testsuite "unit tests" +endif + +functional_tests_orm: + @if [ "${CONSOLE}" = "" ]; then echo "Console executable missing"; exit 1; fi + @echo + @echo '+++ create ORM database +++' + @${CONSOLE} doctrine:schema:drop --env=orm --force + @${CONSOLE} doctrine:database:create --env=orm || echo "Failed to create database. If this is sqlite, this is normal. Otherwise there will be an error with schema creation" + @${CONSOLE} doctrine:schema:create --env=orm + @echo '+++ run ORM functional tests +++' +ifeq ($(HAS_XDEBUG), 0) + @vendor/bin/phpunit --coverage-clover build/logs/clover.xml --testsuite "functional tests with orm" +else + @vendor/bin/phpunit --testsuite "functional tests with orm" +endif + @${CONSOLE} doctrine:database:drop --force + +functional_tests_phpcr: + @if [ "${CONSOLE}" = "" ]; then echo "Console executable missing"; exit 1; fi + @echo + @echo '+++ create PHPCR +++' + @${CONSOLE} doctrine:phpcr:init:dbal --drop --force + @${CONSOLE} doctrine:phpcr:repository:init + @echo '+++ run PHPCR functional tests +++' +ifeq ($(HAS_XDEBUG), 0) + @vendor/bin/phpunit --coverage-clover build/logs/clover.xml --testsuite "functional tests with phpcr" +else + @vendor/bin/phpunit --testsuite "functional tests with phpcr" +endif + @${CONSOLE} doctrine:database:drop --force .PHONY: test test: unit_tests functional_tests_phpcr functional_tests_orm diff --git a/composer.json b/composer.json index c4c886d2..45a3f37e 100644 --- a/composer.json +++ b/composer.json @@ -17,32 +17,31 @@ "require": { "php": "^8.1", "symfony-cmf/routing": "^3.0.3", - "symfony/framework-bundle": "^6.4 || ^7.0" + "symfony/framework-bundle": "^6.4 || ^7.0 || ^8.0" }, "require-dev": { - "doctrine/data-fixtures": "^1.0.0", - "doctrine/doctrine-bundle": "^2.8", + "doctrine/data-fixtures": "^1.2 || ^2.0", + "doctrine/doctrine-bundle": "^2.8 || ^3.0", "doctrine/orm": "^2.9 || ^3.0.1", "doctrine/phpcr-bundle": "^3.0", - "doctrine/phpcr-odm": "^2.0", + "doctrine/phpcr-odm": "^3.0", "jackalope/jackalope-doctrine-dbal": "^2.0", "phpstan/phpstan": "^2.0", "phpstan/phpstan-doctrine": "^2.0", "phpstan/phpstan-phpunit": "^2.0", "phpstan/phpstan-symfony": "^2.0", - "phpunit/phpunit": "^9.5.28", - "matthiasnoback/symfony-dependency-injection-test": "^4.1.0 || ^5.1.0", - "matthiasnoback/symfony-config-test": "^4.1.0 || ^5.1.0", - "symfony/phpunit-bridge": "^7.0.3", - "symfony/form": "^6.4 || ^7.0", - "symfony/monolog-bundle": "^3.5", - "symfony/security-bundle": "^6.4 || ^7.0", - "symfony/serializer": "^6.4 || ^7.0", - "symfony/translation": "^6.4 || ^7.0", - "symfony/validator": "^6.4 || ^7.0", - "symfony/var-exporter": "^6.4 || ^7.0", - "symfony/twig-bundle": "^6.4 || ^7.0", - "symfony-cmf/testing": "5.0.2", + "phpunit/phpunit": "^10.5.63 || ^11.5.55 || ^13", + "matthiasnoback/symfony-dependency-injection-test": "^6.3", + "matthiasnoback/symfony-config-test": "^6.2", + "symfony/form": "^6.4 || ^7.0 || ^8.0", + "symfony/monolog-bundle": "^3.5 || ^4.0", + "symfony/security-bundle": "^6.4 || ^7.0 || ^8.0", + "symfony/serializer": "^6.4 || ^7.0 || ^8.0", + "symfony/translation": "^6.4 || ^7.0 || ^8.0", + "symfony/validator": "^6.4 || ^7.0 || ^8.0", + "symfony/var-exporter": "^6.4 || ^7.0 || ^8.0", + "symfony/twig-bundle": "^6.4 || ^7.0 || ^8.0", + "symfony-cmf/testing": "5.0.4", "twig/twig": "^2.4.4 || ^3.0" }, "suggest": { diff --git a/src/DependencyInjection/CmfRoutingExtension.php b/src/DependencyInjection/CmfRoutingExtension.php index b03db9cb..b26aa5d3 100644 --- a/src/DependencyInjection/CmfRoutingExtension.php +++ b/src/DependencyInjection/CmfRoutingExtension.php @@ -16,7 +16,7 @@ use Symfony\Component\Config\FileLocator; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpKernel\DependencyInjection\Extension; @@ -30,7 +30,7 @@ final class CmfRoutingExtension extends Extension public function load(array $configs, ContainerBuilder $container): void { $config = $this->processConfiguration(new Configuration(), $configs); - $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); if ($this->isConfigEnabled($container, $config['dynamic'])) { $this->setupDynamicRouter($config['dynamic'], $container, $loader); @@ -39,12 +39,12 @@ public function load(array $configs, ContainerBuilder $container): void $this->setupChainRouter($config, $container, $loader); $this->setupFormTypes($config, $container, $loader); - $loader->load('validators.xml'); + $loader->load('validators.php'); } private function setupChainRouter(array $config, ContainerBuilder $container, LoaderInterface $loader): void { - $loader->load('routing-chain.xml'); + $loader->load('routing-chain.php'); $container->setParameter('cmf_routing.replace_symfony_router', $config['chain']['replace_symfony_router']); @@ -57,7 +57,7 @@ private function setupChainRouter(array $config, ContainerBuilder $container, Lo private function setupFormTypes(array $config, ContainerBuilder $container, LoaderInterface $loader): void { - $loader->load('form-type.xml'); + $loader->load('form-type.php'); if (\array_key_exists('dynamic', $config)) { $routeTypeTypeDefinition = $container->getDefinition('cmf_routing.route_type_form_type'); @@ -73,7 +73,7 @@ private function setupFormTypes(array $config, ContainerBuilder $container, Load */ private function setupDynamicRouter(array $config, ContainerBuilder $container, LoaderInterface $loader): void { - $loader->load('routing-dynamic.xml'); + $loader->load('routing-dynamic.php'); $container->setParameter('cmf_routing.redirectable_url_matcher', $config['redirectable_url_matcher']); @@ -205,7 +205,7 @@ private function setupDynamicRouter(array $config, ContainerBuilder $container, private function loadPhpcrProvider(array $config, LoaderInterface $loader, ContainerBuilder $container, array $locales, $matchImplicitLocale): void { - $loader->load('provider-phpcr.xml'); + $loader->load('provider-phpcr.php'); $container->setParameter('cmf_routing.backend_type_phpcr', true); $container->setParameter('cmf_routing.dynamic.persistence.phpcr.route_basepaths', array_values(array_unique($config['route_basepaths']))); @@ -234,12 +234,12 @@ private function loadInitializer(LoaderInterface $loader, ContainerBuilder $cont $initializedBasepaths ); - $loader->load('initializer-phpcr.xml'); + $loader->load('initializer-phpcr.php'); } private function loadOrmProvider(array $config, LoaderInterface $loader, ContainerBuilder $container, $matchImplicitLocale): void { - $loader->load('provider-orm.xml'); + $loader->load('provider-orm.php'); $container->setParameter('cmf_routing.backend_type_orm', true); $container->setParameter('cmf_routing.dynamic.persistence.orm.manager_name', $config['manager_name']); diff --git a/src/Resources/config/form-type.php b/src/Resources/config/form-type.php new file mode 100644 index 00000000..662deb24 --- /dev/null +++ b/src/Resources/config/form-type.php @@ -0,0 +1,11 @@ +services(); + $parameters = $container->parameters(); + + $services->set('cmf_routing.route_type_form_type', \Symfony\Cmf\Bundle\RoutingBundle\Form\Type\RouteTypeType::class) + ->tag('form.type', ['alias' => 'cmf_routing_route_type']); +}; diff --git a/src/Resources/config/form-type.xml b/src/Resources/config/form-type.xml deleted file mode 100644 index 91681dca..00000000 --- a/src/Resources/config/form-type.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - diff --git a/src/Resources/config/initializer-phpcr.php b/src/Resources/config/initializer-phpcr.php new file mode 100644 index 00000000..9e6dfc83 --- /dev/null +++ b/src/Resources/config/initializer-phpcr.php @@ -0,0 +1,15 @@ +services(); + $parameters = $container->parameters(); + + $services->set('cmf_routing.initializer', \Doctrine\Bundle\PHPCRBundle\Initializer\GenericInitializer::class) + ->args([ + 'CmfRoutingBundle', + '%cmf_routing.dynamic.persistence.phpcr.initialized_basepaths%', + ]) + ->tag('doctrine_phpcr.initializer'); +}; diff --git a/src/Resources/config/initializer-phpcr.xml b/src/Resources/config/initializer-phpcr.xml deleted file mode 100644 index 89b94c32..00000000 --- a/src/Resources/config/initializer-phpcr.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - CmfRoutingBundle - %cmf_routing.dynamic.persistence.phpcr.initialized_basepaths% - - - - - diff --git a/src/Resources/config/provider-orm.php b/src/Resources/config/provider-orm.php new file mode 100644 index 00000000..9b907076 --- /dev/null +++ b/src/Resources/config/provider-orm.php @@ -0,0 +1,30 @@ +services(); + $parameters = $container->parameters(); + + $services->set('cmf_routing.orm_content_repository', \Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Orm\ContentRepository::class) + ->args([service('doctrine')]) + ->call('setManagerName', ['%cmf_routing.dynamic.persistence.orm.manager_name%']); + + $services->alias('cmf_routing.content_repository', 'cmf_routing.orm_content_repository'); + + $services->set('cmf_routing.orm_candidates', \Symfony\Cmf\Component\Routing\Candidates\Candidates::class) + ->args([ + '%cmf_routing.dynamic.locales%', + '%cmf_routing.dynamic.limit_candidates%', + ]); + + $services->set('cmf_routing.route_provider', \Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Orm\RouteProvider::class) + ->public() + ->args([ + service('doctrine'), + service('cmf_routing.orm_candidates'), + '%cmf_routing.dynamic.persistence.orm.route_class%', + ]) + ->call('setManagerName', ['%cmf_routing.dynamic.persistence.orm.manager_name%']) + ->call('setRouteCollectionLimit', ['%cmf_routing.route_collection_limit%']); +}; diff --git a/src/Resources/config/provider-orm.xml b/src/Resources/config/provider-orm.xml deleted file mode 100644 index 5eaa0e02..00000000 --- a/src/Resources/config/provider-orm.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - %cmf_routing.dynamic.persistence.orm.manager_name% - - - - - - %cmf_routing.dynamic.locales% - %cmf_routing.dynamic.limit_candidates% - - - - - - %cmf_routing.dynamic.persistence.orm.route_class% - %cmf_routing.dynamic.persistence.orm.manager_name% - %cmf_routing.route_collection_limit% - - - diff --git a/src/Resources/config/provider-phpcr.php b/src/Resources/config/provider-phpcr.php new file mode 100644 index 00000000..ea4e064a --- /dev/null +++ b/src/Resources/config/provider-phpcr.php @@ -0,0 +1,52 @@ +services(); + $parameters = $container->parameters(); + + $services->set('cmf_routing.phpcr_route_provider', \Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\RouteProvider::class) + ->args([ + service('doctrine_phpcr'), + service('cmf_routing.phpcr_candidates_prefix'), + null, + service('logger')->ignoreOnInvalid(), + ]) + ->call('setManagerName', ['%cmf_routing.dynamic.persistence.phpcr.manager_name%']) + ->call('setRouteCollectionLimit', ['%cmf_routing.route_collection_limit%']); + + $services->alias('cmf_routing.route_provider', 'cmf_routing.phpcr_route_provider') + ->public(); + + $services->set('cmf_routing.phpcr_candidates_prefix', \Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\PrefixCandidates::class) + ->args([ + '%cmf_routing.dynamic.persistence.phpcr.route_basepaths%', + '%cmf_routing.dynamic.locales%', + service('doctrine_phpcr'), + '%cmf_routing.dynamic.limit_candidates%', + ]) + ->call('setManagerName', ['%cmf_routing.dynamic.persistence.phpcr.manager_name%']); + + $services->set('cmf_routing.phpcr_content_repository', \Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\ContentRepository::class) + ->args([service('doctrine_phpcr')]) + ->call('setManagerName', ['%cmf_routing.dynamic.persistence.phpcr.manager_name%']); + + $services->alias('cmf_routing.content_repository', 'cmf_routing.phpcr_content_repository'); + + $services->set('cmf_routing.phpcrodm_route_idprefix_listener', \Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\IdPrefixListener::class) + ->args([service('cmf_routing.phpcr_candidates_prefix')]) + ->tag('doctrine_phpcr.event_listener', ['event' => 'postLoad']) + ->tag('doctrine_phpcr.event_listener', ['event' => 'postPersist']) + ->tag('doctrine_phpcr.event_listener', ['event' => 'postMove']); + + $services->set('cmf_routing.phpcrodm_route_locale_listener', \Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\LocaleListener::class) + ->args([ + service('cmf_routing.phpcr_candidates_prefix'), + '%cmf_routing.dynamic.locales%', + '%cmf_routing.dynamic.auto_locale_pattern%', + ]) + ->tag('doctrine_phpcr.event_listener', ['event' => 'postLoad']) + ->tag('doctrine_phpcr.event_listener', ['event' => 'postPersist']) + ->tag('doctrine_phpcr.event_listener', ['event' => 'postMove']); +}; diff --git a/src/Resources/config/provider-phpcr.xml b/src/Resources/config/provider-phpcr.xml deleted file mode 100644 index 48104d89..00000000 --- a/src/Resources/config/provider-phpcr.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - null - - %cmf_routing.dynamic.persistence.phpcr.manager_name% - %cmf_routing.route_collection_limit% - - - - - - %cmf_routing.dynamic.persistence.phpcr.route_basepaths% - %cmf_routing.dynamic.locales% - - %cmf_routing.dynamic.limit_candidates% - %cmf_routing.dynamic.persistence.phpcr.manager_name% - - - - - %cmf_routing.dynamic.persistence.phpcr.manager_name% - - - - - - - - - - - - - - %cmf_routing.dynamic.locales% - %cmf_routing.dynamic.auto_locale_pattern% - - - - - - - diff --git a/src/Resources/config/routing-chain.php b/src/Resources/config/routing-chain.php new file mode 100644 index 00000000..7230fc71 --- /dev/null +++ b/src/Resources/config/routing-chain.php @@ -0,0 +1,14 @@ +services(); + $parameters = $container->parameters(); + + $services->set('cmf_routing.router', \Symfony\Cmf\Component\Routing\ChainRouter::class) + ->args([service('logger')->ignoreOnInvalid()]) + ->call('setContext', [service('router.request_context')]); + + $services->alias(\Symfony\Cmf\Component\Routing\ChainRouterInterface::class, 'cmf_routing.router'); +}; diff --git a/src/Resources/config/routing-chain.xml b/src/Resources/config/routing-chain.xml deleted file mode 100644 index 98288d7e..00000000 --- a/src/Resources/config/routing-chain.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/Resources/config/routing-dynamic.php b/src/Resources/config/routing-dynamic.php new file mode 100644 index 00000000..85775a3c --- /dev/null +++ b/src/Resources/config/routing-dynamic.php @@ -0,0 +1,107 @@ +services(); + $parameters = $container->parameters(); + $parameters->set('cmf_routing.uri_filter_regexp', null); + + $services->set('cmf_routing.enhancer.route_content', \Symfony\Cmf\Component\Routing\Enhancer\RouteContentEnhancer::class) + ->args([ + '_route_object', + '_content', + ]) + ->tag('dynamic_router_route_enhancer', ['priority' => 100]); + + $services->set('cmf_routing.enhancer.default_controller', \Symfony\Cmf\Component\Routing\Enhancer\FieldPresenceEnhancer::class) + ->private() + ->args([ + null, + '_controller', + '%cmf_routing.default_controller%', + ]); + + $services->set('cmf_routing.enhancer.explicit_template', \Symfony\Cmf\Component\Routing\Enhancer\FieldPresenceEnhancer::class) + ->private() + ->args([ + '_template', + '_controller', + '%cmf_routing.generic_controller%', + ]); + + $services->set('cmf_routing.enhancer.controllers_by_type', \Symfony\Cmf\Component\Routing\Enhancer\FieldMapEnhancer::class) + ->private() + ->args([ + 'type', + '_controller', + '%cmf_routing.controllers_by_type%', + ]); + + $services->set('cmf_routing.enhancer.controllers_by_class', \Symfony\Cmf\Component\Routing\Enhancer\FieldByClassEnhancer::class) + ->private() + ->args([ + '_content', + '_controller', + '%cmf_routing.controllers_by_class%', + ]); + + $services->set('cmf_routing.enhancer.controller_for_templates_by_class', \Symfony\Cmf\Component\Routing\Enhancer\FieldByClassEnhancer::class) + ->private() + ->args([ + '_content', + '_controller', + [], + ]); + + $services->set('cmf_routing.enhancer.templates_by_class', \Symfony\Cmf\Component\Routing\Enhancer\FieldByClassEnhancer::class) + ->private() + ->args([ + '_content', + '_template', + '%cmf_routing.templates_by_class%', + ]); + + $services->set('cmf_routing.enhancer.content_repository', \Symfony\Cmf\Component\Routing\Enhancer\ContentRepositoryEnhancer::class) + ->private() + ->args([service('cmf_routing.content_repository')]); + + $services->set('cmf_routing.dynamic_router', \Symfony\Cmf\Bundle\RoutingBundle\Routing\DynamicRouter::class) + ->args([ + service('router.request_context'), + service('cmf_routing.nested_matcher'), + '', + '%cmf_routing.uri_filter_regexp%', + service('event_dispatcher')->ignoreOnInvalid(), + service('cmf_routing.route_provider'), + ]) + ->call('setRequestStack', [service('request_stack')]); + + $services->set('cmf_routing.nested_matcher', \Symfony\Cmf\Component\Routing\NestedMatcher\NestedMatcher::class) + ->args([ + service('cmf_routing.route_provider'), + service('cmf_routing.final_matcher'), + ]); + + $services->set('cmf_routing.matcher.dummy_collection', \Symfony\Component\Routing\RouteCollection::class) + ->private(); + + $services->set('cmf_routing.matcher.dummy_context', \Symfony\Component\Routing\RequestContext::class) + ->private(); + + $services->set('cmf_routing.final_matcher', \Symfony\Cmf\Component\Routing\NestedMatcher\UrlMatcher::class) + ->args([ + service('cmf_routing.matcher.dummy_collection'), + service('cmf_routing.matcher.dummy_context'), + ]); + + $services->set('cmf_routing.generator', \Symfony\Cmf\Component\Routing\ContentAwareGenerator::class) + ->args([ + service('cmf_routing.route_provider'), + service('logger')->ignoreOnInvalid(), + ]); + + $services->set('cmf_routing.redirect_controller', \Symfony\Cmf\Bundle\RoutingBundle\Controller\RedirectController::class) + ->public() + ->args([service('router')]); +}; diff --git a/src/Resources/config/routing-dynamic.xml b/src/Resources/config/routing-dynamic.xml deleted file mode 100644 index 087a6135..00000000 --- a/src/Resources/config/routing-dynamic.xml +++ /dev/null @@ -1,91 +0,0 @@ - - - - - null - - - - - _route_object - _content - - - - - null - _controller - %cmf_routing.default_controller% - - - - _template - _controller - %cmf_routing.generic_controller% - - - - type - _controller - %cmf_routing.controllers_by_type% - - - - _content - _controller - %cmf_routing.controllers_by_class% - - - - _content - _controller - - - - - _content - _template - %cmf_routing.templates_by_class% - - - - - - - - - - - %cmf_routing.uri_filter_regexp% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Resources/config/validators.php b/src/Resources/config/validators.php new file mode 100644 index 00000000..e58ad853 --- /dev/null +++ b/src/Resources/config/validators.php @@ -0,0 +1,15 @@ +services(); + $parameters = $container->parameters(); + + $services->set('cmf_routing.validator.route_defaults', \Symfony\Cmf\Bundle\RoutingBundle\Validator\Constraints\RouteDefaultsTwigValidator::class) + ->args([ + service('controller_resolver'), + service('twig.loader')->nullOnInvalid(), + ]) + ->tag('validator.constraint_validator', ['alias' => 'cmf_routing.validator.route_defaults']); +}; diff --git a/src/Resources/config/validators.xml b/src/Resources/config/validators.xml deleted file mode 100644 index 689dbaf2..00000000 --- a/src/Resources/config/validators.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - diff --git a/tests/Fixtures/App/DataFixtures/Phpcr/LoadRouteData.php b/tests/Fixtures/App/DataFixtures/Phpcr/LoadRouteData.php index 756ff05c..a763ae01 100644 --- a/tests/Fixtures/App/DataFixtures/Phpcr/LoadRouteData.php +++ b/tests/Fixtures/App/DataFixtures/Phpcr/LoadRouteData.php @@ -21,7 +21,7 @@ class LoadRouteData implements FixtureInterface { - public function load(ObjectManager $manager) + public function load(ObjectManager $manager): void { if (!$manager instanceof DocumentManagerInterface) { throw new \InvalidArgumentException(sprintf('Expected %s, got %s', DocumentManagerInterface::class, get_class($manager))); diff --git a/tests/Functional/Doctrine/Phpcr/RouteTest.php b/tests/Functional/Doctrine/Phpcr/RouteTest.php index a5a8eff7..04c9ceba 100644 --- a/tests/Functional/Doctrine/Phpcr/RouteTest.php +++ b/tests/Functional/Doctrine/Phpcr/RouteTest.php @@ -11,6 +11,7 @@ namespace Symfony\Cmf\Bundle\RoutingBundle\Tests\Functional\Doctrine\Phpcr; +use PHPUnit\Framework\Attributes as PHPUnit; use Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route; use Symfony\Cmf\Bundle\RoutingBundle\Tests\Functional\BaseTestCase; @@ -131,6 +132,7 @@ public function testSetPattern(): void /** * @depends testPersistEmptyOptions */ + #[PHPUnit\Depends('testPersistEmptyOptions')] public function testSetPatternInvalid(Route $route): void { $this->expectException(\InvalidArgumentException::class); diff --git a/tests/Unit/DependencyInjection/CmfRoutingExtensionTest.php b/tests/Unit/DependencyInjection/CmfRoutingExtensionTest.php index 13b65be0..beeaf4a1 100644 --- a/tests/Unit/DependencyInjection/CmfRoutingExtensionTest.php +++ b/tests/Unit/DependencyInjection/CmfRoutingExtensionTest.php @@ -13,6 +13,7 @@ use Doctrine\Bundle\PHPCRBundle\Initializer\GenericInitializer; use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractExtensionTestCase; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Cmf\Bundle\RoutingBundle\DependencyInjection\CmfRoutingExtension; use Symfony\Cmf\Component\Routing\ChainRouter; use Symfony\Component\DependencyInjection\Reference; @@ -130,9 +131,7 @@ public function testWhitespaceInPriorities(): void ); } - /** - * @dataProvider getBasePathsTests - */ + #[DataProvider('getBasePathsTests')] public function testLoadBasePaths(array $phpcrConfig, array $routeBasepathsParameter): void { $this->container->setParameter( @@ -163,7 +162,7 @@ public function testLoadBasePaths(array $phpcrConfig, array $routeBasepathsParam ); } - public function getBasePathsTests(): array + public static function getBasePathsTests(): array { return [ [ @@ -188,9 +187,7 @@ public function getBasePathsTests(): array ]; } - /** - * @dataProvider getBasePathsMergingTests - */ + #[DataProvider('getBasePathsMergingTests')] public function testRouteBasepathsMerging(array $phpcrConfig1, array $phpcrConfig2, array $routeBasepathsParameter): void { $this->container->setParameter( @@ -232,28 +229,25 @@ public function testRouteBasepathsMerging(array $phpcrConfig1, array $phpcrConfi ); } - public function getBasePathsMergingTests(): array + public static function getBasePathsMergingTests(): array { return [ [ ['route_basepaths' => ['/cms/test']], ['route_basepaths' => ['/cms/test2']], ['/cms/test', '/cms/test2'], - '/cms/test', ], [ ['route_basepaths' => ['/cms/test']], ['route_basepaths' => ['/cms/test2', '/cms/test3']], ['/cms/test', '/cms/test2', '/cms/test3'], - '/cms/test', ], [ [], ['route_basepaths' => ['/cms/test']], ['/cms/test'], - '/cms/test', ], ]; } diff --git a/tests/Unit/DependencyInjection/Compiler/ValidationPassTest.php b/tests/Unit/DependencyInjection/Compiler/ValidationPassTest.php index f9266386..aa0b1fde 100644 --- a/tests/Unit/DependencyInjection/Compiler/ValidationPassTest.php +++ b/tests/Unit/DependencyInjection/Compiler/ValidationPassTest.php @@ -12,6 +12,7 @@ namespace Symfony\Cmf\Bundle\RoutingBundle\Tests\Unit\DependencyInjection\Compiler; use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractCompilerPassTestCase; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Cmf\Bundle\RoutingBundle\DependencyInjection\Compiler\ValidationPass; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -26,9 +27,8 @@ protected function registerCompilerPass(ContainerBuilder $container): void * It should register the PHPCR documents for validation only when: * - the PHP backend is enabled AND * - the validator service is available. - * - * @dataProvider provideDocumentsValidationContext */ + #[DataProvider('provideDocumentsValidationContext')] public function testRegisterDocumentsValidation(bool $hasPhpcr, bool $hasValidator, bool $shouldBeRegistered): void { if ($hasPhpcr) { @@ -71,7 +71,7 @@ public function testRegisterDocumentsValidation(bool $hasPhpcr, bool $hasValidat * - _$hasValidator: Is the validator available ? * - _$shouldBeRegistered_: Should the documents validation be registered ? */ - public function provideDocumentsValidationContext(): array + public static function provideDocumentsValidationContext(): array { return [ [true, true, true], diff --git a/tests/Unit/DependencyInjection/ConfigurationTest.php b/tests/Unit/DependencyInjection/ConfigurationTest.php index d3bc386f..34cdc125 100644 --- a/tests/Unit/DependencyInjection/ConfigurationTest.php +++ b/tests/Unit/DependencyInjection/ConfigurationTest.php @@ -84,7 +84,6 @@ public function testSupportsAllConfigFormats(): void return __DIR__.'/../../Fixtures/fixtures/'.$path; }, [ 'config/config.yml', - 'config/config.xml', 'config/config.php', ]); diff --git a/tests/Unit/Doctrine/Orm/ContentRepositoryTest.php b/tests/Unit/Doctrine/Orm/ContentRepositoryTest.php index 77250d78..917232be 100644 --- a/tests/Unit/Doctrine/Orm/ContentRepositoryTest.php +++ b/tests/Unit/Doctrine/Orm/ContentRepositoryTest.php @@ -14,6 +14,7 @@ use Doctrine\Persistence\ManagerRegistry; use Doctrine\Persistence\ObjectManager; use Doctrine\Persistence\ObjectRepository; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Orm\ContentRepository; @@ -60,9 +61,7 @@ public function testFindById(): void $this->assertSame($this->document, $foundDocument); } - /** - * @dataProvider getFindCorrectModelAndIdData - */ + #[DataProvider('getFindCorrectModelAndIdData')] public function testFindCorrectModelAndId($input, $model, $id): void { $this->objectManager @@ -89,7 +88,7 @@ public function testFindCorrectModelAndId($input, $model, $id): void $this->assertSame($this, $foundDocument); } - public function getFindCorrectModelAndIdData(): array + public static function getFindCorrectModelAndIdData(): array { return [ ['Acme\ContentBundle\Entity\Content:12', 'Acme\ContentBundle\Entity\Content', 12], diff --git a/tests/Unit/Doctrine/Orm/RouteProviderTest.php b/tests/Unit/Doctrine/Orm/RouteProviderTest.php index 6bca02fd..9776a706 100644 --- a/tests/Unit/Doctrine/Orm/RouteProviderTest.php +++ b/tests/Unit/Doctrine/Orm/RouteProviderTest.php @@ -39,8 +39,7 @@ protected function setUp(): void $this->managerRegistryMock = $this->createMock(ManagerRegistry::class); $this->objectRepositoryMock = $this->getMockBuilder(EntityRepository::class) ->disableOriginalConstructor() - ->onlyMethods(['findOneBy', 'findBy']) - ->addMethods(['findByStaticPrefix']) + ->onlyMethods(['findOneBy', 'findBy', '__call']) ->getMock(); $this->candidatesMock = $this->createMock(CandidatesInterface::class); $this->candidatesMock @@ -88,8 +87,8 @@ public function testGetRouteCollectionForRequest(): void $this->objectRepositoryMock ->expects($this->once()) - ->method('findByStaticPrefix') - ->with($candidates, ['position' => 'ASC']) + ->method('__call') + ->with('findByStaticPrefix', [$candidates, ['position' => 'ASC']]) ->willReturn($objects) ; @@ -111,7 +110,7 @@ public function testGetRouteCollectionForRequestEmpty(): void $this->objectRepositoryMock ->expects($this->never()) - ->method('findByStaticPrefix') + ->method('__call') ; $routeProvider = new RouteProvider($this->managerRegistryMock, $this->candidatesMock, 'Route'); @@ -187,9 +186,24 @@ public function testGetRoutesByNames(): void $candidatesMock = $this->createMock(CandidatesInterface::class); $candidatesMock + ->expects($this->exactly(3)) ->method('isCandidate') - ->withConsecutive([$paths[0]], [$paths[1]], [$paths[2]]) - ->willReturnOnConsecutiveCalls(true, true, false) + ->willReturnCallback(function (string $path) use ($paths): bool { + static $expectedCalls = []; + + if ([] === $expectedCalls) { + $expectedCalls = [ + [$paths[0], true], + [$paths[1], true], + [$paths[2], false], + ]; + } + + [$expectedPath, $returnValue] = array_shift($expectedCalls); + $this->assertSame($expectedPath, $path); + + return $returnValue; + }) ; $routeProvider = new RouteProvider($this->managerRegistryMock, $candidatesMock, 'Route'); diff --git a/tests/Unit/Doctrine/Phpcr/RouteProviderTest.php b/tests/Unit/Doctrine/Phpcr/RouteProviderTest.php index 1142cadc..b7db977d 100644 --- a/tests/Unit/Doctrine/Phpcr/RouteProviderTest.php +++ b/tests/Unit/Doctrine/Phpcr/RouteProviderTest.php @@ -64,16 +64,11 @@ public function testGetRouteCollectionForRequest(): void ->willReturn($candidates) ; - $objects = new ArrayCollection([ - new Route('/my'), - $this, - ]); - $this->dmMock ->expects($this->once()) ->method('findMany') ->with(null, $candidates) - ->willReturn($objects) + ->willReturn([new Route('/my')]) ; $routeProvider = new RouteProvider($this->managerRegistryMock, $this->candidatesMock); @@ -290,10 +285,11 @@ public function testGetRoutesByNames(): void '/cms/routes/not-a-route', ]; - $routes = new ArrayCollection(); - $routes->set('/cms/routes/test-route', new Route('/test-route')); - $routes->set('/cms/simple/other-route', new Route('/other-route')); - $routes->set('/cms/routes/not-a-route', $this); + $routes = [ + '/cms/routes/test-route' => new Route('/test-route'), + '/cms/simple/other-route' => new Route('/other-route'), + '/cms/routes/not-a-route' => $this, + ]; $this->dmMock ->expects($this->once()) @@ -303,9 +299,21 @@ public function testGetRoutesByNames(): void ; $this->candidatesMock + ->expects($this->exactly(4)) ->method('isCandidate') - ->withConsecutive(['/cms/routes/test-route'], ['/cms/simple/other-route'], ['/cms/routes/not-a-route'], ['/outside/prefix']) - ->willReturnOnConsecutiveCalls(true, true, true, false) + ->willReturnCallback(function (string $path): bool { + static $expectedCalls = [ + ['/cms/routes/test-route', true], + ['/cms/simple/other-route', true], + ['/cms/routes/not-a-route', true], + ['/outside/prefix', false], + ]; + + [$expectedPath, $returnValue] = array_shift($expectedCalls); + $this->assertSame($expectedPath, $path); + + return $returnValue; + }) ; $paths[] = '/outside/prefix'; @@ -331,9 +339,19 @@ public function testGetRoutesByNamesNotCandidates(): void ; $this->candidatesMock + ->expects($this->exactly(3)) ->method('isCandidate') - ->withConsecutive(['/cms/routes/test-route'], ['/cms/simple/other-route'], ['/cms/routes/not-a-route']) - ->willReturn(false) + ->willReturnCallback(function (string $path): bool { + static $expectedCalls = [ + '/cms/routes/test-route', + '/cms/simple/other-route', + '/cms/routes/not-a-route', + ]; + + $this->assertSame(array_shift($expectedCalls), $path); + + return false; + }) ; $routeProvider = new RouteProvider($this->managerRegistryMock, $this->candidatesMock); @@ -355,9 +373,10 @@ public function testGetRoutesByNamesUuid(): void $route1 = new Route('/test-route'); $route2 = new Route('/other-route'); - $routes = new ArrayCollection(); - $routes->set($uuid1, $route1); - $routes->set($uuid2, $route2); + $routes = [ + $uuid1 => $route1, + $uuid2 => $route2, + ]; $this->dmMock ->expects($this->once()) @@ -373,15 +392,39 @@ public function testGetRoutesByNamesUuid(): void ->willReturn($uow) ; $uow + ->expects($this->exactly(2)) ->method('getDocumentId') - ->withConsecutive([$route1], [$route2]) - ->willReturnOnConsecutiveCalls('/cms/routes/test-route', '/cms/routes/other-route') + ->willReturnCallback(function ($route) use ($route1, $route2): string { + static $expectedCalls = []; + + if ([] === $expectedCalls) { + $expectedCalls = [ + [$route1, '/cms/routes/test-route'], + [$route2, '/cms/routes/other-route'], + ]; + } + + [$expectedRoute, $returnValue] = array_shift($expectedCalls); + $this->assertSame($expectedRoute, $route); + + return $returnValue; + }) ; $this->candidatesMock + ->expects($this->exactly(2)) ->method('isCandidate') - ->withConsecutive(['/cms/routes/test-route'], ['/cms/routes/other-route']) - ->willReturnOnConsecutiveCalls(true, false) + ->willReturnCallback(function (string $path): bool { + static $expectedCalls = [ + ['/cms/routes/test-route', true], + ['/cms/routes/other-route', false], + ]; + + [$expectedPath, $returnValue] = array_shift($expectedCalls); + $this->assertSame($expectedPath, $path); + + return $returnValue; + }) ; $routeProvider = new RouteProvider($this->managerRegistryMock, $this->candidatesMock); @@ -403,7 +446,7 @@ private function doRouteDump($limit): void $query ->expects($this->once()) ->method('getResult') - ->willReturn([]) + ->willReturn(new ArrayCollection([])) ; if ($limit) { $query diff --git a/tests/Unit/Routing/RedirectableRequestMatcherTest.php b/tests/Unit/Routing/RedirectableRequestMatcherTest.php index 39464670..63498771 100644 --- a/tests/Unit/Routing/RedirectableRequestMatcherTest.php +++ b/tests/Unit/Routing/RedirectableRequestMatcherTest.php @@ -51,16 +51,19 @@ public function testMatchRequest(): void public function testMatchRequestWithSlash(): void { $this->decoratedRequestMatcher + ->expects($this->exactly(2)) ->method('matchRequest') - ->withConsecutive([$this->callback(function (Request $request) { - return '/foo/' === $request->getPathInfo(); - })], [$this->callback(function (Request $request) { - return '/foo' === $request->getPathInfo(); - })]) - ->will($this->onConsecutiveCalls( - $this->throwException(new ResourceNotFoundException()), - $this->returnValue(['_route' => 'foobar']) - )); + ->willReturnCallback(function (Request $request): array { + static $expectedCalls = ['/foo/', '/foo']; + + $this->assertSame(array_shift($expectedCalls), $request->getPathInfo()); + + if ('/foo/' === $request->getPathInfo()) { + throw new ResourceNotFoundException(); + } + + return ['_route' => 'foobar']; + }); $parameters = $this->redirectableRequestMatcher->matchRequest($this->requestWithSlash); $this->assertSame('foobar', $parameters['_route']); diff --git a/tests/Unit/Validator/Constraints/RouteDefaultsTwigValidatorTest.php b/tests/Unit/Validator/Constraints/RouteDefaultsTwigValidatorTest.php index 779d85ac..129b820b 100644 --- a/tests/Unit/Validator/Constraints/RouteDefaultsTwigValidatorTest.php +++ b/tests/Unit/Validator/Constraints/RouteDefaultsTwigValidatorTest.php @@ -90,9 +90,11 @@ public function testTemplateViolation(): void ->willReturn(false) ; + $constraint = new RouteDefaults(); + $constraint->message = 'my message'; $this->validator->validate( ['_template' => 'NotExistingBundle:Foo:bar.html.twig'], - new RouteDefaults(['message' => 'my message']) + $constraint ); (new ConstraintViolationAssertion($this->context, 'my message', new NotNull()))