From 82236d57e667c3c9ecb44a5d817ba8c473b84d2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20Eugon=C3=A9?= Date: Wed, 7 Jan 2026 11:14:04 +0100 Subject: [PATCH 01/11] Rewrite test scripts to use symfony/console --- .led/scripts/tests | 110 ++++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 50 deletions(-) diff --git a/.led/scripts/tests b/.led/scripts/tests index 784e0e86..0be98b00 100755 --- a/.led/scripts/tests +++ b/.led/scripts/tests @@ -1,67 +1,77 @@ #!/usr/bin/env php setCode(function (InputInterface $input, OutputInterface $output) { + $return = 0; -$io = new SymfonyStyle(new ArrayInput([]), new ConsoleOutput()); + $action = Yaml::parseFile(__DIR__ . '/../../.github/actions/install/action.yml'); + $composer = \array_filter(\explode(\PHP_EOL, $action['runs']['steps'][1]['run'])); -$execute = function (array $job, string|null $php = null, string|null $symfony = null) use ($io, $composer) { - $io->section($job['name']); + $io = new SymfonyStyle($input, $output); - if ($php === null && $symfony === null) { - ['php-version' => $php, 'symfony-version' => $symfony] = $job['steps'][1]['with']; - } else { - $io->definitionList( - ['PHP' => $php], - ['Symfony' => $symfony], - ); - } + $execute = function (array $job, string|null $php = null, string|null $symfony = null) use ($io, $composer) { + $io->section($job['name']); - $process = function (string $command, bool $output) use ($io, $php) { - $container = 'php' . \str_replace('.', '', $php); - $command = "led in -s {$container} -- {$command}"; + if ($php === null && $symfony === null) { + ['php-version' => $php, 'symfony-version' => $symfony] = $job['steps'][1]['with']; + } else { + $io->definitionList( + ['PHP' => $php], + ['Symfony' => $symfony], + ); + } - $callback = null; - if ($output) { - $io->writeln($command); - $callback = function ($type, $buffer) { - echo $buffer; + $process = function (string $command, bool $output) use ($io, $php) { + $container = 'php' . \str_replace('.', '', $php); + $command = "led in -s {$container} -- {$command}"; + + $callback = null; + if ($output) { + $io->writeln($command); + $callback = function ($type, $buffer) { + echo $buffer; + }; + } + + Process::fromShellCommandline($command)->mustRun($callback); }; + + foreach ($composer as $command) { + $process(\str_replace('${{ inputs.symfony-version }}', $symfony, $command), false); + } + $process($job['steps'][2]['run'], true); + }; + + $tests = Yaml::parseFile(__DIR__ . '/../../.github/workflows/tests.yml'); + + try { + $execute($tests['jobs']['checkstyke']); + $execute($tests['jobs']['phpstan']); + $execute($tests['jobs']['conventions']); + + $phpunitTestingMatrix = $tests['jobs']['phpunit']['strategy']['matrix']['include']; + foreach ($phpunitTestingMatrix as ['php-version' => $php, 'symfony-version' => $symfony]) { + $execute($tests['jobs']['phpunit'], $php, $symfony); + } + } catch (\Throwable) { + $return = 1; + $io->error('An error occurred, abort tests.'); } - Process::fromShellCommandline($command)->mustRun($callback); - }; - - foreach ($composer as $command) { - $process(\str_replace('${{ inputs.symfony-version }}', $symfony, $command), false); - } - $process($job['steps'][2]['run'], true); -}; - -$tests = Yaml::parseFile(__DIR__ . '/../../.github/workflows/tests.yml'); - -try { - $execute($tests['jobs']['checkstyke']); - $execute($tests['jobs']['phpstan']); - $execute($tests['jobs']['conventions']); - - $phpunitTestingMatrix = $tests['jobs']['phpunit']['strategy']['matrix']['include']; - foreach ($phpunitTestingMatrix as ['php-version' => $php, 'symfony-version' => $symfony]) { - $execute($tests['jobs']['phpunit'], $php, $symfony); - } -} catch (\Throwable) { - $io->error('An error occurred, abort tests.'); -} - -$io->success('Revert changes made to composer.json'); -Process::fromShellCommandline('git restore composer.json')->mustRun(); -Process::fromShellCommandline('led in -- composer update')->mustRun(); + $io->success('Revert changes made to composer.json'); + Process::fromShellCommandline('git restore composer.json')->mustRun(); + Process::fromShellCommandline('led in -- composer update')->mustRun(); + + return $return; + }) + ->run(); From 527c5bd7ed0b8b4a101b9ac3d093905cae827514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20Eugon=C3=A9?= Date: Wed, 7 Jan 2026 11:14:20 +0100 Subject: [PATCH 02/11] Add Symfony 8.0 to testing matrix --- .github/workflows/tests.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 717a03b8..4dc72668 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -21,6 +21,8 @@ jobs: symfony-version: '7.4.*' - php-version: '8.4' symfony-version: '7.4.*' + - php-version: '8.4' + symfony-version: '8.0.*' steps: - name: "Checkout" uses: actions/checkout@v2 @@ -42,7 +44,7 @@ jobs: uses: ./.github/actions/install with: php-version: '8.4' - symfony-version: '7.4.*' + symfony-version: '8.0.*' - name: "Run static analyzis with phpstan/phpstan" run: vendor/bin/phpstan analyze @@ -56,7 +58,7 @@ jobs: uses: ./.github/actions/install with: php-version: '8.4' - symfony-version: '7.4.*' + symfony-version: '8.0.*' - name: "Run checkstyle with symplify/easy-coding-standard" run: vendor/bin/ecs @@ -70,7 +72,7 @@ jobs: uses: ./.github/actions/install with: php-version: '8.4' - symfony-version: '7.4.*' + symfony-version: '8.0.*' - name: "Run tests with phpunit/phpunit" run: vendor/bin/phpunit --testsuite=Convention @@ -85,7 +87,7 @@ jobs: uses: ./.github/actions/install with: php-version: '8.4' - symfony-version: '7.4.*' + symfony-version: '8.0.*' coverage-mode: 'xdebug' - name: "Run tests with phpunit/phpunit" run: | From 24697b7cd689052452ee50d39c767b8bf1344fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20Eugon=C3=A9?= Date: Wed, 7 Jan 2026 11:15:52 +0100 Subject: [PATCH 03/11] Allow Symfony 8.0 & Remove Doctrine <3 --- composer.json | 51 ++++++++++---------- src/batch-doctrine-dbal/composer.json | 4 +- src/batch-doctrine-orm/composer.json | 4 +- src/batch-doctrine-persistence/composer.json | 3 +- src/batch-openspout/composer.json | 2 +- src/batch-symfony-console/composer.json | 4 +- src/batch-symfony-framework/composer.json | 20 ++++---- src/batch-symfony-messenger/composer.json | 2 +- src/batch-symfony-serializer/composer.json | 2 +- src/batch-symfony-uid/composer.json | 2 +- src/batch-symfony-validator/composer.json | 2 +- src/batch/composer.json | 2 +- 12 files changed, 48 insertions(+), 50 deletions(-) diff --git a/composer.json b/composer.json index 5545b56b..28a16c0e 100644 --- a/composer.json +++ b/composer.json @@ -14,44 +14,43 @@ "php": "^8.1", "ext-json": "*", "composer-runtime-api": "^2.0", - "doctrine/dbal": "^2.11|^3.0", - "doctrine/orm": "^2.8", - "doctrine/persistence": "^2.0|^3.0", + "doctrine/dbal": "^4.0", + "doctrine/orm": "^3.0", + "doctrine/persistence": "^4.0", "league/flysystem": "^3.0", "openspout/openspout": "^4.0", "psr/container": "^1.0", "psr/event-dispatcher": "^1.0", - "psr/log": "^1.0|^2.0|^3.0", - "symfony/config": "^6.4|^7.0", - "symfony/console": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/form": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/framework-bundle": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/serializer": "^6.4|^7.0", - "symfony/uid": "^6.4|^7.0", - "symfony/validator": "^6.4|^7.0" + "psr/log": "^3.0", + "symfony/config": "^6.4|^7.4|^8.0", + "symfony/console": "^6.4|^7.4|^8.0", + "symfony/dependency-injection": "^6.4|^7.4|^8.0", + "symfony/form": "^6.4|^7.4|^8.0", + "symfony/http-kernel": "^6.4|^7.4|^8.0", + "symfony/framework-bundle": "^6.4|^7.4|^8.0", + "symfony/messenger": "^6.4|^7.4|^8.0", + "symfony/serializer": "^6.4|^7.4|^8.0", + "symfony/uid": "^6.4|^7.4|^8.0", + "symfony/validator": "^6.4|^7.4|^8.0" }, "require-dev": { - "doctrine/annotations": "^1.14", - "doctrine/doctrine-bundle": "^2.5", + "doctrine/doctrine-bundle": "^2.0|^3.0", "league/flysystem-memory": "^3.0", "phpspec/prophecy-phpunit": "^2.0", "phpstan/phpstan": "^1.4", "phpunit/phpunit": "^9.5", "sonata-project/admin-bundle": "^4.0", - "symfony/browser-kit": "^6.4|^7.0", - "symfony/css-selector": "^6.4|^7.0", - "symfony/filesystem": "^6.4|^7.0", - "symfony/finder": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/security-bundle": "^6.4|^7.0", - "symfony/translation": "^6.4|^7.0", - "symfony/twig-bundle": "^6.4|^7.0", - "symfony/yaml": "^6.4|^7.0", + "symfony/browser-kit": "^6.4|^7.4|^8.0", + "symfony/css-selector": "^6.4|^7.4|^8.0", + "symfony/filesystem": "^6.4|^7.4|^8.0", + "symfony/finder": "^6.4|^7.4|^8.0", + "symfony/process": "^6.4|^7.4|^8.0", + "symfony/security-bundle": "^6.4|^7.4|^8.0", + "symfony/translation": "^6.4|^7.4|^8.0", + "symfony/twig-bundle": "^6.4|^7.4|^8.0", + "symfony/yaml": "^6.4|^7.4|^8.0", "symplify/easy-coding-standard": "^12.5", - "symfony/http-client": "^6.4|^7.0" + "symfony/http-client": "^6.4|^7.4|^8.0" }, "replace": { "yokai/batch": "self.version", diff --git a/src/batch-doctrine-dbal/composer.json b/src/batch-doctrine-dbal/composer.json index 5dcb838f..918c43a0 100644 --- a/src/batch-doctrine-dbal/composer.json +++ b/src/batch-doctrine-dbal/composer.json @@ -13,8 +13,8 @@ "require": { "php": "^8.1", "ext-json": "*", - "doctrine/dbal": "^2.11|^3.0", - "doctrine/persistence": "^2.0|^3.0", + "doctrine/dbal": "^4.0", + "doctrine/persistence": "^4.0", "yokai/batch": "^0.7.0" }, "autoload": { diff --git a/src/batch-doctrine-orm/composer.json b/src/batch-doctrine-orm/composer.json index 36abf3f6..73e76ac4 100644 --- a/src/batch-doctrine-orm/composer.json +++ b/src/batch-doctrine-orm/composer.json @@ -12,8 +12,8 @@ ], "require": { "php": "^8.1", - "doctrine/orm": "^2.8", - "doctrine/persistence": "^2.0|^3.0", + "doctrine/orm": "^3.0", + "doctrine/persistence": "^4.0", "yokai/batch": "^0.7.0" }, "autoload": { diff --git a/src/batch-doctrine-persistence/composer.json b/src/batch-doctrine-persistence/composer.json index 57f555f8..e610238b 100644 --- a/src/batch-doctrine-persistence/composer.json +++ b/src/batch-doctrine-persistence/composer.json @@ -12,7 +12,7 @@ ], "require": { "php": "^8.1", - "doctrine/persistence": "^2.0|^3.0", + "doctrine/persistence": "^4.0", "yokai/batch": "^0.7.0" }, "autoload": { @@ -21,7 +21,6 @@ } }, "require-dev": { - "doctrine/annotations": "^1.14", "phpunit/phpunit": "^9.5" }, "autoload-dev": { diff --git a/src/batch-openspout/composer.json b/src/batch-openspout/composer.json index 2c37c08c..e34d108f 100644 --- a/src/batch-openspout/composer.json +++ b/src/batch-openspout/composer.json @@ -22,7 +22,7 @@ }, "require-dev": { "phpunit/phpunit": "^9.5", - "symfony/filesystem": "^6.4|^7.0" + "symfony/filesystem": "^6.4|^7.4|^8.0" }, "autoload-dev": { "psr-4": { diff --git a/src/batch-symfony-console/composer.json b/src/batch-symfony-console/composer.json index 8d90068b..25eeb0e3 100644 --- a/src/batch-symfony-console/composer.json +++ b/src/batch-symfony-console/composer.json @@ -13,7 +13,7 @@ "require": { "php": "^8.1", "ext-json": "*", - "symfony/console": "^6.4|^7.0", + "symfony/console": "^6.4|^7.4|^8.0", "yokai/batch": "^0.7.0" }, "autoload": { @@ -24,7 +24,7 @@ "require-dev": { "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "symfony/process": "^6.4|^7.0" + "symfony/process": "^6.4|^7.4|^8.0" }, "autoload-dev": { "psr-4": { diff --git a/src/batch-symfony-framework/composer.json b/src/batch-symfony-framework/composer.json index 0be37f6b..475e24b7 100644 --- a/src/batch-symfony-framework/composer.json +++ b/src/batch-symfony-framework/composer.json @@ -13,11 +13,11 @@ "require": { "php": "^8.1", "composer-runtime-api": "^2.0", - "symfony/config": "^6.4|^7.0", - "symfony/console": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/framework-bundle": "^6.4|^7.0", + "symfony/config": "^6.4|^7.4|^8.0", + "symfony/console": "^6.4|^7.4|^8.0", + "symfony/dependency-injection": "^6.4|^7.4|^8.0", + "symfony/http-kernel": "^6.4|^7.4|^8.0", + "symfony/framework-bundle": "^6.4|^7.4|^8.0", "yokai/batch": "^0.7.0", "psr/log": "^1.0|^2.0|^3.0" }, @@ -28,11 +28,11 @@ }, "require-dev": { "sonata-project/admin-bundle": "^4.0", - "symfony/filesystem": "^6.4|^7.0", - "symfony/form": "^6.4|^7.0", - "symfony/security-bundle": "^6.4|^7.0", - "symfony/translation": "^6.4|^7.0", - "symfony/twig-bundle": "^6.4|^7.0", + "symfony/filesystem": "^6.4|^7.4|^8.0", + "symfony/form": "^6.4|^7.4|^8.0", + "symfony/security-bundle": "^6.4|^7.4|^8.0", + "symfony/translation": "^6.4|^7.4|^8.0", + "symfony/twig-bundle": "^6.4|^7.4|^8.0", "phpunit/phpunit": "^9.5" }, "suggest": { diff --git a/src/batch-symfony-messenger/composer.json b/src/batch-symfony-messenger/composer.json index dec8f992..7d3951ff 100644 --- a/src/batch-symfony-messenger/composer.json +++ b/src/batch-symfony-messenger/composer.json @@ -12,7 +12,7 @@ ], "require": { "php": "^8.1", - "symfony/messenger": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.4|^8.0", "yokai/batch": "^0.7.0" }, "autoload": { diff --git a/src/batch-symfony-serializer/composer.json b/src/batch-symfony-serializer/composer.json index fc430c42..d7d6a735 100644 --- a/src/batch-symfony-serializer/composer.json +++ b/src/batch-symfony-serializer/composer.json @@ -12,7 +12,7 @@ ], "require": { "php": "^8.1", - "symfony/serializer": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.4|^8.0", "yokai/batch": "^0.7.0" }, "autoload": { diff --git a/src/batch-symfony-uid/composer.json b/src/batch-symfony-uid/composer.json index 1d4cc916..8faf1eba 100644 --- a/src/batch-symfony-uid/composer.json +++ b/src/batch-symfony-uid/composer.json @@ -12,7 +12,7 @@ ], "require": { "php": "^8.1", - "symfony/uid": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.4|^8.0", "yokai/batch": "^0.7.0" }, "autoload": { diff --git a/src/batch-symfony-validator/composer.json b/src/batch-symfony-validator/composer.json index 6272bc08..fde77431 100644 --- a/src/batch-symfony-validator/composer.json +++ b/src/batch-symfony-validator/composer.json @@ -12,7 +12,7 @@ ], "require": { "php": "^8.1", - "symfony/validator": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.4|^8.0", "yokai/batch": "^0.7.0" }, "autoload": { diff --git a/src/batch/composer.json b/src/batch/composer.json index a0dcc1ee..bb70353f 100644 --- a/src/batch/composer.json +++ b/src/batch/composer.json @@ -24,7 +24,7 @@ "require-dev": { "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "symfony/filesystem": "^6.4|^7.0" + "symfony/filesystem": "^6.4|^7.4|^8.0" }, "autoload-dev": { "psr-4": { From 5cf63df08f3b8d02a622f3d23aa885cbe42aa048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20Eugon=C3=A9?= Date: Wed, 7 Jan 2026 11:17:09 +0100 Subject: [PATCH 04/11] Convert Bundle XML configuration to PHP --- ecs.php | 3 ++ .../CompilerPass/RegisterJobsCompilerPass.php | 7 +-- .../src/DependencyInjection/Configuration.php | 6 ++- .../JobLauncherDefinitionFactory.php | 11 +++-- .../YokaiBatchExtension.php | 41 +++++++--------- .../src/Resources/routing/ui.php | 27 +++++++++++ .../src/Resources/routing/ui.xml | 23 --------- .../src/Resources/services/core.php | 48 +++++++++++++++++++ .../src/Resources/services/doctrine-orm.php | 24 ++++++++++ .../Resources/services/doctrine/orm/item.xml | 15 ------ .../src/Resources/services/global/alias.xml | 25 ---------- .../src/Resources/services/global/core.xml | 39 --------------- .../src/Resources/services/global/logger.xml | 16 ------- .../Resources/services/global/processor.xml | 15 ------ .../Resources/services/global/serializer.xml | 13 ----- .../src/Resources/services/logger.php | 22 +++++++++ .../Resources/services/symfony-console.php | 29 +++++++++++ .../Resources/services/symfony-messenger.php | 21 ++++++++ .../Resources/services/symfony-serializer.php | 18 +++++++ .../Resources/services/symfony-validator.php | 18 +++++++ .../services/symfony/console/command.xml | 23 --------- .../services/symfony/messenger/message.xml | 17 ------- .../services/symfony/serializer/item.xml | 15 ------ .../services/symfony/validator/item.xml | 15 ------ .../src/Resources/services/ui.php | 44 +++++++++++++++++ .../src/Resources/services/ui.xml | 34 ------------- .../RegisterJobsCompilerPassTest.php | 4 +- .../Controller/JobControllerTest.php | 4 +- tests/convention/Autoload.php | 5 ++ 29 files changed, 295 insertions(+), 287 deletions(-) create mode 100644 src/batch-symfony-framework/src/Resources/routing/ui.php delete mode 100644 src/batch-symfony-framework/src/Resources/routing/ui.xml create mode 100644 src/batch-symfony-framework/src/Resources/services/core.php create mode 100644 src/batch-symfony-framework/src/Resources/services/doctrine-orm.php delete mode 100644 src/batch-symfony-framework/src/Resources/services/doctrine/orm/item.xml delete mode 100644 src/batch-symfony-framework/src/Resources/services/global/alias.xml delete mode 100644 src/batch-symfony-framework/src/Resources/services/global/core.xml delete mode 100644 src/batch-symfony-framework/src/Resources/services/global/logger.xml delete mode 100644 src/batch-symfony-framework/src/Resources/services/global/processor.xml delete mode 100644 src/batch-symfony-framework/src/Resources/services/global/serializer.xml create mode 100644 src/batch-symfony-framework/src/Resources/services/logger.php create mode 100644 src/batch-symfony-framework/src/Resources/services/symfony-console.php create mode 100644 src/batch-symfony-framework/src/Resources/services/symfony-messenger.php create mode 100644 src/batch-symfony-framework/src/Resources/services/symfony-serializer.php create mode 100644 src/batch-symfony-framework/src/Resources/services/symfony-validator.php delete mode 100644 src/batch-symfony-framework/src/Resources/services/symfony/console/command.xml delete mode 100644 src/batch-symfony-framework/src/Resources/services/symfony/messenger/message.xml delete mode 100644 src/batch-symfony-framework/src/Resources/services/symfony/serializer/item.xml delete mode 100644 src/batch-symfony-framework/src/Resources/services/symfony/validator/item.xml create mode 100644 src/batch-symfony-framework/src/Resources/services/ui.php delete mode 100644 src/batch-symfony-framework/src/Resources/services/ui.xml diff --git a/ecs.php b/ecs.php index 3216af61..f774cd1e 100644 --- a/ecs.php +++ b/ecs.php @@ -77,5 +77,8 @@ ArrayOpenerAndCloserNewlineFixer::class, ExplicitStringVariableFixer::class, StandaloneLineInMultilineArrayFixer::class, + NativeFunctionInvocationFixer::class => [ + 'src/batch-symfony-framework/src/Resources/*', + ], ]) ; diff --git a/src/batch-symfony-framework/src/DependencyInjection/CompilerPass/RegisterJobsCompilerPass.php b/src/batch-symfony-framework/src/DependencyInjection/CompilerPass/RegisterJobsCompilerPass.php index 81157275..e3711361 100644 --- a/src/batch-symfony-framework/src/DependencyInjection/CompilerPass/RegisterJobsCompilerPass.php +++ b/src/batch-symfony-framework/src/DependencyInjection/CompilerPass/RegisterJobsCompilerPass.php @@ -10,6 +10,7 @@ use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; use Yokai\Batch\Bridge\Symfony\Framework\JobWithStaticNameInterface; +use Yokai\Batch\Bridge\Symfony\Framework\UserInterface\Form\JobFilterType; use Yokai\Batch\Job\JobInterface; use Yokai\Batch\Registry\JobRegistry; @@ -28,11 +29,11 @@ public function process(ContainerBuilder $container): void } } - $container->getDefinition('yokai_batch.job_registry') + $container->getDefinition(JobRegistry::class) ->setArgument('$jobs', ServiceLocatorTagPass::register($container, $jobs)); - if ($container->hasDefinition('yokai_batch.ui.filter_form')) { - $container->getDefinition('yokai_batch.ui.filter_form') + if ($container->hasDefinition(JobFilterType::class)) { + $container->getDefinition(JobFilterType::class) ->setArgument('$jobs', \array_keys($jobs)); } } diff --git a/src/batch-symfony-framework/src/DependencyInjection/Configuration.php b/src/batch-symfony-framework/src/DependencyInjection/Configuration.php index 0944def9..771bd4b8 100644 --- a/src/batch-symfony-framework/src/DependencyInjection/Configuration.php +++ b/src/batch-symfony-framework/src/DependencyInjection/Configuration.php @@ -8,6 +8,8 @@ use Symfony\Component\Config\Definition\Builder\NodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; +use Yokai\Batch\Bridge\Symfony\Framework\UserInterface\Templating\SonataAdminTemplating; +use Yokai\Batch\Serializer\JsonJobExecutionSerializer; /** * Configuration for yokai/batch Symfony Bundle. @@ -94,7 +96,7 @@ private function storage(): ArrayNodeDefinition ->defaultValue('%kernel.project_dir%/var/batch') ->end() ->scalarNode('serializer') - ->defaultValue('yokai_batch.job_execution_serializer.json') + ->defaultValue(JsonJobExecutionSerializer::class) ->end() ->end() ->end() @@ -234,7 +236,7 @@ private function ui(): ArrayNodeDefinition if (\is_string($value)) { $value = match ($value) { 'bootstrap4' => ['prefix' => '@YokaiBatch/bootstrap4', 'service' => null], - 'sonata' => ['service' => 'yokai_batch.ui.sonata_templating', 'prefix' => null], + 'sonata' => ['service' => SonataAdminTemplating::class, 'prefix' => null], default => throw new \InvalidArgumentException( \sprintf('Unknown templating shortcut "%s".', $value), ), diff --git a/src/batch-symfony-framework/src/DependencyInjection/JobLauncherDefinitionFactory.php b/src/batch-symfony-framework/src/DependencyInjection/JobLauncherDefinitionFactory.php index f023c702..af557c12 100644 --- a/src/batch-symfony-framework/src/DependencyInjection/JobLauncherDefinitionFactory.php +++ b/src/batch-symfony-framework/src/DependencyInjection/JobLauncherDefinitionFactory.php @@ -14,6 +14,9 @@ use Yokai\Batch\Bridge\Symfony\Console\RunCommandJobLauncher; use Yokai\Batch\Bridge\Symfony\Messenger\DispatchMessageJobLauncher; use Yokai\Batch\Bridge\Symfony\Messenger\MessengerJobsConfiguration; +use Yokai\Batch\Factory\JobExecutionFactory; +use Yokai\Batch\Job\JobExecutionAccessor; +use Yokai\Batch\Job\JobExecutor; use Yokai\Batch\Launcher\JobLauncherInterface; use Yokai\Batch\Launcher\RoutingJobLauncher; use Yokai\Batch\Launcher\SimpleJobLauncher; @@ -65,8 +68,8 @@ public static function routing( private static function simple(): Definition { return new Definition(SimpleJobLauncher::class, [ - '$jobExecutionAccessor' => new Reference('yokai_batch.job_execution_accessor'), - '$jobExecutor' => new Reference('yokai_batch.job_executor'), + '$jobExecutionAccessor' => new Reference(JobExecutionAccessor::class), + '$jobExecutor' => new Reference(JobExecutor::class), ]); } @@ -78,7 +81,7 @@ private static function console(array $config): Definition $log = $config['log'] ?? 'batch_execute.log'; return new Definition(RunCommandJobLauncher::class, [ - '$jobExecutionFactory' => new Reference('yokai_batch.job_execution_factory'), + '$jobExecutionFactory' => new Reference(JobExecutionFactory::class), '$commandRunner' => new Definition(CommandRunner::class, [ '$binDir' => '%kernel.project_dir%/bin', '$logDir' => '%kernel.logs_dir%', @@ -91,7 +94,7 @@ private static function console(array $config): Definition private static function messenger(): Definition { return new Definition(DispatchMessageJobLauncher::class, [ - '$jobExecutionFactory' => new Reference('yokai_batch.job_execution_factory'), + '$jobExecutionFactory' => new Reference(JobExecutionFactory::class), '$jobExecutionStorage' => new Reference(JobExecutionStorageInterface::class), '$messageBus' => new Reference(MessageBusInterface::class), '$messengerJobsConfiguration' => new Definition(MessengerJobsConfiguration::class, [ diff --git a/src/batch-symfony-framework/src/DependencyInjection/YokaiBatchExtension.php b/src/batch-symfony-framework/src/DependencyInjection/YokaiBatchExtension.php index 5b460547..d28a1dd1 100644 --- a/src/batch-symfony-framework/src/DependencyInjection/YokaiBatchExtension.php +++ b/src/batch-symfony-framework/src/DependencyInjection/YokaiBatchExtension.php @@ -26,6 +26,7 @@ use Yokai\Batch\Factory\JobExecutionParametersBuilder\PerJobJobExecutionParametersBuilder; use Yokai\Batch\Factory\JobExecutionParametersBuilder\StaticJobExecutionParametersBuilder; use Yokai\Batch\Launcher\JobLauncherInterface; +use Yokai\Batch\Logger\BatchLogger; use Yokai\Batch\Storage\FilesystemJobExecutionStorage; use Yokai\Batch\Storage\JobExecutionStorageInterface; @@ -50,16 +51,15 @@ public function load(array $configs, ContainerBuilder $container): void $config = $this->processConfiguration($configuration, $configs); $loader = $this->getLoader($container); - $loader->load('global/'); - $bridges = [ - 'doctrine/orm/' => $this->installed('doctrine-orm'), - 'symfony/console/' => $this->installed('symfony-console'), - 'symfony/messenger/' => $this->installed('symfony-messenger'), - 'symfony/serializer/' => $this->installed('symfony-serializer'), - 'symfony/validator/' => $this->installed('symfony-validator'), + 'core.php' => true, + 'doctrine-orm.php' => $this->installed('doctrine-orm'), + 'logger.php' => true, + 'symfony-console.php' => $this->installed('symfony-console'), + 'symfony-messenger.php' => $this->installed('symfony-messenger'), + 'symfony-serializer.php' => $this->installed('symfony-serializer'), + 'symfony-validator.php' => $this->installed('symfony-validator'), ]; - foreach (\array_keys(\array_filter($bridges)) as $resource) { $loader->load($resource); } @@ -72,7 +72,7 @@ public function load(array $configs, ContainerBuilder $container): void $jobExecutionIdGeneratorDefinition = JobExecutionIdGeneratorDefinitionFactory::fromType($config['id']); $container->setDefinition(JobExecutionIdGeneratorInterface::class, $jobExecutionIdGeneratorDefinition); - $container->registerAliasForArgument('yokai_batch.logger', LoggerInterface::class, 'yokaiBatchLogger'); + $container->registerAliasForArgument(BatchLogger::class, LoggerInterface::class, 'yokaiBatchLogger'); } private function installed(string $package): bool @@ -84,12 +84,9 @@ private function installed(string $package): bool private function getLoader(ContainerBuilder $container): LoaderInterface { $locator = new FileLocator(__DIR__ . '/../Resources/services'); - $resolver = new ConfigLoader\LoaderResolver( - [ - new DependencyInjectionLoader\XmlFileLoader($container, $locator), - new DependencyInjectionLoader\DirectoryLoader($container, $locator), - ], - ); + $resolver = new ConfigLoader\LoaderResolver([ + new DependencyInjectionLoader\PhpFileLoader($container, $locator), + ]); return new ConfigLoader\DelegatingLoader($resolver); } @@ -103,7 +100,7 @@ private function configureStorage(ContainerBuilder $container, array $config): v $defaultStorage = $config['service']; } elseif (isset($config['dbal'])) { $container - ->register('yokai_batch.storage.dbal', DoctrineDBALJobExecutionStorage::class) + ->register($defaultStorage = DoctrineDBALJobExecutionStorage::class) ->setArguments( [ new Reference('doctrine'), @@ -114,15 +111,11 @@ private function configureStorage(ContainerBuilder $container, array $config): v ], ) ; - - $defaultStorage = 'yokai_batch.storage.dbal'; } else { $container - ->register('yokai_batch.storage.filesystem', FilesystemJobExecutionStorage::class) + ->register($defaultStorage = FilesystemJobExecutionStorage::class) ->setArguments([new Reference($config['filesystem']['serializer']), $config['filesystem']['dir']]) ; - - $defaultStorage = 'yokai_batch.storage.filesystem'; } $container @@ -203,14 +196,14 @@ private function configureUserInterface(ContainerBuilder $container, LoaderInter return; } - $loader->load('ui.xml'); + $loader->load('ui.php'); if (\class_exists(AbstractType::class)) { - $container->register('yokai_batch.ui.filter_form', JobFilterType::class) + $container->register(JobFilterType::class) ->addTag('form.type'); } if (\interface_exists(TemplateRegistryInterface::class)) { - $container->register('yokai_batch.ui.sonata_templating', SonataAdminTemplating::class) + $container->register(SonataAdminTemplating::class) ->addArgument(new Reference('sonata.admin.global_template_registry')); } diff --git a/src/batch-symfony-framework/src/Resources/routing/ui.php b/src/batch-symfony-framework/src/Resources/routing/ui.php new file mode 100644 index 00000000..c5a350f8 --- /dev/null +++ b/src/batch-symfony-framework/src/Resources/routing/ui.php @@ -0,0 +1,27 @@ +add('yokai_batch.job_list', '/jobs') + ->controller([JobController::class, 'list']) + ->methods(['GET']) + ; + $routes->add('yokai_batch.job_view', '/jobs/{job}/{id}') + ->controller([JobController::class, 'view']) + ->methods(['GET']) + ; + $routes->add('yokai_batch.job_view_child', '/jobs/{job}/{id}/child/{path}') + ->controller([JobController::class, 'view']) + ->methods(['GET']) + ; + $routes->add('yokai_batch.job_logs', '/jobs/{job}/{id}/logs') + ->controller([JobController::class, 'logs']) + ->methods(['GET']) + ; +}; diff --git a/src/batch-symfony-framework/src/Resources/routing/ui.xml b/src/batch-symfony-framework/src/Resources/routing/ui.xml deleted file mode 100644 index 2d2f14d9..00000000 --- a/src/batch-symfony-framework/src/Resources/routing/ui.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - yokai_batch.ui.controller::list - - - - yokai_batch.ui.controller::view - - - - yokai_batch.ui.controller::view - - - - yokai_batch.ui.controller::logs - - - diff --git a/src/batch-symfony-framework/src/Resources/services/core.php b/src/batch-symfony-framework/src/Resources/services/core.php new file mode 100644 index 00000000..23ad8b61 --- /dev/null +++ b/src/batch-symfony-framework/src/Resources/services/core.php @@ -0,0 +1,48 @@ +services() + + ->set(JobRegistry::class) + ->set(JsonJobExecutionSerializer::class) + + ->set(JobExecutionFactory::class) + ->args([ + service(JobExecutionIdGeneratorInterface::class), + service(JobExecutionParametersBuilderInterface::class), + ]) + + ->set(JobExecutionAccessor::class) + ->args([ + service(JobExecutionFactory::class), + service(JobExecutionStorageInterface::class), + ]) + + ->set(JobExecutor::class) + ->args([ + service(JobRegistry::class), + service(JobExecutionStorageInterface::class), + service(EventDispatcherInterface::class)->nullOnInvalid(), + ]) + + ->set(JobExecutionParametersBuilderInterface::class, ChainJobExecutionParametersBuilder::class) + ->args([ + tagged_iterator('yokai_batch.job_execution_parameters_builder'), + ]) + ; +}; diff --git a/src/batch-symfony-framework/src/Resources/services/doctrine-orm.php b/src/batch-symfony-framework/src/Resources/services/doctrine-orm.php new file mode 100644 index 00000000..f7bf3395 --- /dev/null +++ b/src/batch-symfony-framework/src/Resources/services/doctrine-orm.php @@ -0,0 +1,24 @@ +services() + + ->set(ObjectWriter::class) + ->args([ + service(ManagerRegistry::class), + ]) + + ->set(ObjectRegistry::class) + ->args([ + service(ManagerRegistry::class), + ]) + ; +}; diff --git a/src/batch-symfony-framework/src/Resources/services/doctrine/orm/item.xml b/src/batch-symfony-framework/src/Resources/services/doctrine/orm/item.xml deleted file mode 100644 index e3db7be1..00000000 --- a/src/batch-symfony-framework/src/Resources/services/doctrine/orm/item.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - diff --git a/src/batch-symfony-framework/src/Resources/services/global/alias.xml b/src/batch-symfony-framework/src/Resources/services/global/alias.xml deleted file mode 100644 index a4dda2d8..00000000 --- a/src/batch-symfony-framework/src/Resources/services/global/alias.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/src/batch-symfony-framework/src/Resources/services/global/core.xml b/src/batch-symfony-framework/src/Resources/services/global/core.xml deleted file mode 100644 index 3649821b..00000000 --- a/src/batch-symfony-framework/src/Resources/services/global/core.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/batch-symfony-framework/src/Resources/services/global/logger.xml b/src/batch-symfony-framework/src/Resources/services/global/logger.xml deleted file mode 100644 index c15d5235..00000000 --- a/src/batch-symfony-framework/src/Resources/services/global/logger.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/batch-symfony-framework/src/Resources/services/global/processor.xml b/src/batch-symfony-framework/src/Resources/services/global/processor.xml deleted file mode 100644 index 1684dd6d..00000000 --- a/src/batch-symfony-framework/src/Resources/services/global/processor.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - diff --git a/src/batch-symfony-framework/src/Resources/services/global/serializer.xml b/src/batch-symfony-framework/src/Resources/services/global/serializer.xml deleted file mode 100644 index 42d7976f..00000000 --- a/src/batch-symfony-framework/src/Resources/services/global/serializer.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - diff --git a/src/batch-symfony-framework/src/Resources/services/logger.php b/src/batch-symfony-framework/src/Resources/services/logger.php new file mode 100644 index 00000000..17bfc71f --- /dev/null +++ b/src/batch-symfony-framework/src/Resources/services/logger.php @@ -0,0 +1,22 @@ +services() + + ->set(BatchLogger::class) + ->args([ + service(ManagerRegistry::class), + ]) + ->tag('kernel.event_listener', ['event' => PreExecuteEvent::class, 'method' => 'onPreExecute']) + ->tag('kernel.event_listener', ['event' => PostExecuteEvent::class, 'method' => 'onPostExecute']) + ; +}; diff --git a/src/batch-symfony-framework/src/Resources/services/symfony-console.php b/src/batch-symfony-framework/src/Resources/services/symfony-console.php new file mode 100644 index 00000000..62ed67ec --- /dev/null +++ b/src/batch-symfony-framework/src/Resources/services/symfony-console.php @@ -0,0 +1,29 @@ +services() + + ->set(RunJobCommand::class) + ->args([ + service(JobExecutionAccessor::class), + service(JobExecutor::class), + ]) + ->tag('console.command') + + ->set(SetupStorageCommand::class) + ->args([ + service(JobExecutionStorageInterface::class), + ]) + ->tag('console.command') + ; +}; diff --git a/src/batch-symfony-framework/src/Resources/services/symfony-messenger.php b/src/batch-symfony-framework/src/Resources/services/symfony-messenger.php new file mode 100644 index 00000000..5f4000b6 --- /dev/null +++ b/src/batch-symfony-framework/src/Resources/services/symfony-messenger.php @@ -0,0 +1,21 @@ +services() + + ->set(LaunchJobMessageHandler::class) + ->args([ + service(JobExecutionAccessor::class), + service(JobExecutor::class), + ]) + ->tag('messenger.message_handler') + ; +}; diff --git a/src/batch-symfony-framework/src/Resources/services/symfony-serializer.php b/src/batch-symfony-framework/src/Resources/services/symfony-serializer.php new file mode 100644 index 00000000..54348e1a --- /dev/null +++ b/src/batch-symfony-framework/src/Resources/services/symfony-serializer.php @@ -0,0 +1,18 @@ +services() + + ->set(NormalizeItemProcessor::class) + ->args([ + service(SerializerInterface::class), + ]) + ; +}; diff --git a/src/batch-symfony-framework/src/Resources/services/symfony-validator.php b/src/batch-symfony-framework/src/Resources/services/symfony-validator.php new file mode 100644 index 00000000..be3a61ce --- /dev/null +++ b/src/batch-symfony-framework/src/Resources/services/symfony-validator.php @@ -0,0 +1,18 @@ +services() + + ->set(SkipInvalidItemProcessor::class) + ->args([ + service(ValidatorInterface::class), + ]) + ; +}; diff --git a/src/batch-symfony-framework/src/Resources/services/symfony/console/command.xml b/src/batch-symfony-framework/src/Resources/services/symfony/console/command.xml deleted file mode 100644 index fe2c52eb..00000000 --- a/src/batch-symfony-framework/src/Resources/services/symfony/console/command.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/src/batch-symfony-framework/src/Resources/services/symfony/messenger/message.xml b/src/batch-symfony-framework/src/Resources/services/symfony/messenger/message.xml deleted file mode 100644 index 57fbcdaf..00000000 --- a/src/batch-symfony-framework/src/Resources/services/symfony/messenger/message.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/batch-symfony-framework/src/Resources/services/symfony/serializer/item.xml b/src/batch-symfony-framework/src/Resources/services/symfony/serializer/item.xml deleted file mode 100644 index 27988cb4..00000000 --- a/src/batch-symfony-framework/src/Resources/services/symfony/serializer/item.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - diff --git a/src/batch-symfony-framework/src/Resources/services/symfony/validator/item.xml b/src/batch-symfony-framework/src/Resources/services/symfony/validator/item.xml deleted file mode 100644 index a6126ac7..00000000 --- a/src/batch-symfony-framework/src/Resources/services/symfony/validator/item.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - diff --git a/src/batch-symfony-framework/src/Resources/services/ui.php b/src/batch-symfony-framework/src/Resources/services/ui.php new file mode 100644 index 00000000..c23c5bf2 --- /dev/null +++ b/src/batch-symfony-framework/src/Resources/services/ui.php @@ -0,0 +1,44 @@ +services() + + ->set(JobController::class) + ->args([ + service(JobExecutionStorageInterface::class), + service(FormFactoryInterface::class)->nullOnInvalid(), + service(JobSecurity::class), + service(Environment::class), + service(TemplatingInterface::class), + ]) + ->tag('controller.service_arguments') + + ->set(JobSecurity::class) + ->args([ + service(AuthorizationCheckerInterface::class)->nullOnInvalid(), + param('yokai_batch.ui.security_list_attribute'), + param('yokai_batch.ui.security_view_attribute'), + param('yokai_batch.ui.security_traces_attribute'), + param('yokai_batch.ui.security_logs_attribute'), + ]) + + ->set(TwigExtension::class) + ->args([ + service(JobSecurity::class), + ]) + ->tag('twig.extension') + ; +}; diff --git a/src/batch-symfony-framework/src/Resources/services/ui.xml b/src/batch-symfony-framework/src/Resources/services/ui.xml deleted file mode 100644 index 7e6502a9..00000000 --- a/src/batch-symfony-framework/src/Resources/services/ui.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - %yokai_batch.ui.security_list_attribute% - %yokai_batch.ui.security_view_attribute% - %yokai_batch.ui.security_traces_attribute% - %yokai_batch.ui.security_logs_attribute% - - - - - - - - diff --git a/src/batch-symfony-framework/tests/DependencyInjection/CompilerPass/RegisterJobsCompilerPassTest.php b/src/batch-symfony-framework/tests/DependencyInjection/CompilerPass/RegisterJobsCompilerPassTest.php index 9a937bae..9123b24d 100644 --- a/src/batch-symfony-framework/tests/DependencyInjection/CompilerPass/RegisterJobsCompilerPassTest.php +++ b/src/batch-symfony-framework/tests/DependencyInjection/CompilerPass/RegisterJobsCompilerPassTest.php @@ -18,7 +18,7 @@ final class RegisterJobsCompilerPassTest extends TestCase public function testProcess(): void { $container = new ContainerBuilder(); - $container->register('yokai_batch.job_registry', JobRegistry::class) + $container->register(JobRegistry::class) ->setPublic(true); $container->register(DummyJobWithName::class, DummyJobWithName::class) @@ -42,7 +42,7 @@ public function testProcess(): void private function getJob(ContainerBuilder $container, string $name): JobInterface|null { /** @var JobRegistry $registry */ - $registry = $container->get('yokai_batch.job_registry'); + $registry = $container->get(JobRegistry::class); try { return $registry->get($name); diff --git a/src/batch-symfony-framework/tests/UserInterface/Controller/JobControllerTest.php b/src/batch-symfony-framework/tests/UserInterface/Controller/JobControllerTest.php index c1f2d8e3..fce0e9e1 100644 --- a/src/batch-symfony-framework/tests/UserInterface/Controller/JobControllerTest.php +++ b/src/batch-symfony-framework/tests/UserInterface/Controller/JobControllerTest.php @@ -24,7 +24,7 @@ use Symfony\Component\HttpFoundation\Test\Constraint as ResponseConstraint; use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\Routing\Generator\UrlGenerator; -use Symfony\Component\Routing\Loader\XmlFileLoader; +use Symfony\Component\Routing\Loader\PhpFileLoader; use Symfony\Component\Routing\RequestContext; use Symfony\Component\Security\Core\Authorization\AccessDecision; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; @@ -492,7 +492,7 @@ private function controller( $twig->addExtension( new RoutingExtension( new UrlGenerator( - (new XmlFileLoader(new FileLocator()))->load(__DIR__ . '/../../../src/Resources/routing/ui.xml'), + (new PhpFileLoader(new FileLocator()))->load(__DIR__ . '/../../../src/Resources/routing/ui.php'), new RequestContext(), ), ), diff --git a/tests/convention/Autoload.php b/tests/convention/Autoload.php index f90914a0..cabbb8f4 100644 --- a/tests/convention/Autoload.php +++ b/tests/convention/Autoload.php @@ -43,6 +43,11 @@ public static function listFiles(string $path): iterable $files = Finder::create()->files()->in($path)->name('*.php'); /** @var SplFileInfo $file */ foreach ($files as $file) { + $letter = \substr($file->getFilename(), 0, 1); + if ($letter !== \strtoupper($letter)) { + continue; // file end with .php but do not start with uppercase, probably not a class + } + yield $file->getRealpath(); } } From 11eeea363d1a1d8a3f0a08b3551125b59b20df41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20Eugon=C3=A9?= Date: Wed, 7 Jan 2026 11:19:31 +0100 Subject: [PATCH 05/11] Fixed Doctrine compatibility --- phpunit.xml | 2 +- .../src/DoctrineDBALJobExecutionStorage.php | 81 ++++++++++--------- .../tests/DoctrineDBALTestCase.php | 3 +- .../tests/Dummy/SingleConnectionRegistry.php | 8 +- .../tests/Dummy/SingleManagerRegistry.php | 11 +-- .../tests/EntityReaderTest.php | 11 ++- .../tests/DoctrinePersistenceTestCase.php | 17 ++-- .../Dummy/DecoratedRepositoryFactory.php | 8 +- ...edOnlyOnceWhenFoundRepositoryDecorator.php | 20 +++-- .../tests/Dummy/SimpleManagerRegistry.php | 18 +++-- .../tests/Entity/Shop/Product.php | 18 ++--- tests/integration/Entity/Badge.php | 14 ++-- tests/integration/Entity/Developer.php | 18 ++--- tests/integration/Entity/Repository.php | 14 ++-- .../ImportDevelopersXlsxToORMTest.php | 11 ++- tests/symfony/src/Kernel.php | 7 +- tests/symfony/tests/JobTest.php | 10 ++- 17 files changed, 149 insertions(+), 122 deletions(-) diff --git a/phpunit.xml b/phpunit.xml index 79c1b9ca..7331c64d 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -9,7 +9,7 @@ > - + diff --git a/src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php b/src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php index 0632180b..5b97d14b 100644 --- a/src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php +++ b/src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php @@ -4,12 +4,17 @@ namespace Yokai\Batch\Bridge\Doctrine\DBAL; +use Doctrine\DBAL\ArrayParameterType; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Driver\Result; use Doctrine\DBAL\Exception as DBALException; use Doctrine\DBAL\Query\QueryBuilder; use Doctrine\DBAL\Schema\AbstractAsset; -use Doctrine\DBAL\Schema\Comparator; +use Doctrine\DBAL\Schema\Name; +use Doctrine\DBAL\Schema\Name\Identifier; +use Doctrine\DBAL\Schema\Name\UnqualifiedName; +use Doctrine\DBAL\Schema\NamedObject; +use Doctrine\DBAL\Schema\PrimaryKeyConstraint; use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Types\Types; use Doctrine\Persistence\ConnectionRegistry; @@ -61,38 +66,23 @@ public function __construct(ConnectionRegistry $doctrine, array $options) */ public function setup(): void { - $assetFilter = $this->connection->getConfiguration()->getSchemaAssetsFilter() - ?? fn() => true; + $assetFilter = $this->connection->getConfiguration()->getSchemaAssetsFilter(); $this->connection->getConfiguration()->setSchemaAssetsFilter(function (string|AbstractAsset $table) { - $table = $table instanceof AbstractAsset ? $table->getName() : $table; + $table = $table instanceof AbstractAsset ? $this->getAssetName($table) : $table; return $table === $this->table; }); - $schemaManager = \method_exists($this->connection, 'createSchemaManager') - ? $this->connection->createSchemaManager() - : $this->connection->getSchemaManager(); - $comparator = \method_exists($schemaManager, 'createComparator') - ? $schemaManager->createComparator() - : new Comparator(); - $fromSchema = \method_exists($schemaManager, 'introspectSchema') - ? $schemaManager->introspectSchema() - : $schemaManager->createSchema(); + $schemaManager = $this->connection->createSchemaManager(); + $comparator = $schemaManager->createComparator(); + $fromSchema = $schemaManager->introspectSchema(); $toSchema = $this->getSchema(); - $schemaDiff = \method_exists($comparator, 'compareSchemas') - ? $comparator->compareSchemas($fromSchema, $toSchema) - : $comparator->compare($fromSchema, $toSchema); + $schemaDiff = $comparator->compareSchemas($fromSchema, $toSchema); $platform = $this->connection->getDatabasePlatform(); - $schemaDiffQueries = \method_exists($platform, 'getAlterSchemaSQL') - ? $platform->getAlterSchemaSQL($schemaDiff) - : $schemaDiff->toSaveSql($platform); + $schemaDiffQueries = $platform->getAlterSchemaSQL($schemaDiff); foreach ($schemaDiffQueries as $sql) { - if (\method_exists($this->connection, 'executeStatement')) { - $this->connection->executeStatement($sql); - } else { - $this->connection->exec($sql); - } + $this->connection->executeStatement($sql); } $this->connection->getConfiguration()->setSchemaAssetsFilter($assetFilter); @@ -104,7 +94,7 @@ public function store(JobExecution $execution): void try { $this->fetchRow($execution->getJobName(), $execution->getId()); $stored = true; - } catch (RuntimeException $exception) { + } catch (RuntimeException) { $stored = false; } @@ -156,10 +146,6 @@ public function query(Query $query): iterable $qb->select('*') ->from($this->table); - /** - * @var array $queryParameters - * @var array $queryTypes - */ [$queryParameters, $queryTypes] = $this->addWheres($query, $qb); switch ($query->sort()) { @@ -192,10 +178,6 @@ public function count(Query $query): int $qb->select('count(*)') ->from($this->table); - /** - * @var array $queryParameters - * @var array $queryTypes - */ [$queryParameters, $queryTypes] = $this->addWheres($query, $qb); /** @var int $result */ @@ -223,7 +205,13 @@ private function getSchema(): Schema $table->addColumn('warnings', Types::JSON); $table->addColumn('child_executions', Types::JSON); $table->addColumn('logs', Types::TEXT); - $table->setPrimaryKey(['id']); + if (\method_exists($table, 'addPrimaryKeyConstraint')) { + $table->addPrimaryKeyConstraint( + new PrimaryKeyConstraint(null, [new UnqualifiedName(Identifier::unquoted('id'))], false), + ); + } else { + $table->setPrimaryKey(['id']); + } $table->addIndex(['job_name']); $table->addIndex(['status']); $table->addIndex(['start_time']); @@ -294,8 +282,8 @@ private function fetchRow(string $jobName, string $id): array } /** - * @param array $parameters - * @param array $types + * @param array $parameters + * @param array $types * * @return Generator */ @@ -335,7 +323,10 @@ private function getNormalizer(): JobExecutionRowNormalizer } /** - * @return array{array, array} + * @return array{ + * array, + * array, + * } */ private function addWheres(Query $query, QueryBuilder $qb): array { @@ -346,21 +337,21 @@ private function addWheres(Query $query, QueryBuilder $qb): array if (\count($names) > 0) { $qb->andWhere($qb->expr()->in('job_name', ':jobNames')); $queryParameters['jobNames'] = $names; - $queryTypes['jobNames'] = Connection::PARAM_STR_ARRAY; + $queryTypes['jobNames'] = ArrayParameterType::STRING; } $ids = $query->ids(); if (\count($ids) > 0) { $qb->andWhere($qb->expr()->in('id', ':ids')); $queryParameters['ids'] = $ids; - $queryTypes['ids'] = Connection::PARAM_STR_ARRAY; + $queryTypes['ids'] = ArrayParameterType::STRING; } $statuses = $query->statuses(); if (\count($statuses) > 0) { $qb->andWhere($qb->expr()->in('status', ':statuses')); $queryParameters['statuses'] = $statuses; - $queryTypes['statuses'] = Connection::PARAM_INT_ARRAY; + $queryTypes['statuses'] = ArrayParameterType::INTEGER; } if ($query->startTime()) { @@ -397,4 +388,14 @@ private function addWheres(Query $query, QueryBuilder $qb): array return [$queryParameters, $queryTypes]; } + + /** + * @param AbstractAsset $asset + */ + private function getAssetName(AbstractAsset $asset): string + { + return $asset instanceof NamedObject + ? $asset->getObjectName()->toString() + : $asset->getName(); + } } diff --git a/src/batch-doctrine-dbal/tests/DoctrineDBALTestCase.php b/src/batch-doctrine-dbal/tests/DoctrineDBALTestCase.php index 92acd3bc..77e01386 100644 --- a/src/batch-doctrine-dbal/tests/DoctrineDBALTestCase.php +++ b/src/batch-doctrine-dbal/tests/DoctrineDBALTestCase.php @@ -8,6 +8,7 @@ use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\Result; use Doctrine\DBAL\Schema\Table; +use Doctrine\DBAL\Tools\DsnParser; use Doctrine\Persistence\ConnectionRegistry; use PHPUnit\Framework\TestCase; use Yokai\Batch\Tests\Bridge\Doctrine\DBAL\Dummy\SingleConnectionRegistry; @@ -19,7 +20,7 @@ abstract class DoctrineDBALTestCase extends TestCase protected function setUp(): void { - $this->connection = DriverManager::getConnection(['url' => \getenv('DATABASE_URL')]); + $this->connection = DriverManager::getConnection((new DsnParser())->parse(\getenv('DATABASE_URL'))); $this->doctrine = new SingleConnectionRegistry($this->connection); } diff --git a/src/batch-doctrine-dbal/tests/Dummy/SingleConnectionRegistry.php b/src/batch-doctrine-dbal/tests/Dummy/SingleConnectionRegistry.php index 7cf45679..b0fdcdba 100644 --- a/src/batch-doctrine-dbal/tests/Dummy/SingleConnectionRegistry.php +++ b/src/batch-doctrine-dbal/tests/Dummy/SingleConnectionRegistry.php @@ -16,12 +16,12 @@ public function __construct( ) { } - public function getDefaultConnectionName() + public function getDefaultConnectionName(): string { return $this->name; } - public function getConnection($name = null) + public function getConnection(string|null $name = null): object { if ($name === $this->name) { return $this->connection; @@ -30,12 +30,12 @@ public function getConnection($name = null) throw new InvalidArgumentException(\sprintf('Doctrine Connection named "%s" does not exist.', $name)); } - public function getConnections() + public function getConnections(): array { return [$this->connection]; } - public function getConnectionNames() + public function getConnectionNames(): array { return [$this->name]; } diff --git a/src/batch-doctrine-orm/tests/Dummy/SingleManagerRegistry.php b/src/batch-doctrine-orm/tests/Dummy/SingleManagerRegistry.php index 4258c686..e13f4817 100644 --- a/src/batch-doctrine-orm/tests/Dummy/SingleManagerRegistry.php +++ b/src/batch-doctrine-orm/tests/Dummy/SingleManagerRegistry.php @@ -4,7 +4,7 @@ namespace Yokai\Batch\Tests\Bridge\Doctrine\ORM\Dummy; -use Doctrine\ORM\Proxy\Proxy; +use Doctrine\Persistence\Proxy; use Doctrine\Persistence\AbstractManagerRegistry; use Doctrine\Persistence\ObjectManager; @@ -16,7 +16,7 @@ public function __construct( parent::__construct('ORM', ['default'], ['default'], 'default', 'default', Proxy::class); } - protected function getService($name) + protected function getService(string $name): object { if ($name !== 'default') { throw new \InvalidArgumentException('Unknown service "' . $name . '".'); @@ -25,12 +25,7 @@ protected function getService($name) return $this->manager; } - protected function resetService($name) + protected function resetService(string $name): void { } - - public function getAliasNamespace($alias) - { - return $alias; - } } diff --git a/src/batch-doctrine-orm/tests/EntityReaderTest.php b/src/batch-doctrine-orm/tests/EntityReaderTest.php index 3c0dd94a..2052001e 100644 --- a/src/batch-doctrine-orm/tests/EntityReaderTest.php +++ b/src/batch-doctrine-orm/tests/EntityReaderTest.php @@ -4,6 +4,8 @@ namespace Yokai\Batch\Tests\Bridge\Doctrine\ORM; +use Doctrine\DBAL\DriverManager; +use Doctrine\DBAL\Tools\DsnParser; use Doctrine\ORM\EntityManager; use Doctrine\ORM\ORMSetup; use Doctrine\ORM\Tools\SchemaTool; @@ -24,7 +26,14 @@ class EntityReaderTest extends TestCase protected function setUp(): void { $config = ORMSetup::createAttributeMetadataConfiguration([__DIR__ . '/Entity'], true); - $this->manager = EntityManager::create(['url' => \getenv('DATABASE_URL')], $config); + if (\PHP_VERSION_ID >= 80400) { + $config->enableNativeLazyObjects(true); + } else { + $config->setProxyDir(\sys_get_temp_dir()); + $config->setProxyNamespace('DoctrineProxies'); + } + $connection = DriverManager::getConnection((new DsnParser())->parse(\getenv('DATABASE_URL'))); + $this->manager = new EntityManager($connection, $config); $this->doctrine = new SingleManagerRegistry($this->manager); (new SchemaTool($this->manager)) diff --git a/src/batch-doctrine-persistence/tests/DoctrinePersistenceTestCase.php b/src/batch-doctrine-persistence/tests/DoctrinePersistenceTestCase.php index b5ec66c3..d306cd43 100644 --- a/src/batch-doctrine-persistence/tests/DoctrinePersistenceTestCase.php +++ b/src/batch-doctrine-persistence/tests/DoctrinePersistenceTestCase.php @@ -5,6 +5,7 @@ namespace Yokai\Batch\Tests\Bridge\Doctrine\Persistence; use Doctrine\DBAL\DriverManager; +use Doctrine\DBAL\Tools\DsnParser; use Doctrine\ORM\Configuration; use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManagerInterface; @@ -22,15 +23,21 @@ abstract class DoctrinePersistenceTestCase extends TestCase protected function setUp(): void { - // It is important to have both attribute & annotation configurations because - // otherwise Doctrine do not seem to be able to find which manager is responsible - // to manage an entity or another. $authConfig = ORMSetup::createAttributeMetadataConfiguration([__DIR__ . '/Entity/Auth'], true); - $shopConfig = ORMSetup::createAnnotationMetadataConfiguration([__DIR__ . '/Entity/Shop'], true); + $shopConfig = ORMSetup::createAttributeMetadataConfiguration([__DIR__ . '/Entity/Shop'], true); + if (PHP_VERSION_ID >= 80400) { + $authConfig->enableNativeLazyObjects(true); + $shopConfig->enableNativeLazyObjects(true); + } else { + $authConfig->setProxyDir(\sys_get_temp_dir()); + $authConfig->setProxyNamespace('DoctrineProxies'); + $shopConfig->setProxyDir(\sys_get_temp_dir()); + $shopConfig->setProxyNamespace('DoctrineProxies'); + } $this->setUpConfigs($authConfig, $shopConfig); - $connection = DriverManager::getConnection(['url' => \getenv('DATABASE_URL')]); + $connection = DriverManager::getConnection((new DsnParser())->parse(\getenv('DATABASE_URL'))); $this->authManager = new EntityManager($connection, $authConfig); $this->shopManager = new EntityManager($connection, $shopConfig); diff --git a/src/batch-doctrine-persistence/tests/Dummy/DecoratedRepositoryFactory.php b/src/batch-doctrine-persistence/tests/Dummy/DecoratedRepositoryFactory.php index e2a5d1cb..b3044a08 100644 --- a/src/batch-doctrine-persistence/tests/Dummy/DecoratedRepositoryFactory.php +++ b/src/batch-doctrine-persistence/tests/Dummy/DecoratedRepositoryFactory.php @@ -5,26 +5,26 @@ namespace Yokai\Batch\Tests\Bridge\Doctrine\Persistence\Dummy; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Repository\RepositoryFactory; -use Doctrine\Persistence\ObjectRepository; class DecoratedRepositoryFactory implements RepositoryFactory { /** - * @var array + * @var array */ private array $repositories = []; public function __construct( /** - * @var class-string + * @var class-string */ private string $class, private RepositoryFactory $decorated, ) { } - public function getRepository(EntityManagerInterface $entityManager, $entityName): ObjectRepository + public function getRepository(EntityManagerInterface $entityManager, string $entityName): EntityRepository { return $this->repositories[$entityName] ??= new $this->class( $this->decorated->getRepository($entityManager, $entityName), diff --git a/src/batch-doctrine-persistence/tests/Dummy/FindOneByCalledOnlyOnceWhenFoundRepositoryDecorator.php b/src/batch-doctrine-persistence/tests/Dummy/FindOneByCalledOnlyOnceWhenFoundRepositoryDecorator.php index e92f1bbf..3979e395 100644 --- a/src/batch-doctrine-persistence/tests/Dummy/FindOneByCalledOnlyOnceWhenFoundRepositoryDecorator.php +++ b/src/batch-doctrine-persistence/tests/Dummy/FindOneByCalledOnlyOnceWhenFoundRepositoryDecorator.php @@ -4,9 +4,11 @@ namespace Yokai\Batch\Tests\Bridge\Doctrine\Persistence\Dummy; +use Doctrine\DBAL\LockMode; +use Doctrine\ORM\EntityRepository; use Doctrine\Persistence\ObjectRepository; -class FindOneByCalledOnlyOnceWhenFoundRepositoryDecorator implements ObjectRepository +class FindOneByCalledOnlyOnceWhenFoundRepositoryDecorator extends EntityRepository { private array $calls = []; @@ -15,22 +17,26 @@ public function __construct( ) { } - public function find($id) + public function find(mixed $id, LockMode|int|null $lockMode = null, int|null $lockVersion = null): object|null { return $this->decorated->find($id); } - public function findAll() + public function findAll(): array { return $this->decorated->findAll(); } - public function findBy(array $criteria, array|null $orderBy = null, $limit = null, $offset = null) - { + public function findBy( + array $criteria, + array|null $orderBy = null, + int|null $limit = null, + int|null $offset = null, + ): array { return $this->decorated->findBy($criteria, $orderBy, $limit, $offset); } - public function findOneBy(array $criteria) + public function findOneBy(array $criteria, array|null $orderBy = null): object|null { $result = $this->decorated->findOneBy($criteria); if ($result === null) { @@ -42,7 +48,7 @@ public function findOneBy(array $criteria) return $result; } - public function getClassName() + public function getClassName(): string { return $this->decorated->getClassName(); } diff --git a/src/batch-doctrine-persistence/tests/Dummy/SimpleManagerRegistry.php b/src/batch-doctrine-persistence/tests/Dummy/SimpleManagerRegistry.php index d8c1e155..400382ad 100644 --- a/src/batch-doctrine-persistence/tests/Dummy/SimpleManagerRegistry.php +++ b/src/batch-doctrine-persistence/tests/Dummy/SimpleManagerRegistry.php @@ -4,9 +4,9 @@ namespace Yokai\Batch\Tests\Bridge\Doctrine\Persistence\Dummy; -use Doctrine\ORM\Proxy\Proxy; use Doctrine\Persistence\AbstractManagerRegistry; use Doctrine\Persistence\ObjectManager; +use Doctrine\Persistence\Proxy; final class SimpleManagerRegistry extends AbstractManagerRegistry { @@ -36,17 +36,25 @@ public function __construct( ); } - protected function getService($name) + protected function getService(string $name): object { return $this->services[$name] ?? throw new \InvalidArgumentException('Unknown service "' . $name . '".'); } - protected function resetService($name) + protected function resetService(string $name): void { } - public function getAliasNamespace($alias) + public function getManagerForClass(string $class): ObjectManager|null { - return $alias; + foreach ($this->services as $service) { + foreach ($service->getMetadataFactory()->getAllMetadata() as $metadata) { + if (\is_a($class, $metadata->name, true)) { + return $service; + } + } + } + + return null; } } diff --git a/src/batch-doctrine-persistence/tests/Entity/Shop/Product.php b/src/batch-doctrine-persistence/tests/Entity/Shop/Product.php index 7b2c6724..dc2a3dff 100644 --- a/src/batch-doctrine-persistence/tests/Entity/Shop/Product.php +++ b/src/batch-doctrine-persistence/tests/Entity/Shop/Product.php @@ -6,22 +6,16 @@ use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\Entity() - * @ORM\Table(name="shop_product") - */ +#[ORM\Entity] +#[ORM\Table(name: 'shop_product')] class Product { - /** - * @ORM\Column(type="integer") - * @ORM\Id() - * @ORM\GeneratedValue() - */ + #[ORM\Column(type: 'integer')] + #[ORM\Id] + #[ORM\GeneratedValue] public int $id; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] public string $name; public function __construct(string $name) diff --git a/tests/integration/Entity/Badge.php b/tests/integration/Entity/Badge.php index b711eafe..e6381667 100644 --- a/tests/integration/Entity/Badge.php +++ b/tests/integration/Entity/Badge.php @@ -6,28 +6,26 @@ use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\Entity() - */ +#[ORM\Entity] class Badge { /** * @var int - * @ORM\Column(type="integer") - * @ORM\Id() - * @ORM\GeneratedValue(strategy="AUTO") */ + #[ORM\Column(type: 'integer')] + #[ORM\Id] + #[ORM\GeneratedValue] public $id; /** * @var string - * @ORM\Column() */ + #[ORM\Column(type: 'string')] public $label; /** * @var string - * @ORM\Column(type="integer") */ + #[ORM\Column(type: 'integer')] public $rank; } diff --git a/tests/integration/Entity/Developer.php b/tests/integration/Entity/Developer.php index 32dc6cf5..dfa387a2 100644 --- a/tests/integration/Entity/Developer.php +++ b/tests/integration/Entity/Developer.php @@ -8,41 +8,39 @@ use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\Entity() - */ +#[ORM\Entity] class Developer { /** * @var int - * @ORM\Column(type="integer") - * @ORM\Id() - * @ORM\GeneratedValue(strategy="AUTO") */ + #[ORM\Column(type: 'integer')] + #[ORM\Id] + #[ORM\GeneratedValue] public $id; /** * @var string - * @ORM\Column() */ + #[ORM\Column(type: 'string')] public $firstName; /** * @var string - * @ORM\Column() */ + #[ORM\Column(type: 'string')] public $lastName; /** * @var Collection - * @ORM\ManyToMany(targetEntity=Badge::class) */ + #[ORM\ManyToMany(targetEntity: Badge::class)] public $badges; /** * @var Collection - * @ORM\ManyToMany(targetEntity=Repository::class) */ + #[ORM\ManyToMany(targetEntity: Repository::class)] public $repositories; public function __construct() diff --git a/tests/integration/Entity/Repository.php b/tests/integration/Entity/Repository.php index 45f98dff..027c1328 100644 --- a/tests/integration/Entity/Repository.php +++ b/tests/integration/Entity/Repository.php @@ -6,28 +6,26 @@ use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\Entity() - */ +#[ORM\Entity] class Repository { /** * @var int - * @ORM\Column(type="integer") - * @ORM\Id() - * @ORM\GeneratedValue(strategy="AUTO") */ + #[ORM\Column(type: 'integer')] + #[ORM\Id] + #[ORM\GeneratedValue] public $id; /** * @var string - * @ORM\Column() */ + #[ORM\Column(type: 'string')] public $label; /** * @var string - * @ORM\Column() */ + #[ORM\Column(type: 'string')] public $url; } diff --git a/tests/integration/ImportDevelopersXlsxToORMTest.php b/tests/integration/ImportDevelopersXlsxToORMTest.php index 82bc996d..e3590eb2 100644 --- a/tests/integration/ImportDevelopersXlsxToORMTest.php +++ b/tests/integration/ImportDevelopersXlsxToORMTest.php @@ -5,6 +5,7 @@ namespace Yokai\Batch\Sources\Tests\Integration; use Doctrine\DBAL\DriverManager; +use Doctrine\DBAL\Tools\DsnParser; use Doctrine\ORM\EntityManager; use Doctrine\ORM\ORMSetup; use Doctrine\ORM\Tools\SchemaTool; @@ -55,8 +56,14 @@ protected function setUp(): void { $this->persisted = []; - $connection = DriverManager::getConnection(['url' => \getenv('DATABASE_URL')]); - $config = ORMSetup::createAnnotationMetadataConfiguration([__DIR__ . '/Entity'], true); + $config = ORMSetup::createAttributeMetadataConfiguration([__DIR__ . '/Entity'], true); + if (\PHP_VERSION_ID >= 80400) { + $config->enableNativeLazyObjects(true); + } else { + $config->setProxyDir(\sys_get_temp_dir()); + $config->setProxyNamespace('DoctrineProxies'); + } + $connection = DriverManager::getConnection((new DsnParser())->parse(\getenv('DATABASE_URL'))); $this->entityManager = new EntityManager($connection, $config); (new SchemaTool($this->entityManager)) diff --git a/tests/symfony/src/Kernel.php b/tests/symfony/src/Kernel.php index 5f7926b5..004980c9 100644 --- a/tests/symfony/src/Kernel.php +++ b/tests/symfony/src/Kernel.php @@ -85,8 +85,7 @@ protected function configureContainer(ContainerConfigurator $container): void 'url' => 'sqlite:///%kernel.project_dir%/var/database.sqlite', 'logging' => false, ], - 'orm' => [ - 'auto_generate_proxy_classes' => true, + 'orm' => \array_merge([ 'naming_strategy' => 'doctrine.orm.naming_strategy.underscore', 'mappings' => [ 'App' => [ @@ -97,7 +96,7 @@ protected function configureContainer(ContainerConfigurator $container): void 'alias' => 'App', ], ], - ], + ], (\PHP_VERSION_ID < 80400 ? ['auto_generate_proxy_classes' => true] : [])), ]); $container->extension('twig', [ 'default_path' => __DIR__ . '/../templates', @@ -142,7 +141,7 @@ protected function configureContainer(ContainerConfigurator $container): void protected function configureRoutes(RoutingConfigurator $routes): void { - $routes->import('@YokaiBatchBundle/Resources/routing/ui.xml'); + $routes->import('@YokaiBatchBundle/Resources/routing/ui.php'); } public function process(ContainerBuilder $container): void diff --git a/tests/symfony/tests/JobTest.php b/tests/symfony/tests/JobTest.php index 5d76150f..f582b2a4 100644 --- a/tests/symfony/tests/JobTest.php +++ b/tests/symfony/tests/JobTest.php @@ -4,6 +4,7 @@ namespace Yokai\Batch\Sources\Tests\Symfony\Tests; +use Doctrine\DBAL\Platforms\Exception\NotSupported; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Tools\SchemaTool; use Generator; @@ -70,8 +71,13 @@ private static function setupDatabase(): void if (\file_exists($database)) { \unlink($database); } - $schema = $connection->createSchemaManager(); - $schema->createDatabase($database); + + try { + $schema = $connection->createSchemaManager(); + $schema->createDatabase($database); + } catch (NotSupported) { + // when using sqlite, creating database is implicit + } (new SchemaTool($entityManager)) ->createSchema($entityManager->getMetadataFactory()->getAllMetadata()); From a4cc5c23e79dfd8a25c9b1860f3a1827544f2674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20Eugon=C3=A9?= Date: Wed, 7 Jan 2026 11:19:51 +0100 Subject: [PATCH 06/11] Fixed usage of validator constraints options --- .../tests/SkipInvalidItemProcessorTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/batch-symfony-validator/tests/SkipInvalidItemProcessorTest.php b/src/batch-symfony-validator/tests/SkipInvalidItemProcessorTest.php index 462c030c..c2b440d8 100644 --- a/src/batch-symfony-validator/tests/SkipInvalidItemProcessorTest.php +++ b/src/batch-symfony-validator/tests/SkipInvalidItemProcessorTest.php @@ -22,7 +22,7 @@ class SkipInvalidItemProcessorTest extends TestCase public function testProcessValid(null|array $groups): void { $validator = Validation::createValidator(); - $processor = new SkipInvalidItemProcessor($validator, [new NotBlank(['groups' => $groups])], $groups); + $processor = new SkipInvalidItemProcessor($validator, [new NotBlank(groups: $groups)], $groups); self::assertSame('valid item not blank', $processor->process('valid item not blank')); } @@ -32,7 +32,7 @@ public function testProcessValid(null|array $groups): void public function testProcessInvalid(null|array $groups): void { $validator = Validation::createValidator(); - $processor = new SkipInvalidItemProcessor($validator, [new Blank(['groups' => ['Default', 'Full']])], $groups); + $processor = new SkipInvalidItemProcessor($validator, [new Blank(groups: ['Default', 'Full'])], $groups); $exception = null; From 14cd8caa1122dbc422309e870d8f0396377646b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20Eugon=C3=A9?= Date: Wed, 7 Jan 2026 11:20:13 +0100 Subject: [PATCH 07/11] Lock more Symfony component versions to avoid incompatibility issues --- .github/actions/install/action.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/actions/install/action.yml b/.github/actions/install/action.yml index cce4658e..56b18243 100644 --- a/.github/actions/install/action.yml +++ b/.github/actions/install/action.yml @@ -41,4 +41,6 @@ runs: composer require --quiet --no-update "symfony/process:${{ inputs.symfony-version }}" --dev composer require --quiet --no-update "symfony/yaml:${{ inputs.symfony-version }}" --dev composer require --quiet --no-update "symfony/http-client:${{ inputs.symfony-version }}" --dev + composer require --quiet --no-update "symfony/browser-kit:${{ inputs.symfony-version }}" --dev + composer require --quiet --no-update "symfony/translation:${{ inputs.symfony-version }}" --dev composer update --no-interaction --no-progress From a9038696139ea6ce2bff5707f787a54e1f25c9c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20Eugon=C3=A9?= Date: Wed, 7 Jan 2026 11:28:02 +0100 Subject: [PATCH 08/11] Update PHPUnit version --- .led/config | 2 +- composer.json | 2 +- phpunit.xml | 16 ++---- .../DoctrineDBALJobExecutionStorageTest.php | 13 ++--- .../tests/Reader/FlatFileReaderTest.php | 13 ++--- .../tests/Writer/FlatFileWriterTest.php | 53 +++++++++---------- .../tests/RunJobCommandTest.php | 15 ++---- .../YokaiBatchExtensionTest.php | 37 +++++-------- .../Controller/JobControllerTest.php | 13 ++--- .../UserInterface/Form/JobFilterTypeTest.php | 5 +- .../tests/UserInterface/JobSecurityTest.php | 5 +- .../tests/UserInterface/TwigExtensionTest.php | 5 +- .../tests/DenormalizeItemProcessorTest.php | 13 ++--- .../tests/NormalizeItemProcessorTest.php | 13 ++--- .../tests/SkipInvalidItemProcessorTest.php | 11 ++-- .../tests/SkipItemOnViolationsTest.php | 7 ++- src/batch/tests/BatchStatusTest.php | 7 ++- src/batch/tests/FailureTest.php | 7 ++- .../Item/Exception/SkipItemOnErrorTest.php | 7 ++- src/batch/tests/Job/Item/ItemJobTest.php | 7 ++- .../Processor/FilterUniqueProcessorTest.php | 7 ++- .../Job/Item/Reader/CallbackReaderTest.php | 5 +- .../FixedColumnSizeFileReaderTest.php | 7 ++- .../Job/Item/Reader/IndexWithReaderTest.php | 7 ++- .../Reader/ParameterAccessorReaderTest.php | 7 ++- .../Item/Reader/StaticIterableReaderTest.php | 7 ++- src/batch/tests/Job/JobExecutorTest.php | 7 ++- .../JsonJobExecutionSerializerTest.php | 23 +++----- .../FilesystemJobExecutionStorageTest.php | 13 ++--- src/batch/tests/Storage/QueryBuilderTest.php | 13 ++--- .../convention/Comment/ClassCommentsTest.php | 11 ++-- .../convention/Comment/MethodCommentsTest.php | 17 +++--- tests/convention/Dependency/PackagesTest.php | 6 +-- .../Documentation/DocumentationLinksTest.php | 11 ++-- tests/integration/JobTestCase.php | 11 ++-- tests/symfony/tests/JobTest.php | 9 ++-- tests/symfony/tests/UserInterfaceTest.php | 9 ++-- 37 files changed, 163 insertions(+), 258 deletions(-) diff --git a/.led/config b/.led/config index 591b163d..5a8d63a8 100644 --- a/.led/config +++ b/.led/config @@ -1,4 +1,4 @@ [service] project-name = yokai-batch [default] - container = php83 + container = php84 diff --git a/composer.json b/composer.json index 28a16c0e..ee2130ea 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,7 @@ "league/flysystem-memory": "^3.0", "phpspec/prophecy-phpunit": "^2.0", "phpstan/phpstan": "^1.4", - "phpunit/phpunit": "^9.5", + "phpunit/phpunit": "^10.0|^12.0", "sonata-project/admin-bundle": "^4.0", "symfony/browser-kit": "^6.4|^7.4|^8.0", "symfony/css-selector": "^6.4|^7.4|^8.0", diff --git a/phpunit.xml b/phpunit.xml index 7331c64d..89d33d3c 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -2,7 +2,7 @@ - - ./src/*/tests - - - ./tests/integration - - - ./tests/symfony/tests - - ./src/*/tests ./tests/integration @@ -34,9 +24,9 @@ - + ./src/*/src - + diff --git a/src/batch-doctrine-dbal/tests/DoctrineDBALJobExecutionStorageTest.php b/src/batch-doctrine-dbal/tests/DoctrineDBALJobExecutionStorageTest.php index 9e378182..60fdd2cc 100644 --- a/src/batch-doctrine-dbal/tests/DoctrineDBALJobExecutionStorageTest.php +++ b/src/batch-doctrine-dbal/tests/DoctrineDBALJobExecutionStorageTest.php @@ -8,6 +8,7 @@ use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Types\Types; use Generator; +use PHPUnit\Framework\Attributes\DataProvider; use RuntimeException; use Throwable; use Yokai\Batch\BatchStatus; @@ -215,9 +216,7 @@ public function testRetrieveFailing(): void $storage->retrieve('export', '456'); } - /** - * @dataProvider retrieveInvalid - */ + #[DataProvider('retrieveInvalid')] public function testRetrieveInvalid(array $data, Throwable $error): void { $this->expectExceptionObject($error); @@ -238,7 +237,7 @@ public function testRetrieveInvalid(array $data, Throwable $error): void $storage->retrieve('export', '123'); } - public function retrieveInvalid(): \Generator + public static function retrieveInvalid(): \Generator { yield '"parameters" column value is expected to be array' => [ ['parameters' => '"string"'], @@ -272,9 +271,7 @@ public function testList(): void self::assertExecutionIds(['456', '789', '987'], $storage->list('import')); } - /** - * @dataProvider queries - */ + #[DataProvider('queries')] public function testQuery(QueryBuilder $queryBuilder, array $expectedCouples): void { $storage = $this->createStorage(); @@ -285,7 +282,7 @@ public function testQuery(QueryBuilder $queryBuilder, array $expectedCouples): v self::assertSame(\count($expectedCouples), $storage->count($queryBuilder->getQuery())); } - public function queries(): Generator + public static function queries(): Generator { yield 'No filter' => [ new QueryBuilder(), diff --git a/src/batch-openspout/tests/Reader/FlatFileReaderTest.php b/src/batch-openspout/tests/Reader/FlatFileReaderTest.php index 7f3f6621..4c2ca0f0 100644 --- a/src/batch-openspout/tests/Reader/FlatFileReaderTest.php +++ b/src/batch-openspout/tests/Reader/FlatFileReaderTest.php @@ -8,6 +8,7 @@ use OpenSpout\Reader\CSV\Options as CSVOptions; use OpenSpout\Reader\ODS\Options as ODSOptions; use OpenSpout\Reader\XLSX\Options as XLSXOptions; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Yokai\Batch\Bridge\OpenSpout\Reader\FlatFileReader; use Yokai\Batch\Bridge\OpenSpout\Reader\HeaderStrategy; @@ -17,9 +18,7 @@ class FlatFileReaderTest extends TestCase { - /** - * @dataProvider sets - */ + #[DataProvider('sets')] public function testRead( string $file, null|object $options, @@ -42,7 +41,7 @@ public function testRead( self::assertSame($expected, \iterator_to_array($got)); } - public function sets(): Generator + public static function sets(): Generator { $csv = __DIR__ . '/fixtures/sample.csv'; $ods = __DIR__ . '/fixtures/sample.ods'; @@ -219,9 +218,7 @@ public function testReadWrongLineSize(): void ); } - /** - * @dataProvider wrongOptions - */ + #[DataProvider('wrongOptions')] public function testWrongOptions(string $file, object $options): void { $this->expectException(\TypeError::class); @@ -233,7 +230,7 @@ public function testWrongOptions(string $file, object $options): void \iterator_to_array($reader->read()); } - public function wrongOptions(): \Generator + public static function wrongOptions(): \Generator { // with CSV file, CSVOptions is expected yield [__DIR__ . '/fixtures/sample.csv', new XLSXOptions()]; diff --git a/src/batch-openspout/tests/Writer/FlatFileWriterTest.php b/src/batch-openspout/tests/Writer/FlatFileWriterTest.php index e3d63f8a..aaecf450 100644 --- a/src/batch-openspout/tests/Writer/FlatFileWriterTest.php +++ b/src/batch-openspout/tests/Writer/FlatFileWriterTest.php @@ -11,6 +11,7 @@ use OpenSpout\Writer\CSV\Options as CSVOptions; use OpenSpout\Writer\ODS\Options as ODSOptions; use OpenSpout\Writer\XLSX\Options as XLSXOptions; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Yokai\Batch\Bridge\OpenSpout\Writer\FlatFileWriter; use Yokai\Batch\Bridge\OpenSpout\Writer\WriteToSheetItem; @@ -24,9 +25,7 @@ class FlatFileWriterTest extends TestCase { private const WRITE_DIR = ARTIFACT_DIR . '/openspout-flat-file-writer'; - /** - * @dataProvider sets - */ + #[DataProvider('sets')] public function testWrite( string $filename, null|object $options, @@ -48,7 +47,7 @@ public function testWrite( self::assertFileContents($file, $expectedContent); } - public function sets(): \Generator + public static function sets(): \Generator { $headers = ['firstName', 'lastName']; $items = [ @@ -68,7 +67,7 @@ public function sets(): \Generator Jack,Doe CSV; - foreach ($this->types() as [$type]) { + foreach (self::types() as [$type]) { yield [ "no-header.$type", null, @@ -165,9 +164,7 @@ public function sets(): \Generator ]; } - /** - * @dataProvider types - */ + #[DataProvider('types')] public function testWriteInvalidItem(string $type): void { $this->expectException(UnexpectedValueException::class); @@ -180,9 +177,7 @@ public function testWriteInvalidItem(string $type): void $writer->write([true]); // writer accept collection of array or \OpenSpout\Common\Entity\Row } - /** - * @dataProvider types - */ + #[DataProvider('types')] public function testCannotCreateFile(string $type): void { $this->expectException(RuntimeException::class); @@ -194,9 +189,7 @@ public function testCannotCreateFile(string $type): void $writer->initialize(); } - /** - * @dataProvider types - */ + #[DataProvider('types')] public function testShouldInitializeBeforeWrite(string $type): void { $this->expectException(BadMethodCallException::class); @@ -206,9 +199,7 @@ public function testShouldInitializeBeforeWrite(string $type): void $writer->write([true]); } - /** - * @dataProvider types - */ + #[DataProvider('types')] public function testShouldInitializeBeforeFlush(string $type): void { $this->expectException(BadMethodCallException::class); @@ -218,16 +209,14 @@ public function testShouldInitializeBeforeFlush(string $type): void $writer->flush(); } - public function types(): \Generator + public static function types(): \Generator { yield ['csv']; yield ['ods']; yield ['xlsx']; } - /** - * @dataProvider multipleSheets - */ + #[DataProvider('multipleSheets')] public function testWriteMultipleSheets(string $type, null|string $defaultSheet): void { $file = self::WRITE_DIR . '/multiple-sheets.' . $type; @@ -264,16 +253,14 @@ public function testWriteMultipleSheets(string $type, null|string $defaultSheet) } } - public function multipleSheets(): \Generator + public static function multipleSheets(): \Generator { yield ['csv', null]; yield ['xlsx', 'English']; yield ['ods', 'English']; } - /** - * @dataProvider wrongOptions - */ + #[DataProvider('wrongOptions')] public function testWrongOptions(string $type, object $options): void { $this->expectException(\TypeError::class); @@ -285,7 +272,7 @@ public function testWrongOptions(string $type, object $options): void $reader->initialize(); } - public function wrongOptions(): \Generator + public static function wrongOptions(): \Generator { // with CSV file, CSVOptions is expected yield ['csv', new XLSXOptions()]; @@ -303,7 +290,12 @@ public function wrongOptions(): \Generator private static function assertFileContents(string $filePath, string $inlineData): void { $type = \strtolower(\pathinfo($filePath, PATHINFO_EXTENSION)); - $strings = \array_merge(...\array_map('str_getcsv', \explode(PHP_EOL, $inlineData))); + $strings = \array_merge( + ...\array_map( + fn(string $string) => \str_getcsv($string, ',', '"', '\\'), + \explode(PHP_EOL, $inlineData), + ), + ); switch ($type) { case 'csv': @@ -337,7 +329,12 @@ private static function assertFileContents(string $filePath, string $inlineData) private static function assertSheetContents(string $filePath, string $sheet, string $inlineData): void { $type = \strtolower(\pathinfo($filePath, PATHINFO_EXTENSION)); - $strings = \array_merge(...\array_map('str_getcsv', \explode(PHP_EOL, $inlineData))); + $strings = \array_merge( + ...\array_map( + fn(string $string) => \str_getcsv($string, ',', '"', '\\'), + \explode(PHP_EOL, $inlineData), + ), + ); switch ($type) { case 'csv': diff --git a/src/batch-symfony-console/tests/RunJobCommandTest.php b/src/batch-symfony-console/tests/RunJobCommandTest.php index a1bfd9ee..e20b2687 100644 --- a/src/batch-symfony-console/tests/RunJobCommandTest.php +++ b/src/batch-symfony-console/tests/RunJobCommandTest.php @@ -5,6 +5,7 @@ namespace Yokai\Batch\Tests\Bridge\Symfony\Console; use JsonException; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; @@ -65,9 +66,7 @@ public function testRunWithInvalidConfiguration(): void $this->execute('"string"'); } - /** - * @dataProvider verbosity - */ + #[DataProvider('verbosity')] public function testRunWithErrors(int $verbosity): void { $this->job->execute(Argument::any()) @@ -97,9 +96,7 @@ public function testRunWithErrors(int $verbosity): void } } - /** - * @dataProvider verbosity - */ + #[DataProvider('verbosity')] public function testRunWithWarnings(int $verbosity): void { $this->job->execute(Argument::any()) @@ -128,9 +125,7 @@ public function testRunWithWarnings(int $verbosity): void } } - /** - * @dataProvider verbosity - */ + #[DataProvider('verbosity')] public function testRunSuccessful(int $verbosity): void { $this->job->execute(Argument::any()) @@ -147,7 +142,7 @@ public function testRunSuccessful(int $verbosity): void } } - public function verbosity(): \Generator + public static function verbosity(): \Generator { yield 'quiet' => [OutputInterface::VERBOSITY_QUIET]; yield 'normal' => [OutputInterface::VERBOSITY_NORMAL]; diff --git a/src/batch-symfony-framework/tests/DependencyInjection/YokaiBatchExtensionTest.php b/src/batch-symfony-framework/tests/DependencyInjection/YokaiBatchExtensionTest.php index db9e9012..83ac3ec0 100644 --- a/src/batch-symfony-framework/tests/DependencyInjection/YokaiBatchExtensionTest.php +++ b/src/batch-symfony-framework/tests/DependencyInjection/YokaiBatchExtensionTest.php @@ -5,6 +5,7 @@ namespace Yokai\Batch\Tests\Bridge\Symfony\Framework\DependencyInjection; use Exception; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; @@ -39,9 +40,7 @@ class YokaiBatchExtensionTest extends TestCase { - /** - * @dataProvider storage - */ + #[DataProvider('storage')] public function testStorage(array $config, \Closure|null $configure, string $storage): void { $container = $this->createContainer($config, $configure); @@ -51,7 +50,7 @@ public function testStorage(array $config, \Closure|null $configure, string $sto self::assertSame($storage, $jobExecutionStorageService->getClass()); } - public function storage(): \Generator + public static function storage(): \Generator { yield 'Default config' => [ [], @@ -75,9 +74,7 @@ public function storage(): \Generator ]; } - /** - * @dataProvider launcher - */ + #[DataProvider('launcher')] public function testLauncher( array $config, \Closure|null $configure, @@ -97,7 +94,7 @@ public function testLauncher( } } - public function launcher(): \Generator + public static function launcher(): \Generator { yield 'Default config' => [ [], @@ -210,9 +207,7 @@ function (ContainerBuilder $container) { ]; } - /** - * @dataProvider userInterface - */ + #[DataProvider('userInterface')] public function testUserInterface( array $config, \Closure|null $configure, @@ -250,7 +245,7 @@ public function testUserInterface( } } - public function userInterface(): \Generator + public static function userInterface(): \Generator { yield 'Default config' => [ [], @@ -352,9 +347,7 @@ function (Definition $templating) { ]; } - /** - * @dataProvider parameters - */ + #[DataProvider('parameters')] public function testParameters(array $config, array|null $global, array|null $perJob): void { $container = $this->createContainer($config); @@ -386,7 +379,7 @@ public function testParameters(array $config, array|null $global, array|null $pe self::assertSame('yokai_batch.job_execution_parameters_builder', $defaultServiceBuilders->getTag()); } - public function parameters(): \Generator + public static function parameters(): \Generator { yield 'Global parameters' => [ ['parameters' => ['global' => ['global' => true]]], @@ -408,16 +401,14 @@ public function parameters(): \Generator ]; } - /** - * @dataProvider errors - */ + #[DataProvider('errors')] public function testErrors(array $config, Exception $error): void { $this->expectExceptionObject($error); $this->createContainer($config); } - public function errors(): \Generator + public static function errors(): \Generator { yield 'Templating : Not configured' => [ ['ui' => ['enabled' => true, 'templating' => []]], @@ -463,9 +454,7 @@ public function errors(): \Generator ]; } - /** - * @dataProvider id - */ + #[DataProvider('id')] public function testId(array $config, string $idGenerator): void { $container = $this->createContainer($config); @@ -474,7 +463,7 @@ public function testId(array $config, string $idGenerator): void self::assertSame($idGenerator, $idGeneratorDefinition->getClass()); } - public function id(): \Generator + public static function id(): \Generator { yield 'Default config' => [ [], diff --git a/src/batch-symfony-framework/tests/UserInterface/Controller/JobControllerTest.php b/src/batch-symfony-framework/tests/UserInterface/Controller/JobControllerTest.php index fce0e9e1..72185c73 100644 --- a/src/batch-symfony-framework/tests/UserInterface/Controller/JobControllerTest.php +++ b/src/batch-symfony-framework/tests/UserInterface/Controller/JobControllerTest.php @@ -4,6 +4,7 @@ namespace Yokai\Batch\Tests\Bridge\Symfony\Framework\UserInterface\Controller; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Constraint\LogicalAnd; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Twig\Extension\FormExtension; @@ -67,9 +68,7 @@ protected function setUp(): void (new Filesystem())->remove(self::STORAGE_DIR); } - /** - * @dataProvider list - */ + #[DataProvider('list')] public function testList( \Closure $fixtures, Request $request, @@ -191,9 +190,7 @@ function () { } } - /** - * @dataProvider view - */ + #[DataProvider('view')] public function testView( \Closure $fixtures, string $job, @@ -322,9 +319,7 @@ public static function view(): \Generator } } - /** - * @dataProvider logs - */ + #[DataProvider('logs')] public function testLogs( \Closure $fixtures, string $job, diff --git a/src/batch-symfony-framework/tests/UserInterface/Form/JobFilterTypeTest.php b/src/batch-symfony-framework/tests/UserInterface/Form/JobFilterTypeTest.php index 6588dbe7..1a80cdfc 100644 --- a/src/batch-symfony-framework/tests/UserInterface/Form/JobFilterTypeTest.php +++ b/src/batch-symfony-framework/tests/UserInterface/Form/JobFilterTypeTest.php @@ -4,6 +4,7 @@ namespace Yokai\Batch\Tests\Bridge\Symfony\Framework\UserInterface\Form; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\Form\ChoiceList\View\ChoiceView; use Symfony\Component\Form\FormView; use Symfony\Component\Form\Test\TypeTestCase; @@ -48,9 +49,7 @@ public function testBuild(): void ); } - /** - * @dataProvider submit - */ + #[DataProvider('submit')] public function testSubmit(array $submit, JobFilter $expected, bool $valid): void { $form = $this->factory->create(JobFilterType::class, $actual = new JobFilter()); diff --git a/src/batch-symfony-framework/tests/UserInterface/JobSecurityTest.php b/src/batch-symfony-framework/tests/UserInterface/JobSecurityTest.php index 7c16f147..bac22bb4 100644 --- a/src/batch-symfony-framework/tests/UserInterface/JobSecurityTest.php +++ b/src/batch-symfony-framework/tests/UserInterface/JobSecurityTest.php @@ -4,6 +4,7 @@ namespace Yokai\Batch\Tests\Bridge\Symfony\Framework\UserInterface; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Security\Core\Authorization\AccessDecision; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; @@ -30,9 +31,7 @@ public function testWithNoSecurity(): void self::assertEquals($expected, $this->test($security)); } - /** - * @dataProvider withSecurity - */ + #[DataProvider('withSecurity')] public function testWithSecurity(array $attributes, array $expected): void { $authorizationChecker = new class($attributes) implements AuthorizationCheckerInterface { diff --git a/src/batch-symfony-framework/tests/UserInterface/TwigExtensionTest.php b/src/batch-symfony-framework/tests/UserInterface/TwigExtensionTest.php index cdcdc10b..0fff73f7 100644 --- a/src/batch-symfony-framework/tests/UserInterface/TwigExtensionTest.php +++ b/src/batch-symfony-framework/tests/UserInterface/TwigExtensionTest.php @@ -4,6 +4,7 @@ namespace Yokai\Batch\Tests\Bridge\Symfony\Framework\UserInterface; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Security\Core\Authorization\AccessDecision; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; @@ -15,9 +16,7 @@ final class TwigExtensionTest extends TestCase { - /** - * @dataProvider security - */ + #[DataProvider('security')] public function testSecurity(JobSecurity $security, bool $granted): void { $twig = new Environment(new ArrayLoader(['default' => <<process($item)); } - /** - * @dataProvider sets - */ + #[DataProvider('sets')] public function testUnsupported(string $type, null|string $format, array $context, $item): void { $denormalizer = new DummyNormalizer(false, null); @@ -51,9 +48,7 @@ public function testUnsupported(string $type, null|string $format, array $contex self::assertSame('Unable to denormalize item. Not supported.', $cause->getError()->getMessage()); } - /** - * @dataProvider sets - */ + #[DataProvider('sets')] public function testException(string $type, null|string $format, array $context, $item): void { $denormalizer = new FailingNormalizer($exceptionThrown = new UnsupportedException()); diff --git a/src/batch-symfony-serializer/tests/NormalizeItemProcessorTest.php b/src/batch-symfony-serializer/tests/NormalizeItemProcessorTest.php index dc29579e..aafd379e 100644 --- a/src/batch-symfony-serializer/tests/NormalizeItemProcessorTest.php +++ b/src/batch-symfony-serializer/tests/NormalizeItemProcessorTest.php @@ -7,6 +7,7 @@ use DateTime; use DateTimeImmutable; use Generator; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Serializer\Exception\BadMethodCallException; use Yokai\Batch\Bridge\Symfony\Serializer\NormalizeItemProcessor; @@ -17,9 +18,7 @@ final class NormalizeItemProcessorTest extends TestCase { - /** - * @dataProvider sets - */ + #[DataProvider('sets')] public function testProcess(null|string $format, array $context, $item, $expected): void { $normalizer = new DummyNormalizer(true, $expected); @@ -28,9 +27,7 @@ public function testProcess(null|string $format, array $context, $item, $expecte self::assertSame($expected, $processor->process($item)); } - /** - * @dataProvider sets - */ + #[DataProvider('sets')] public function testUnsupported(null|string $format, array $context, $item): void { $normalizer = new DummyNormalizer(false, null); @@ -51,9 +48,7 @@ public function testUnsupported(null|string $format, array $context, $item): voi self::assertSame('Unable to normalize item. Not supported.', $cause->getError()->getMessage()); } - /** - * @dataProvider sets - */ + #[DataProvider('sets')] public function testException(null|string $format, array $context, $item): void { $normalizer = new FailingNormalizer($exceptionThrown = new BadMethodCallException()); diff --git a/src/batch-symfony-validator/tests/SkipInvalidItemProcessorTest.php b/src/batch-symfony-validator/tests/SkipInvalidItemProcessorTest.php index c2b440d8..df3ac598 100644 --- a/src/batch-symfony-validator/tests/SkipInvalidItemProcessorTest.php +++ b/src/batch-symfony-validator/tests/SkipInvalidItemProcessorTest.php @@ -5,6 +5,7 @@ namespace Yokai\Batch\Tests\Bridge\Symfony\Validator; use Generator; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Validator\Constraints\Blank; use Symfony\Component\Validator\Constraints\NotBlank; @@ -16,9 +17,7 @@ class SkipInvalidItemProcessorTest extends TestCase { - /** - * @dataProvider groups - */ + #[DataProvider('validationGroups')] public function testProcessValid(null|array $groups): void { $validator = Validation::createValidator(); @@ -26,9 +25,7 @@ public function testProcessValid(null|array $groups): void self::assertSame('valid item not blank', $processor->process('valid item not blank')); } - /** - * @dataProvider groups - */ + #[DataProvider('validationGroups')] public function testProcessInvalid(null|array $groups): void { $validator = Validation::createValidator(); @@ -57,7 +54,7 @@ public function testProcessInvalid(null|array $groups): void self::assertSame('invalid item not blank', $violation->getInvalidValue()); } - public function groups(): Generator + public static function validationGroups(): Generator { yield 'No groups specified' => [null]; yield 'Group "Full" only' => [['Full']]; diff --git a/src/batch-symfony-validator/tests/SkipItemOnViolationsTest.php b/src/batch-symfony-validator/tests/SkipItemOnViolationsTest.php index 782c4067..95545c70 100644 --- a/src/batch-symfony-validator/tests/SkipItemOnViolationsTest.php +++ b/src/batch-symfony-validator/tests/SkipItemOnViolationsTest.php @@ -5,6 +5,7 @@ namespace Yokai\Batch\Tests\Bridge\Symfony\Validator; use DateTimeImmutable; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolationList; @@ -15,9 +16,7 @@ class SkipItemOnViolationsTest extends TestCase { - /** - * @dataProvider provider - */ + #[DataProvider('provider')] public function test(array $violations, array $expectedViolations): void { $execution = JobExecution::createRoot('123', 'testing'); @@ -34,7 +33,7 @@ public function test(array $violations, array $expectedViolations): void ); } - public function provider(): \Generator + public static function provider(): \Generator { $violation = function (string $message, $value) { return new ConstraintViolation($message, $message, [], null, 'property.path', $value); diff --git a/src/batch/tests/BatchStatusTest.php b/src/batch/tests/BatchStatusTest.php index 67a8c08c..9da54e2e 100644 --- a/src/batch/tests/BatchStatusTest.php +++ b/src/batch/tests/BatchStatusTest.php @@ -4,14 +4,13 @@ namespace Yokai\Batch\Tests; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Yokai\Batch\BatchStatus; class BatchStatusTest extends TestCase { - /** - * @dataProvider statuses - */ + #[DataProvider('statuses')] public function testStatus(int $value, string $label, bool $unsucessful) { $status = new BatchStatus($value); @@ -22,7 +21,7 @@ public function testStatus(int $value, string $label, bool $unsucessful) self::assertSame($unsucessful, $status->isUnsuccessful()); } - public function statuses(): \Generator + public static function statuses(): \Generator { yield 'completed' => [BatchStatus::COMPLETED, 'COMPLETED', false]; yield 'pending' => [BatchStatus::PENDING, 'PENDING', false]; diff --git a/src/batch/tests/FailureTest.php b/src/batch/tests/FailureTest.php index de9609c6..843cb29e 100644 --- a/src/batch/tests/FailureTest.php +++ b/src/batch/tests/FailureTest.php @@ -6,15 +6,14 @@ use Generator; use LogicException; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use RuntimeException; use Yokai\Batch\Failure; class FailureTest extends TestCase { - /** - * @dataProvider failures - */ + #[DataProvider('failures')] public function test( callable $load, string $class, @@ -36,7 +35,7 @@ public function test( self::assertSame($string, (string)$failure); } - public function failures(): Generator + public static function failures(): Generator { yield [ fn() => Failure::fromException( diff --git a/src/batch/tests/Job/Item/Exception/SkipItemOnErrorTest.php b/src/batch/tests/Job/Item/Exception/SkipItemOnErrorTest.php index 6b86fd86..4bea1c62 100644 --- a/src/batch/tests/Job/Item/Exception/SkipItemOnErrorTest.php +++ b/src/batch/tests/Job/Item/Exception/SkipItemOnErrorTest.php @@ -4,6 +4,7 @@ namespace Yokai\Batch\Tests\Job\Item\Exception; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use RuntimeException; use Throwable; @@ -14,9 +15,7 @@ class SkipItemOnErrorTest extends TestCase { - /** - * @dataProvider provider - */ + #[DataProvider('provider')] public function test(Throwable $error): void { $execution = JobExecution::createRoot('123', 'testing'); @@ -40,7 +39,7 @@ public function test(Throwable $error): void ); } - public function provider(): \Generator + public static function provider(): \Generator { yield [new RuntimeException('RuntimeException from SPL')]; yield [new LogicException('LogicException from library')]; diff --git a/src/batch/tests/Job/Item/ItemJobTest.php b/src/batch/tests/Job/Item/ItemJobTest.php index 7154530b..f2213ae3 100644 --- a/src/batch/tests/Job/Item/ItemJobTest.php +++ b/src/batch/tests/Job/Item/ItemJobTest.php @@ -6,6 +6,7 @@ use ArrayIterator; use Closure; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Yokai\Batch\Job\Item\Exception\SkipItemException; use Yokai\Batch\Job\Item\ExpandProcessedItem; @@ -77,9 +78,7 @@ public function testExecute(): void $debugWriter->assertWasUsed(); } - /** - * @dataProvider expand - */ + #[DataProvider('expand')] public function testWithExpandItem(Closure $callback): void { $job = new ItemJob( @@ -108,7 +107,7 @@ public function testWithExpandItem(Closure $callback): void self::assertSame(6, $execution->getSummary()->get('write')); } - public function expand(): \Generator + public static function expand(): \Generator { yield [ fn($item) => new ExpandProcessedItem(['fruit:' . $item, 'vegetable:' . $item]), diff --git a/src/batch/tests/Job/Item/Processor/FilterUniqueProcessorTest.php b/src/batch/tests/Job/Item/Processor/FilterUniqueProcessorTest.php index 06219ca6..81a7bf87 100644 --- a/src/batch/tests/Job/Item/Processor/FilterUniqueProcessorTest.php +++ b/src/batch/tests/Job/Item/Processor/FilterUniqueProcessorTest.php @@ -6,15 +6,14 @@ use ArrayIterator; use Generator; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Yokai\Batch\Job\Item\Exception\SkipItemException; use Yokai\Batch\Job\Item\Processor\FilterUniqueProcessor; class FilterUniqueProcessorTest extends TestCase { - /** - * @dataProvider provider - */ + #[DataProvider('provider')] public function test(callable $factory, array $items, array $expected): void { /** @var FilterUniqueProcessor $processor */ @@ -32,7 +31,7 @@ public function test(callable $factory, array $items, array $expected): void self::assertSame($expected, $actual); } - public function provider(): Generator + public static function provider(): Generator { $john = ['name' => 'John', 'location' => 'Washington']; $johnFiltered = ['name' => 'John', 'location' => 'New-York']; diff --git a/src/batch/tests/Job/Item/Reader/CallbackReaderTest.php b/src/batch/tests/Job/Item/Reader/CallbackReaderTest.php index 5d0bdfef..db1a69d5 100644 --- a/src/batch/tests/Job/Item/Reader/CallbackReaderTest.php +++ b/src/batch/tests/Job/Item/Reader/CallbackReaderTest.php @@ -4,14 +4,13 @@ namespace Yokai\Batch\Tests\Job\Item\Reader; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Yokai\Batch\Job\Item\Reader\CallbackReader; class CallbackReaderTest extends TestCase { - /** - * @dataProvider provider - */ + #[DataProvider('provider')] public function test(array $expected, \Closure $closure): void { $items = []; diff --git a/src/batch/tests/Job/Item/Reader/Filesystem/FixedColumnSizeFileReaderTest.php b/src/batch/tests/Job/Item/Reader/Filesystem/FixedColumnSizeFileReaderTest.php index ae6e6257..930b905b 100644 --- a/src/batch/tests/Job/Item/Reader/Filesystem/FixedColumnSizeFileReaderTest.php +++ b/src/batch/tests/Job/Item/Reader/Filesystem/FixedColumnSizeFileReaderTest.php @@ -5,6 +5,7 @@ namespace Yokai\Batch\Tests\Job\Item\Reader\Filesystem; use Generator; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Yokai\Batch\Exception\RuntimeException; use Yokai\Batch\Exception\UnexpectedValueException; @@ -14,9 +15,7 @@ class FixedColumnSizeFileReaderTest extends TestCase { - /** - * @dataProvider config - */ + #[DataProvider('config')] public function test(array $columns, string $headersMode, array $expected): void { $execution = JobExecution::createRoot('123456', 'testing'); @@ -47,7 +46,7 @@ public function testFileNotFound(): void \iterator_to_array($reader->read()); } - public function config(): Generator + public static function config(): Generator { $columnsWithoutNames = [10, 9, 8, -1]; $columnsWithNames = ['firstName' => 10, 'lastName' => 9, 'country' => 8, 'city' => -1]; diff --git a/src/batch/tests/Job/Item/Reader/IndexWithReaderTest.php b/src/batch/tests/Job/Item/Reader/IndexWithReaderTest.php index 52f69637..c47f74bd 100644 --- a/src/batch/tests/Job/Item/Reader/IndexWithReaderTest.php +++ b/src/batch/tests/Job/Item/Reader/IndexWithReaderTest.php @@ -6,6 +6,7 @@ use ArrayIterator; use Generator; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Yokai\Batch\Job\Item\Reader\IndexWithReader; use Yokai\Batch\Job\Item\Reader\StaticIterableReader; @@ -14,9 +15,7 @@ class IndexWithReaderTest extends TestCase { - /** - * @dataProvider provider - */ + #[DataProvider('provider')] public function test(callable $factory, array $expected): void { /** @var IndexWithReader $reader */ @@ -38,7 +37,7 @@ public function test(callable $factory, array $expected): void $decorated->assertWasUsed(); } - public function provider(): Generator + public static function provider(): Generator { $john = ['name' => 'John', 'location' => 'Washington']; $marie = ['name' => 'Marie', 'location' => 'London']; diff --git a/src/batch/tests/Job/Item/Reader/ParameterAccessorReaderTest.php b/src/batch/tests/Job/Item/Reader/ParameterAccessorReaderTest.php index 99445616..50ec4431 100644 --- a/src/batch/tests/Job/Item/Reader/ParameterAccessorReaderTest.php +++ b/src/batch/tests/Job/Item/Reader/ParameterAccessorReaderTest.php @@ -5,6 +5,7 @@ namespace Yokai\Batch\Tests\Job\Item\Reader; use Generator; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Yokai\Batch\Job\Item\Reader\ParameterAccessorReader; use Yokai\Batch\Job\Parameters\JobParameterAccessorInterface; @@ -13,9 +14,7 @@ class ParameterAccessorReaderTest extends TestCase { - /** - * @dataProvider provider - */ + #[DataProvider('provider')] public function test(JobParameterAccessorInterface $accessor, array $expected): void { $reader = new ParameterAccessorReader($accessor); @@ -29,7 +28,7 @@ public function test(JobParameterAccessorInterface $accessor, array $expected): self::assertSame($expected, $actual); } - public function provider(): Generator + public static function provider(): Generator { yield 'Read from preserved iterable' => [ new StaticValueParameterAccessor([1 => 'One', 2 => 'Two', 3 => 'Three']), diff --git a/src/batch/tests/Job/Item/Reader/StaticIterableReaderTest.php b/src/batch/tests/Job/Item/Reader/StaticIterableReaderTest.php index ff89a3d1..8cd72a11 100644 --- a/src/batch/tests/Job/Item/Reader/StaticIterableReaderTest.php +++ b/src/batch/tests/Job/Item/Reader/StaticIterableReaderTest.php @@ -4,14 +4,13 @@ namespace Yokai\Batch\Tests\Job\Item\Reader; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Yokai\Batch\Job\Item\Reader\StaticIterableReader; class StaticIterableReaderTest extends TestCase { - /** - * @dataProvider items - */ + #[DataProvider('items')] public function testRead(iterable $items, array $expected): void { $reader = new StaticIterableReader($items); @@ -24,7 +23,7 @@ public function testRead(iterable $items, array $expected): void self::assertSame($expected, $actual); } - public function items(): \Iterator + public static function items(): \Iterator { $items = [1, 2, 3]; diff --git a/src/batch/tests/Job/JobExecutorTest.php b/src/batch/tests/Job/JobExecutorTest.php index f5562c5a..488e9f02 100644 --- a/src/batch/tests/Job/JobExecutorTest.php +++ b/src/batch/tests/Job/JobExecutorTest.php @@ -5,6 +5,7 @@ namespace Yokai\Batch\Tests\Job; use PHPUnit\Framework\Assert; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; @@ -69,9 +70,7 @@ public function testLaunch(): void self::assertInstanceOf(PostExecuteEvent::class, $events[1] ?? null); } - /** - * @dataProvider errors - */ + #[DataProvider('errors')] public function testLaunchJobCatchErrors(Throwable $error): void { $execution = JobExecution::createRoot('123', 'test.job_executor'); @@ -139,7 +138,7 @@ public function testLaunchJobNotExecutable(): void self::assertCount(0, $events); } - public function errors(): \Generator + public static function errors(): \Generator { yield [new \Exception('Triggered for test purpose')]; yield [new \DivisionByZeroError('Triggered for test purpose')]; diff --git a/src/batch/tests/Serializer/JsonJobExecutionSerializerTest.php b/src/batch/tests/Serializer/JsonJobExecutionSerializerTest.php index 7990956d..91a27737 100644 --- a/src/batch/tests/Serializer/JsonJobExecutionSerializerTest.php +++ b/src/batch/tests/Serializer/JsonJobExecutionSerializerTest.php @@ -4,6 +4,7 @@ namespace Yokai\Batch\Tests\Unit\Serializer; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Yokai\Batch\Exception\RuntimeException; use Yokai\Batch\JobExecution; @@ -11,18 +12,14 @@ class JsonJobExecutionSerializerTest extends TestCase { - /** - * @dataProvider sets - */ + #[DataProvider('sets')] public function testSerialize(JobExecution $jobExecutionToSerialize, string $expectedSerializedJobExecution): void { $serializer = new JsonJobExecutionSerializer(); self::assertSame($expectedSerializedJobExecution, $serializer->serialize($jobExecutionToSerialize)); } - /** - * @dataProvider sets - */ + #[DataProvider('sets')] public function testDenormalize(JobExecution $expectedjobExecution, string $serializedJobExecution): void { $serializer = new JsonJobExecutionSerializer(); @@ -32,7 +29,7 @@ public function testDenormalize(JobExecution $expectedjobExecution, string $seri ); } - public function sets(): \Generator + public static function sets(): \Generator { yield [ require __DIR__ . '/fixtures/minimal.object.php', @@ -44,9 +41,7 @@ public function sets(): \Generator ]; } - /** - * @dataProvider invalidJobExecutions - */ + #[DataProvider('invalidJobExecutions')] public function testSerializeThrowExceptionOnFailure(JobExecution $jobExecutionToSerialize): void { $this->expectException(RuntimeException::class); @@ -55,16 +50,14 @@ public function testSerializeThrowExceptionOnFailure(JobExecution $jobExecutionT $serializer->serialize($jobExecutionToSerialize); } - public function invalidJobExecutions(): \Generator + public static function invalidJobExecutions(): \Generator { $jobExecutionWithResource = JobExecution::createRoot('123', 'test'); $jobExecutionWithResource->getSummary()->set('fail', \fopen(__FILE__, 'r')); yield [$jobExecutionWithResource]; } - /** - * @dataProvider invalidJSON - */ + #[DataProvider('invalidJSON')] public function testUnSerializeThrowExceptionOnFailure(string $json): void { $this->expectException(RuntimeException::class); @@ -73,7 +66,7 @@ public function testUnSerializeThrowExceptionOnFailure(string $json): void $serializer->unserialize($json); } - public function invalidJSON(): \Generator + public static function invalidJSON(): \Generator { yield ['malformed JSON']; yield ['"json string"']; diff --git a/src/batch/tests/Storage/FilesystemJobExecutionStorageTest.php b/src/batch/tests/Storage/FilesystemJobExecutionStorageTest.php index 67009463..2cf1aada 100644 --- a/src/batch/tests/Storage/FilesystemJobExecutionStorageTest.php +++ b/src/batch/tests/Storage/FilesystemJobExecutionStorageTest.php @@ -4,6 +4,7 @@ namespace Yokai\Batch\Tests\Storage; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\Prophecy\ObjectProphecy; @@ -107,9 +108,7 @@ public function testRetrieve(): void self::assertSame($jobExecution, $this->createStorage()->retrieve('export', '123456789')); } - /** - * @dataProvider list - */ + #[DataProvider('list')] public function testList(string $jobName, array $expectedCouples): void { $storage = $this->createStorage( @@ -120,7 +119,7 @@ public function testList(string $jobName, array $expectedCouples): void self::assertExecutions($expectedCouples, $storage->list($jobName)); } - public function list(): \Generator + public static function list(): \Generator { yield [ 'export', @@ -139,9 +138,7 @@ public function list(): \Generator ]; } - /** - * @dataProvider query - */ + #[DataProvider('query')] public function testQueryWithProvider(QueryBuilder $query, array $expectedCouples): void { $storage = $this->createStorage( @@ -153,7 +150,7 @@ public function testQueryWithProvider(QueryBuilder $query, array $expectedCouple self::assertEquals(\count($expectedCouples), $storage->count($query->getQuery())); } - public function query(): \Generator + public static function query(): \Generator { yield 'No filter' => [ new QueryBuilder(), diff --git a/src/batch/tests/Storage/QueryBuilderTest.php b/src/batch/tests/Storage/QueryBuilderTest.php index d13ff68a..98701125 100644 --- a/src/batch/tests/Storage/QueryBuilderTest.php +++ b/src/batch/tests/Storage/QueryBuilderTest.php @@ -5,6 +5,7 @@ namespace Yokai\Batch\Tests\Storage; use Exception; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Yokai\Batch\BatchStatus; use Yokai\Batch\Exception\UnexpectedValueException; @@ -14,9 +15,7 @@ class QueryBuilderTest extends TestCase { - /** - * @dataProvider valid - */ + #[DataProvider('valid')] public function testValid(callable $factory, Query $expected): void { /** @var QueryBuilder $builder */ @@ -34,7 +33,7 @@ public function testValid(callable $factory, Query $expected): void self::assertSame($expected->offset(), $actual->offset()); } - public function valid(): \Generator + public static function valid(): \Generator { /** default values for {@see Query::__construct} */ $jobNames = []; @@ -171,16 +170,14 @@ public function valid(): \Generator ]; } - /** - * @dataProvider invalid - */ + #[DataProvider('invalid')] public function testInvalid(callable $factory, Exception $expected): void { $this->expectExceptionObject($expected); $factory(); } - public function invalid(): \Generator + public static function invalid(): \Generator { yield 'QueryBuilder::jobs expect string array' => [ fn() => (new QueryBuilder())->jobs(['string', 666]), diff --git a/tests/convention/Comment/ClassCommentsTest.php b/tests/convention/Comment/ClassCommentsTest.php index 5c51ca0f..3c440c1b 100644 --- a/tests/convention/Comment/ClassCommentsTest.php +++ b/tests/convention/Comment/ClassCommentsTest.php @@ -4,6 +4,7 @@ namespace Yokai\Batch\Sources\Tests\Convention\Comment; +use PHPUnit\Framework\Attributes\DataProvider; use ReflectionClass; use Yokai\Batch\Sources\Tests\Convention\Autoload; use Yokai\Batch\Sources\Tests\Convention\Package; @@ -11,9 +12,7 @@ final class ClassCommentsTest extends CommentsTestCase { - /** - * @dataProvider classes - */ + #[DataProvider('classes')] public function testAllClassesHasComment(ReflectionClass $class): void { self::assertNotFalse( @@ -22,15 +21,13 @@ public function testAllClassesHasComment(ReflectionClass $class): void ); } - /** - * @dataProvider classes - */ + #[DataProvider('classes')] public function testAllSeeDocAreSurroundedWithBrackets(ReflectionClass $class): void { self::assertAllSeeDocAreSurroundedWithBrackets((string)$class->getDocComment()); } - public function classes(): iterable + public static function classes(): iterable { /** @var Package $package */ foreach (Packages::listYokaiPackages() as $package) { diff --git a/tests/convention/Comment/MethodCommentsTest.php b/tests/convention/Comment/MethodCommentsTest.php index 7b35194b..c6310ee1 100644 --- a/tests/convention/Comment/MethodCommentsTest.php +++ b/tests/convention/Comment/MethodCommentsTest.php @@ -4,6 +4,7 @@ namespace Yokai\Batch\Sources\Tests\Convention\Comment; +use PHPUnit\Framework\Attributes\DataProvider; use ReflectionClass; use ReflectionMethod; use Yokai\Batch\Sources\Tests\Convention\Autoload; @@ -12,9 +13,7 @@ final class MethodCommentsTest extends CommentsTestCase { - /** - * @dataProvider publicMethods - */ + #[DataProvider('publicMethods')] public function testAllPublicMethodsHasComment(ReflectionMethod $method): void { // Only true comments are relevant, phpdoc is not. @@ -31,15 +30,13 @@ public function testAllPublicMethodsHasComment(ReflectionMethod $method): void ); } - /** - * @dataProvider publicMethods - */ + #[DataProvider('publicMethods')] public function testAllSeeDocAreSurroundedWithBrackets(ReflectionMethod $method): void { self::assertAllSeeDocAreSurroundedWithBrackets((string)$method->getDocComment()); } - public function publicMethods(): iterable + public static function publicMethods(): iterable { $magicMethods = \array_fill_keys(['__construct', '__invoke'], true); @@ -84,18 +81,18 @@ public function publicMethods(): iterable continue; } - yield $this->methodFQCN($method) => [$method]; + yield self::methodFQCN($method) => [$method]; } } } } - private function methodFQCN(ReflectionMethod $method): string + private static function methodFQCN(ReflectionMethod $method): string { return "{$method->getDeclaringClass()->getName()}::{$method->getName()}"; } - private function fileAndLine(ReflectionMethod $method): string + private static function fileAndLine(ReflectionMethod $method): string { return "{$method->getDeclaringClass()->getFileName()}:{$method->getStartLine()}"; } diff --git a/tests/convention/Dependency/PackagesTest.php b/tests/convention/Dependency/PackagesTest.php index 22b6e48f..e2b21719 100644 --- a/tests/convention/Dependency/PackagesTest.php +++ b/tests/convention/Dependency/PackagesTest.php @@ -4,6 +4,7 @@ namespace Yokai\Batch\Sources\Tests\Convention\Dependency; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Yokai\Batch\Sources\Tests\Convention\Autoload; use Yokai\Batch\Sources\Tests\Convention\Package; @@ -24,9 +25,8 @@ final class PackagesTest extends TestCase /** * Every individual package must declare explicit dependencies, based on use statements. - * - * @dataProvider packages */ + #[DataProvider('packages')] public function testPackagesAreUsingRequiredClasses(Package $package): void { // Read package's composer.json and extract autoload prefixes of @@ -91,7 +91,7 @@ public function testPackagesAreUsingSameDependencyVersions(): void } } - public function packages(): iterable + public static function packages(): iterable { /** @var Package $package */ foreach (Packages::listYokaiPackages() as $package) { diff --git a/tests/convention/Documentation/DocumentationLinksTest.php b/tests/convention/Documentation/DocumentationLinksTest.php index 324ad36d..a4ee4f2d 100644 --- a/tests/convention/Documentation/DocumentationLinksTest.php +++ b/tests/convention/Documentation/DocumentationLinksTest.php @@ -4,6 +4,7 @@ namespace Yokai\Batch\Sources\Tests\Convention\Documentation; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Yokai\Batch\Job\Item\ItemProcessorInterface; use Yokai\Batch\Job\Item\ItemReaderInterface; @@ -25,9 +26,8 @@ final class DocumentationLinksTest extends TestCase /** * Ensure that all links in Sphinx files points to valid internal resources. - * - * @dataProvider filesWithLinks */ + #[DataProvider('filesWithLinks')] public function testInternalLinksAreValid(DocFile $file): void { /** @var DocLink $link */ @@ -42,7 +42,7 @@ public function testInternalLinksAreValid(DocFile $file): void } } - public function filesWithLinks(): iterable + public static function filesWithLinks(): iterable { /** @var DocFile $file */ foreach (Sphinx::listFiles() as $file) { @@ -55,9 +55,8 @@ public function filesWithLinks(): iterable /** * Ensure that all implementations of some yokai batch interfaces are listed in certain files. - * - * @dataProvider interfaceRules */ + #[DataProvider('interfaceRules')] public function testComponentsAreListed(string $filepath, string $interface): void { $expectedClasses = []; @@ -98,7 +97,7 @@ public function testComponentsAreListed(string $filepath, string $interface): vo ); } - public function interfaceRules(): iterable + public static function interfaceRules(): iterable { yield 'JobInterface' => [ 'docs/docs/core-concepts/job.rst', diff --git a/tests/integration/JobTestCase.php b/tests/integration/JobTestCase.php index b8ab6908..bfaaaa60 100644 --- a/tests/integration/JobTestCase.php +++ b/tests/integration/JobTestCase.php @@ -4,6 +4,7 @@ namespace Yokai\Batch\Sources\Tests\Integration; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Yokai\Batch\BatchStatus; use Yokai\Batch\Factory\JobExecutionFactory; @@ -42,9 +43,7 @@ public static function setUpBeforeClass(): void } } - /** - * @dataProvider variant - */ + #[DataProvider('variant')] public function testExecuteJob(JobExecutionStorageInterface $jobExecutionStorage): void { $job = $this->createJob($jobExecutionStorage); @@ -63,9 +62,9 @@ public function testExecuteJob(JobExecutionStorageInterface $jobExecutionStorage $this->assertAgainstExecution($jobExecutionStorage, $jobExecution); } - public function variant(): \Iterator + public static function variant(): \Iterator { - foreach ($this->storages() as $storage) { + foreach (self::storages() as $storage) { yield [$storage]; } } @@ -116,7 +115,7 @@ private function compareExecutions(JobExecution $jobExecution, JobExecution $sto } } - private function storages(): \Iterator + private static function storages(): \Iterator { yield new FilesystemJobExecutionStorage( new JsonJobExecutionSerializer(), diff --git a/tests/symfony/tests/JobTest.php b/tests/symfony/tests/JobTest.php index f582b2a4..1962dcd4 100644 --- a/tests/symfony/tests/JobTest.php +++ b/tests/symfony/tests/JobTest.php @@ -8,6 +8,7 @@ use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Tools\SchemaTool; use Generator; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\Console\Tester\CommandTester; @@ -16,9 +17,7 @@ final class JobTest extends KernelTestCase { - /** - * @dataProvider configs - */ + #[DataProvider('configs')] public function testUsingCli(string $job, callable $assert): void { $kernel = self::createKernel(); @@ -38,9 +37,7 @@ public function testUsingCli(string $job, callable $assert): void $assert($storage->retrieve($job, $id), $container); } - /** - * @dataProvider configs - */ + #[DataProvider('configs')] public function testUsingLauncher(string $job, callable $assert): void { $container = self::getContainer(); diff --git a/tests/symfony/tests/UserInterfaceTest.php b/tests/symfony/tests/UserInterfaceTest.php index f2e41753..6396b9fc 100644 --- a/tests/symfony/tests/UserInterfaceTest.php +++ b/tests/symfony/tests/UserInterfaceTest.php @@ -4,6 +4,7 @@ namespace Yokai\Batch\Sources\Tests\Symfony\Tests; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\DomCrawler\Crawler; use Symfony\Component\Filesystem\Filesystem; @@ -73,9 +74,7 @@ public function testList(): void } } - /** - * @dataProvider view - */ + #[DataProvider('view')] public function testView(string $job, \Closure $expected): void { $execution = self::$executions[$job]; @@ -115,9 +114,7 @@ static function (Crawler $page) { ]; } - /** - * @dataProvider logs - */ + #[DataProvider('logs')] public function testLogs(string $job, \Closure $expected): void { $execution = self::$executions[$job]; From a28df3749ab66d17faf426cd6c4d0e714ae9c13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20Eugon=C3=A9?= Date: Wed, 7 Jan 2026 16:50:42 +0100 Subject: [PATCH 09/11] Fixed PHPUnit warnings, deprecations and notices --- .../UserInterface/Form/JobFilterTypeTest.php | 4 ++++ .../tests/DenormalizeItemProcessorTest.php | 21 ++++++++++++------- .../tests/NormalizeItemProcessorTest.php | 21 ++++++++++++------- .../DefaultParameterAccessorTest.php | 4 +++- .../ParentJobExecutionAccessorTest.php | 7 +++++-- tests/bootstrap.php | 3 +++ .../Processor/DeveloperProcessor.php | 4 ++-- 7 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/batch-symfony-framework/tests/UserInterface/Form/JobFilterTypeTest.php b/src/batch-symfony-framework/tests/UserInterface/Form/JobFilterTypeTest.php index 1a80cdfc..35b0b995 100644 --- a/src/batch-symfony-framework/tests/UserInterface/Form/JobFilterTypeTest.php +++ b/src/batch-symfony-framework/tests/UserInterface/Form/JobFilterTypeTest.php @@ -16,6 +16,8 @@ final class JobFilterTypeTest extends TypeTestCase { public function testBuild(): void { + $this->dispatcher->expects($this->never()) + ->method('dispatch'); $form = $this->factory->create(JobFilterType::class, new JobFilter()); $view = $form->createView(); @@ -52,6 +54,8 @@ public function testBuild(): void #[DataProvider('submit')] public function testSubmit(array $submit, JobFilter $expected, bool $valid): void { + $this->dispatcher->expects($this->never()) + ->method('dispatch'); $form = $this->factory->create(JobFilterType::class, $actual = new JobFilter()); $form->submit($submit); diff --git a/src/batch-symfony-serializer/tests/DenormalizeItemProcessorTest.php b/src/batch-symfony-serializer/tests/DenormalizeItemProcessorTest.php index 7abb0dbc..8e5fdf4e 100644 --- a/src/batch-symfony-serializer/tests/DenormalizeItemProcessorTest.php +++ b/src/batch-symfony-serializer/tests/DenormalizeItemProcessorTest.php @@ -18,8 +18,8 @@ final class DenormalizeItemProcessorTest extends TestCase { - #[DataProvider('sets')] - public function testProcess(string $type, null|string $format, array $context, $item, $expected): void + #[DataProvider('withExpected')] + public function testProcess(string $type, null|string $format, array $context, mixed $item, mixed $expected): void { $denormalizer = new DummyNormalizer(true, $expected); $processor = new DenormalizeItemProcessor($denormalizer, $type, $format, $context); @@ -27,8 +27,8 @@ public function testProcess(string $type, null|string $format, array $context, $ self::assertSame($expected, $processor->process($item)); } - #[DataProvider('sets')] - public function testUnsupported(string $type, null|string $format, array $context, $item): void + #[DataProvider('withoutExpected')] + public function testUnsupported(string $type, null|string $format, array $context, mixed $item): void { $denormalizer = new DummyNormalizer(false, null); $processor = new DenormalizeItemProcessor($denormalizer, $type, $format, $context); @@ -48,8 +48,8 @@ public function testUnsupported(string $type, null|string $format, array $contex self::assertSame('Unable to denormalize item. Not supported.', $cause->getError()->getMessage()); } - #[DataProvider('sets')] - public function testException(string $type, null|string $format, array $context, $item): void + #[DataProvider('withoutExpected')] + public function testException(string $type, null|string $format, array $context, mixed $item): void { $denormalizer = new FailingNormalizer($exceptionThrown = new UnsupportedException()); $processor = new DenormalizeItemProcessor($denormalizer, $type, $format, $context); @@ -69,7 +69,7 @@ public function testException(string $type, null|string $format, array $context, self::assertSame($exceptionThrown, $cause->getError()); } - public function sets(): Generator + public static function withExpected(): Generator { yield [ 'stdClass', @@ -93,4 +93,11 @@ public function sets(): Generator DateTimeImmutable::createFromFormat(\DATE_RSS, 'Wed, 01 Jan 2020 12:00:00 +0200'), ]; } + + public static function withoutExpected(): Generator + { + foreach (self::withExpected() as $set) { + yield [$set[0], $set[1], $set[2], $set[3]]; + } + } } diff --git a/src/batch-symfony-serializer/tests/NormalizeItemProcessorTest.php b/src/batch-symfony-serializer/tests/NormalizeItemProcessorTest.php index aafd379e..d02ae3eb 100644 --- a/src/batch-symfony-serializer/tests/NormalizeItemProcessorTest.php +++ b/src/batch-symfony-serializer/tests/NormalizeItemProcessorTest.php @@ -18,8 +18,8 @@ final class NormalizeItemProcessorTest extends TestCase { - #[DataProvider('sets')] - public function testProcess(null|string $format, array $context, $item, $expected): void + #[DataProvider('withExpected')] + public function testProcess(null|string $format, array $context, mixed $item, mixed $expected): void { $normalizer = new DummyNormalizer(true, $expected); $processor = new NormalizeItemProcessor($normalizer, $format, $context); @@ -27,8 +27,8 @@ public function testProcess(null|string $format, array $context, $item, $expecte self::assertSame($expected, $processor->process($item)); } - #[DataProvider('sets')] - public function testUnsupported(null|string $format, array $context, $item): void + #[DataProvider('withoutExpected')] + public function testUnsupported(null|string $format, array $context, mixed $item): void { $normalizer = new DummyNormalizer(false, null); $processor = new NormalizeItemProcessor($normalizer, $format, $context); @@ -48,8 +48,8 @@ public function testUnsupported(null|string $format, array $context, $item): voi self::assertSame('Unable to normalize item. Not supported.', $cause->getError()->getMessage()); } - #[DataProvider('sets')] - public function testException(null|string $format, array $context, $item): void + #[DataProvider('withoutExpected')] + public function testException(null|string $format, array $context, mixed $item): void { $normalizer = new FailingNormalizer($exceptionThrown = new BadMethodCallException()); $processor = new NormalizeItemProcessor($normalizer, $format, $context); @@ -69,7 +69,7 @@ public function testException(null|string $format, array $context, $item): void self::assertSame($exceptionThrown, $cause->getError()); } - public function sets(): Generator + public static function withExpected(): Generator { yield [ null, @@ -90,4 +90,11 @@ public function sets(): Generator 'Wed, 01 Jan 2020 12:00:00 +0200', ]; } + + public static function withoutExpected(): Generator + { + foreach (self::withExpected() as $set) { + yield [$set[0], $set[1], $set[2]]; + } + } } diff --git a/src/batch/tests/Job/Parameters/DefaultParameterAccessorTest.php b/src/batch/tests/Job/Parameters/DefaultParameterAccessorTest.php index e1a4c49a..1905fb2a 100644 --- a/src/batch/tests/Job/Parameters/DefaultParameterAccessorTest.php +++ b/src/batch/tests/Job/Parameters/DefaultParameterAccessorTest.php @@ -16,7 +16,9 @@ class DefaultParameterAccessorTest extends TestCase public function testDefaultWhenInnerFails(): void { $inner = $this->createMock(JobParameterAccessorInterface::class); - $inner->method('get')->willThrowException(new CannotAccessParameterException()); + $inner->expects($this->once()) + ->method('get') + ->willThrowException(new CannotAccessParameterException()); $accessor = new DefaultParameterAccessor($inner, 'default value'); self::assertSame('default value', $accessor->get(JobExecution::createRoot('123', 'testing'))); diff --git a/src/batch/tests/Job/Parameters/ParentJobExecutionAccessorTest.php b/src/batch/tests/Job/Parameters/ParentJobExecutionAccessorTest.php index 197e657b..97af6798 100644 --- a/src/batch/tests/Job/Parameters/ParentJobExecutionAccessorTest.php +++ b/src/batch/tests/Job/Parameters/ParentJobExecutionAccessorTest.php @@ -21,7 +21,9 @@ public function test(): void $one->addChildExecution($two); $inner = $this->createMock(JobParameterAccessorInterface::class); - $inner->method('get')->willReturnCallback(fn(JobExecution $execution) => $execution->getJobName()); + $inner->expects($this->atLeastOnce()) + ->method('get') + ->willReturnCallback(fn(JobExecution $execution) => $execution->getJobName()); $accessor = new ParentJobExecutionAccessor($inner); self::assertSame('root', $accessor->get($one)); @@ -37,7 +39,8 @@ public function testNoParent(): void $root->addChildExecution($do); $inner = $this->createMock(JobParameterAccessorInterface::class); - $inner->method('get')->willReturnCallback(fn(JobExecution $execution) => $execution->getJobName()); + $inner->expects($this->never()) + ->method('get'); $accessor = new ParentJobExecutionAccessor($inner); $accessor->get($root); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 6c8853a6..01e9d92b 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -4,10 +4,13 @@ // phpcs:disable PSR1.Files.SideEffects +use Symfony\Component\ErrorHandler\ErrorHandler; use Symfony\Component\Filesystem\Filesystem; require_once __DIR__ . '/../vendor/autoload.php'; +ErrorHandler::register(null, false); + $artifactDir = @getenv('ARTIFACT_DIR'); if (false === $artifactDir) { throw new \LogicException('Missing "ARTIFACT_DIR" env var.'); diff --git a/tests/integration/Processor/DeveloperProcessor.php b/tests/integration/Processor/DeveloperProcessor.php index ea77abf8..2c5631c0 100644 --- a/tests/integration/Processor/DeveloperProcessor.php +++ b/tests/integration/Processor/DeveloperProcessor.php @@ -22,10 +22,10 @@ public function __construct(EntityManager $manager) public function process(mixed $item): Developer { $badges = $this->manager->getRepository(Badge::class) - ->findBy(['label' => \str_getcsv($item['badges'], '|')]) + ->findBy(['label' => \str_getcsv($item['badges'], '|', '"', '\\')]) ; $repositories = $this->manager->getRepository(Repository::class) - ->findBy(['label' => \str_getcsv($item['repositories'], '|')]) + ->findBy(['label' => \str_getcsv($item['repositories'], '|', '"', '\\')]) ; $developer = new Developer(); From cb7e8506333eb0d26d20935d3f98d268f7f08a2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20Eugon=C3=A9?= Date: Thu, 8 Jan 2026 15:16:51 +0100 Subject: [PATCH 10/11] Drop PHP 8.1 & Symfony 6.4 support --- .github/workflows/tests.yml | 4 -- composer.json | 44 ++++++++++---------- src/batch-doctrine-dbal/composer.json | 2 +- src/batch-doctrine-orm/composer.json | 2 +- src/batch-doctrine-persistence/composer.json | 2 +- src/batch-league-flysystem/composer.json | 2 +- src/batch-openspout/composer.json | 4 +- src/batch-symfony-console/composer.json | 6 +-- src/batch-symfony-framework/composer.json | 22 +++++----- src/batch-symfony-messenger/composer.json | 4 +- src/batch-symfony-serializer/composer.json | 4 +- src/batch-symfony-uid/composer.json | 4 +- src/batch-symfony-validator/composer.json | 4 +- src/batch/composer.json | 4 +- 14 files changed, 52 insertions(+), 56 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4dc72668..9d742f76 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,10 +13,6 @@ jobs: strategy: matrix: include: - - php-version: '8.1' - symfony-version: '6.4.*' - - php-version: '8.4' - symfony-version: '6.4.*' - php-version: '8.2' symfony-version: '7.4.*' - php-version: '8.4' diff --git a/composer.json b/composer.json index ee2130ea..9a9a21ac 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "minimum-stability": "dev", "prefer-stable": true, "require": { - "php": "^8.1", + "php": "^8.2", "ext-json": "*", "composer-runtime-api": "^2.0", "doctrine/dbal": "^4.0", @@ -22,35 +22,35 @@ "psr/container": "^1.0", "psr/event-dispatcher": "^1.0", "psr/log": "^3.0", - "symfony/config": "^6.4|^7.4|^8.0", - "symfony/console": "^6.4|^7.4|^8.0", - "symfony/dependency-injection": "^6.4|^7.4|^8.0", - "symfony/form": "^6.4|^7.4|^8.0", - "symfony/http-kernel": "^6.4|^7.4|^8.0", - "symfony/framework-bundle": "^6.4|^7.4|^8.0", - "symfony/messenger": "^6.4|^7.4|^8.0", - "symfony/serializer": "^6.4|^7.4|^8.0", - "symfony/uid": "^6.4|^7.4|^8.0", - "symfony/validator": "^6.4|^7.4|^8.0" + "symfony/config": "^7.4|^8.0", + "symfony/console": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/form": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/framework-bundle": "^7.4|^8.0", + "symfony/messenger": "^7.4|^8.0", + "symfony/serializer": "^7.4|^8.0", + "symfony/uid": "^7.4|^8.0", + "symfony/validator": "^7.4|^8.0" }, "require-dev": { "doctrine/doctrine-bundle": "^2.0|^3.0", "league/flysystem-memory": "^3.0", "phpspec/prophecy-phpunit": "^2.0", "phpstan/phpstan": "^1.4", - "phpunit/phpunit": "^10.0|^12.0", + "phpunit/phpunit": "^11.0|^12.0", "sonata-project/admin-bundle": "^4.0", - "symfony/browser-kit": "^6.4|^7.4|^8.0", - "symfony/css-selector": "^6.4|^7.4|^8.0", - "symfony/filesystem": "^6.4|^7.4|^8.0", - "symfony/finder": "^6.4|^7.4|^8.0", - "symfony/process": "^6.4|^7.4|^8.0", - "symfony/security-bundle": "^6.4|^7.4|^8.0", - "symfony/translation": "^6.4|^7.4|^8.0", - "symfony/twig-bundle": "^6.4|^7.4|^8.0", - "symfony/yaml": "^6.4|^7.4|^8.0", + "symfony/browser-kit": "^7.4|^8.0", + "symfony/css-selector": "^7.4|^8.0", + "symfony/filesystem": "^7.4|^8.0", + "symfony/finder": "^7.4|^8.0", + "symfony/process": "^7.4|^8.0", + "symfony/security-bundle": "^7.4|^8.0", + "symfony/translation": "^7.4|^8.0", + "symfony/twig-bundle": "^7.4|^8.0", + "symfony/yaml": "^7.4|^8.0", "symplify/easy-coding-standard": "^12.5", - "symfony/http-client": "^6.4|^7.4|^8.0" + "symfony/http-client": "^7.4|^8.0" }, "replace": { "yokai/batch": "self.version", diff --git a/src/batch-doctrine-dbal/composer.json b/src/batch-doctrine-dbal/composer.json index 918c43a0..088baf23 100644 --- a/src/batch-doctrine-dbal/composer.json +++ b/src/batch-doctrine-dbal/composer.json @@ -11,7 +11,7 @@ } ], "require": { - "php": "^8.1", + "php": "^8.2", "ext-json": "*", "doctrine/dbal": "^4.0", "doctrine/persistence": "^4.0", diff --git a/src/batch-doctrine-orm/composer.json b/src/batch-doctrine-orm/composer.json index 73e76ac4..d4b36b4a 100644 --- a/src/batch-doctrine-orm/composer.json +++ b/src/batch-doctrine-orm/composer.json @@ -11,7 +11,7 @@ } ], "require": { - "php": "^8.1", + "php": "^8.2", "doctrine/orm": "^3.0", "doctrine/persistence": "^4.0", "yokai/batch": "^0.7.0" diff --git a/src/batch-doctrine-persistence/composer.json b/src/batch-doctrine-persistence/composer.json index e610238b..1409d76e 100644 --- a/src/batch-doctrine-persistence/composer.json +++ b/src/batch-doctrine-persistence/composer.json @@ -11,7 +11,7 @@ } ], "require": { - "php": "^8.1", + "php": "^8.2", "doctrine/persistence": "^4.0", "yokai/batch": "^0.7.0" }, diff --git a/src/batch-league-flysystem/composer.json b/src/batch-league-flysystem/composer.json index 3b6e3a5a..27d35f31 100644 --- a/src/batch-league-flysystem/composer.json +++ b/src/batch-league-flysystem/composer.json @@ -11,7 +11,7 @@ } ], "require": { - "php": "^8.1", + "php": "^8.2", "league/flysystem": "^3.0", "yokai/batch": "^0.7.0" }, diff --git a/src/batch-openspout/composer.json b/src/batch-openspout/composer.json index e34d108f..906a7af8 100644 --- a/src/batch-openspout/composer.json +++ b/src/batch-openspout/composer.json @@ -11,7 +11,7 @@ } ], "require": { - "php": "^8.1", + "php": "^8.2", "openspout/openspout": "^4.0", "yokai/batch": "^0.7.0" }, @@ -22,7 +22,7 @@ }, "require-dev": { "phpunit/phpunit": "^9.5", - "symfony/filesystem": "^6.4|^7.4|^8.0" + "symfony/filesystem": "^7.4|^8.0" }, "autoload-dev": { "psr-4": { diff --git a/src/batch-symfony-console/composer.json b/src/batch-symfony-console/composer.json index 25eeb0e3..a56c0059 100644 --- a/src/batch-symfony-console/composer.json +++ b/src/batch-symfony-console/composer.json @@ -11,9 +11,9 @@ } ], "require": { - "php": "^8.1", + "php": "^8.2", "ext-json": "*", - "symfony/console": "^6.4|^7.4|^8.0", + "symfony/console": "^7.4|^8.0", "yokai/batch": "^0.7.0" }, "autoload": { @@ -24,7 +24,7 @@ "require-dev": { "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "symfony/process": "^6.4|^7.4|^8.0" + "symfony/process": "^7.4|^8.0" }, "autoload-dev": { "psr-4": { diff --git a/src/batch-symfony-framework/composer.json b/src/batch-symfony-framework/composer.json index 475e24b7..f0b112c3 100644 --- a/src/batch-symfony-framework/composer.json +++ b/src/batch-symfony-framework/composer.json @@ -11,13 +11,13 @@ } ], "require": { - "php": "^8.1", + "php": "^8.2", "composer-runtime-api": "^2.0", - "symfony/config": "^6.4|^7.4|^8.0", - "symfony/console": "^6.4|^7.4|^8.0", - "symfony/dependency-injection": "^6.4|^7.4|^8.0", - "symfony/http-kernel": "^6.4|^7.4|^8.0", - "symfony/framework-bundle": "^6.4|^7.4|^8.0", + "symfony/config": "^7.4|^8.0", + "symfony/console": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/framework-bundle": "^7.4|^8.0", "yokai/batch": "^0.7.0", "psr/log": "^1.0|^2.0|^3.0" }, @@ -28,11 +28,11 @@ }, "require-dev": { "sonata-project/admin-bundle": "^4.0", - "symfony/filesystem": "^6.4|^7.4|^8.0", - "symfony/form": "^6.4|^7.4|^8.0", - "symfony/security-bundle": "^6.4|^7.4|^8.0", - "symfony/translation": "^6.4|^7.4|^8.0", - "symfony/twig-bundle": "^6.4|^7.4|^8.0", + "symfony/filesystem": "^7.4|^8.0", + "symfony/form": "^7.4|^8.0", + "symfony/security-bundle": "^7.4|^8.0", + "symfony/translation": "^7.4|^8.0", + "symfony/twig-bundle": "^7.4|^8.0", "phpunit/phpunit": "^9.5" }, "suggest": { diff --git a/src/batch-symfony-messenger/composer.json b/src/batch-symfony-messenger/composer.json index 7d3951ff..2a04b9f0 100644 --- a/src/batch-symfony-messenger/composer.json +++ b/src/batch-symfony-messenger/composer.json @@ -11,8 +11,8 @@ } ], "require": { - "php": "^8.1", - "symfony/messenger": "^6.4|^7.4|^8.0", + "php": "^8.2", + "symfony/messenger": "^7.4|^8.0", "yokai/batch": "^0.7.0" }, "autoload": { diff --git a/src/batch-symfony-serializer/composer.json b/src/batch-symfony-serializer/composer.json index d7d6a735..20b6419a 100644 --- a/src/batch-symfony-serializer/composer.json +++ b/src/batch-symfony-serializer/composer.json @@ -11,8 +11,8 @@ } ], "require": { - "php": "^8.1", - "symfony/serializer": "^6.4|^7.4|^8.0", + "php": "^8.2", + "symfony/serializer": "^7.4|^8.0", "yokai/batch": "^0.7.0" }, "autoload": { diff --git a/src/batch-symfony-uid/composer.json b/src/batch-symfony-uid/composer.json index 8faf1eba..eb34e98d 100644 --- a/src/batch-symfony-uid/composer.json +++ b/src/batch-symfony-uid/composer.json @@ -11,8 +11,8 @@ } ], "require": { - "php": "^8.1", - "symfony/uid": "^6.4|^7.4|^8.0", + "php": "^8.2", + "symfony/uid": "^7.4|^8.0", "yokai/batch": "^0.7.0" }, "autoload": { diff --git a/src/batch-symfony-validator/composer.json b/src/batch-symfony-validator/composer.json index fde77431..58fd1911 100644 --- a/src/batch-symfony-validator/composer.json +++ b/src/batch-symfony-validator/composer.json @@ -11,8 +11,8 @@ } ], "require": { - "php": "^8.1", - "symfony/validator": "^6.4|^7.4|^8.0", + "php": "^8.2", + "symfony/validator": "^7.4|^8.0", "yokai/batch": "^0.7.0" }, "autoload": { diff --git a/src/batch/composer.json b/src/batch/composer.json index bb70353f..d4cb5ebf 100644 --- a/src/batch/composer.json +++ b/src/batch/composer.json @@ -10,7 +10,7 @@ } ], "require": { - "php": "^8.1", + "php": "^8.2", "ext-json": "*", "psr/container": "^1.0|^2.0", "psr/log": "^1.0|^2.0|^3.0", @@ -24,7 +24,7 @@ "require-dev": { "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "symfony/filesystem": "^6.4|^7.4|^8.0" + "symfony/filesystem": "^7.4|^8.0" }, "autoload-dev": { "psr-4": { From 10f7ff117d5a4b5173047ae3efb67a4bbb8bce4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20Eugon=C3=A9?= Date: Wed, 14 Jan 2026 14:20:15 +0100 Subject: [PATCH 11/11] Ignore deprecated parts of DoctrineDBALJobExecutionStorage from coverage --- .../src/DoctrineDBALJobExecutionStorage.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php b/src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php index 5b97d14b..f700ab8b 100644 --- a/src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php +++ b/src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php @@ -210,7 +210,7 @@ private function getSchema(): Schema new PrimaryKeyConstraint(null, [new UnqualifiedName(Identifier::unquoted('id'))], false), ); } else { - $table->setPrimaryKey(['id']); + $table->setPrimaryKey(['id']); // @codeCoverageIgnore deprecated method, untested in latest versions } $table->addIndex(['job_name']); $table->addIndex(['status']); @@ -394,8 +394,10 @@ private function addWheres(Query $query, QueryBuilder $qb): array */ private function getAssetName(AbstractAsset $asset): string { - return $asset instanceof NamedObject - ? $asset->getObjectName()->toString() - : $asset->getName(); + if ($asset instanceof NamedObject) { + return $asset->getObjectName()->toString(); + } + + return $asset->getName(); // @codeCoverageIgnore deprecated method, untested in latest versions } }