From b8ac185796e02ee02c6ff1b9dab4f44cd7096a48 Mon Sep 17 00:00:00 2001 From: meszarosrob Date: Mon, 20 Jul 2026 20:34:45 +0300 Subject: [PATCH 1/8] Return the output of WP-CLI --- src/WpCli.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/WpCli.php b/src/WpCli.php index e2c0837..6d2cbfc 100644 --- a/src/WpCli.php +++ b/src/WpCli.php @@ -20,7 +20,7 @@ public function __construct( /** * @param string[] $args */ - public function run(array $args): void + public function run(array $args): string { $extendedArgs = [ $this->wpCliPath->path(), @@ -29,14 +29,19 @@ public function run(array $args): void '--skip-themes', '--path=' . $this->wordPressPath->path(), ]; + $output = ''; $this->symfonyProcessFactory->create($extendedArgs)->run( - static function (string $type, string $data): void { + static function (string $type, string $data) use (&$output): void { if ($type === Process::ERR) { // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped throw new Exception($data); } + + $output .= $data; } ); + + return $output; } } From c2d967ff1e92b2e2e94e301b1c6b431af0c2f27a Mon Sep 17 00:00:00 2001 From: meszarosrob Date: Mon, 20 Jul 2026 20:45:16 +0300 Subject: [PATCH 2/8] Add task to activate dependencies of tested plugins --- inc/container.php | 6 +++ src/Task/ActivateTestedPluginDependencies.php | 52 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/Task/ActivateTestedPluginDependencies.php diff --git a/inc/container.php b/inc/container.php index 8d3438f..3db6f18 100644 --- a/inc/container.php +++ b/inc/container.php @@ -24,6 +24,7 @@ use Syde\WpPhpUnitIntegration\ShutdownFunctionRegisterer; use Syde\WpPhpUnitIntegration\SymfonyProcessFactory; use Syde\WpPhpUnitIntegration\Task\ActivateTestedPlugin; +use Syde\WpPhpUnitIntegration\Task\ActivateTestedPluginDependencies; use Syde\WpPhpUnitIntegration\Task\ActivateTestedTheme; use Syde\WpPhpUnitIntegration\Task\Bundle\Cleanup; use Syde\WpPhpUnitIntegration\Task\Bundle\Load; @@ -130,6 +131,7 @@ $contextual = (match ($container->get(PackageTypeDetector::class)->determine()) { PackageType::Plugin => [ $container->get(SymlinkTestedPlugin::class), + $container->get(ActivateTestedPluginDependencies::class), $container->get(ActivateTestedPlugin::class), ], PackageType::Theme => [ @@ -155,6 +157,10 @@ $container->get(PackageRootPath::class), $container->get(WpCli::class), ), + ActivateTestedPluginDependencies::class => static fn (ContainerInterface $container): ActivateTestedPluginDependencies => new ActivateTestedPluginDependencies( + $container->get(PackageRootPath::class), + $container->get(WpCli::class), + ), ActivateTestedTheme::class => static fn (ContainerInterface $container): ActivateTestedTheme => new ActivateTestedTheme( $container->get(PackageRootPath::class), $container->get(WpCli::class), diff --git a/src/Task/ActivateTestedPluginDependencies.php b/src/Task/ActivateTestedPluginDependencies.php new file mode 100644 index 0000000..9634238 --- /dev/null +++ b/src/Task/ActivateTestedPluginDependencies.php @@ -0,0 +1,52 @@ +packageRootPath->path()); + + $requiredPluginsField = json_decode( + $this->wpCli->run([ + 'plugin', + 'get', + $name, + '--field=requires_plugins', + '--format=json', + ]), + true, + JSON_THROW_ON_ERROR, + ); + + if ($requiredPluginsField === '') { + return; + } + + $requiredPlugins = array_map( + 'trim', + explode(',', $requiredPluginsField), + ); + + foreach ($requiredPlugins as $requiredPlugin) { + $this->wpCli->run([ + 'plugin', + 'activate', + $requiredPlugin, + ]); + } + } +} From 070eb35bdf703b8ed13aa9c977625ff241ee4c60 Mon Sep 17 00:00:00 2001 From: meszarosrob Date: Mon, 20 Jul 2026 20:45:27 +0300 Subject: [PATCH 3/8] Add tests for activating dependencies of tested plugins --- .../ActivateTestedPluginDependenciesTest.php | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 tests/phpunit/Functional/Task/ActivateTestedPluginDependenciesTest.php diff --git a/tests/phpunit/Functional/Task/ActivateTestedPluginDependenciesTest.php b/tests/phpunit/Functional/Task/ActivateTestedPluginDependenciesTest.php new file mode 100644 index 0000000..046a3b3 --- /dev/null +++ b/tests/phpunit/Functional/Task/ActivateTestedPluginDependenciesTest.php @@ -0,0 +1,115 @@ +filesystem->mkdir($this->workspace . '/acme'); + + $wpCli = $this->createMock(WpCli::class); + $wpCli + ->expects($this->once()) + ->method('run') + ->with( + [ + 'plugin', + 'get', + 'acme', + '--field=requires_plugins', + '--format=json', + ], + ) + ->willReturn('""'); + + (new ActivateTestedPluginDependencies( + $this->localDependencyPath($this->workspace . '/acme'), + $wpCli, + ))->execute(); + } + + public function testRequiredPluginIsActivated(): void + { + $this->filesystem->mkdir($this->workspace . '/acme'); + + $wpCli = $this->createMock(WpCli::class); + $wpCli + ->expects($this->exactly(2)) + ->method('run') + ->willReturnMap([ + [ + [ + 'plugin', + 'get', + 'acme', + '--field=requires_plugins', + '--format=json', + ], + '"woocommerce"', + ], + [ + [ + 'plugin', + 'activate', + 'woocommerce', + ], + '', + ], + ]); + + (new ActivateTestedPluginDependencies( + $this->localDependencyPath($this->workspace . '/acme'), + $wpCli, + ))->execute(); + } + + public function testMultipleRequiredPluginsAreActivated(): void + { + $this->filesystem->mkdir($this->workspace . '/acme'); + + $wpCli = $this->createMock(WpCli::class); + $wpCli + ->expects($this->exactly(3)) + ->method('run') + ->willReturnMap([ + [ + [ + 'plugin', + 'get', + 'acme', + '--field=requires_plugins', + '--format=json', + ], + '"woocommerce, woocommerce-subscriptions"', + ], + [ + [ + 'plugin', + 'activate', + 'woocommerce', + ], + '', + ], + [ + [ + 'plugin', + 'activate', + 'woocommerce-subscriptions', + ], + '', + ], + ]); + + (new ActivateTestedPluginDependencies( + $this->localDependencyPath($this->workspace . '/acme'), + $wpCli, + ))->execute(); + } +} From 34de4a9d448cbfdba410aa01799710206f0932ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20R=C3=B3bert?= Date: Tue, 21 Jul 2026 08:46:24 +0300 Subject: [PATCH 4/8] Make things slighly more readable --- src/Task/ActivateTestedPluginDependencies.php | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/Task/ActivateTestedPluginDependencies.php b/src/Task/ActivateTestedPluginDependencies.php index 9634238..b8901e1 100644 --- a/src/Task/ActivateTestedPluginDependencies.php +++ b/src/Task/ActivateTestedPluginDependencies.php @@ -18,35 +18,36 @@ public function __construct( public function execute(): void { - $name = Path::getFilenameWithoutExtension($this->packageRootPath->path()); + $testedPluginName = Path::getFilenameWithoutExtension($this->packageRootPath->path()); + foreach ($this->requiredPlugins($testedPluginName) as $requiredPlugin) { + $this->wpCli->run(['plugin', 'activate', $requiredPlugin]); + } + } + + /** + * @return string[] + */ + private function requiredPlugins(string $pluginName): array + { $requiredPluginsField = json_decode( $this->wpCli->run([ 'plugin', 'get', - $name, + $pluginName, '--field=requires_plugins', '--format=json', ]), - true, - JSON_THROW_ON_ERROR, + flags: JSON_THROW_ON_ERROR, ); - if ($requiredPluginsField === '') { - return; + if (!is_string($requiredPluginsField) || $requiredPluginsField === '') { + return []; } - $requiredPlugins = array_map( + return array_map( 'trim', explode(',', $requiredPluginsField), ); - - foreach ($requiredPlugins as $requiredPlugin) { - $this->wpCli->run([ - 'plugin', - 'activate', - $requiredPlugin, - ]); - } } } From b15aceb98537172e60a72c98702738be8a2d19e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20R=C3=B3bert?= Date: Tue, 21 Jul 2026 11:00:36 +0300 Subject: [PATCH 5/8] Handle some weirded defintions --- src/Task/ActivateTestedPluginDependencies.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Task/ActivateTestedPluginDependencies.php b/src/Task/ActivateTestedPluginDependencies.php index b8901e1..659c6d4 100644 --- a/src/Task/ActivateTestedPluginDependencies.php +++ b/src/Task/ActivateTestedPluginDependencies.php @@ -45,9 +45,9 @@ private function requiredPlugins(string $pluginName): array return []; } - return array_map( - 'trim', - explode(',', $requiredPluginsField), + return array_filter( + array_map('trim', explode(',', $requiredPluginsField)), + static fn (string $value): bool => !empty($value), ); } } From 6c6789a0a7b4bbd5df672672b406f98795970b3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20R=C3=B3bert?= Date: Tue, 21 Jul 2026 11:00:47 +0300 Subject: [PATCH 6/8] Make tests slightly more managable --- .../ActivateTestedPluginDependenciesTest.php | 70 ++++++++++++------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/tests/phpunit/Functional/Task/ActivateTestedPluginDependenciesTest.php b/tests/phpunit/Functional/Task/ActivateTestedPluginDependenciesTest.php index 046a3b3..af37b32 100644 --- a/tests/phpunit/Functional/Task/ActivateTestedPluginDependenciesTest.php +++ b/tests/phpunit/Functional/Task/ActivateTestedPluginDependenciesTest.php @@ -4,13 +4,14 @@ namespace Syde\WpPhpUnitIntegration\Tests\Functional\Task; +use PHPUnit\Framework\Attributes\DataProvider; use Syde\WpPhpUnitIntegration\Task\ActivateTestedPluginDependencies; use Syde\WpPhpUnitIntegration\Tests\FunctionalTestCase; use Syde\WpPhpUnitIntegration\WpCli; final class ActivateTestedPluginDependenciesTest extends FunctionalTestCase { - public function testNothingIsActivatedWhenThereAreNoRequiredPlugins(): void + public function testPluginActivateNotCalledWhenNoRequiredPlugins(): void { $this->filesystem->mkdir($this->workspace . '/acme'); @@ -35,15 +36,27 @@ public function testNothingIsActivatedWhenThereAreNoRequiredPlugins(): void ))->execute(); } - public function testRequiredPluginIsActivated(): void + #[DataProvider('wpCliArgsReturnMapProvider')] + public function testRequiredPluginsAreActivated(array $wpCliArgsReturnMap): void { $this->filesystem->mkdir($this->workspace . '/acme'); $wpCli = $this->createMock(WpCli::class); $wpCli - ->expects($this->exactly(2)) + ->expects($this->exactly(count($wpCliArgsReturnMap))) ->method('run') - ->willReturnMap([ + ->willReturnMap($wpCliArgsReturnMap); + + (new ActivateTestedPluginDependencies( + $this->localDependencyPath($this->workspace . '/acme'), + $wpCli, + ))->execute(); + } + + public static function wpCliArgsReturnMapProvider(): \Generator + { + yield [ + [ [ [ 'plugin', @@ -62,23 +75,34 @@ public function testRequiredPluginIsActivated(): void ], '', ], - ]); + ], + ]; - (new ActivateTestedPluginDependencies( - $this->localDependencyPath($this->workspace . '/acme'), - $wpCli, - ))->execute(); - } - - public function testMultipleRequiredPluginsAreActivated(): void - { - $this->filesystem->mkdir($this->workspace . '/acme'); + yield [ + [ + [ + [ + 'plugin', + 'get', + 'acme', + '--field=requires_plugins', + '--format=json', + ], + '"woocommerce,, ,"', + ], + [ + [ + 'plugin', + 'activate', + 'woocommerce', + ], + '', + ], + ], + ]; - $wpCli = $this->createMock(WpCli::class); - $wpCli - ->expects($this->exactly(3)) - ->method('run') - ->willReturnMap([ + yield [ + [ [ [ 'plugin', @@ -105,11 +129,7 @@ public function testMultipleRequiredPluginsAreActivated(): void ], '', ], - ]); - - (new ActivateTestedPluginDependencies( - $this->localDependencyPath($this->workspace . '/acme'), - $wpCli, - ))->execute(); + ], + ]; } } From 63debc9a26d8747ffe69560c4bb88f3dbf4d9123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20R=C3=B3bert?= Date: Tue, 21 Jul 2026 11:08:14 +0300 Subject: [PATCH 7/8] Fix phpstan --- .../Functional/Task/ActivateTestedPluginDependenciesTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/phpunit/Functional/Task/ActivateTestedPluginDependenciesTest.php b/tests/phpunit/Functional/Task/ActivateTestedPluginDependenciesTest.php index af37b32..6e5a6f7 100644 --- a/tests/phpunit/Functional/Task/ActivateTestedPluginDependenciesTest.php +++ b/tests/phpunit/Functional/Task/ActivateTestedPluginDependenciesTest.php @@ -36,6 +36,9 @@ public function testPluginActivateNotCalledWhenNoRequiredPlugins(): void ))->execute(); } + /** + * @param list, 1: string}> $wpCliArgsReturnMap + */ #[DataProvider('wpCliArgsReturnMapProvider')] public function testRequiredPluginsAreActivated(array $wpCliArgsReturnMap): void { From a4449ebeb4ef29ecc0eb15e65ef87351f1e013ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20R=C3=B3bert?= Date: Mon, 27 Jul 2026 08:42:28 +0300 Subject: [PATCH 8/8] Drop seemingly unneeded filter empty callback --- src/Task/ActivateTestedPluginDependencies.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Task/ActivateTestedPluginDependencies.php b/src/Task/ActivateTestedPluginDependencies.php index 659c6d4..a140e91 100644 --- a/src/Task/ActivateTestedPluginDependencies.php +++ b/src/Task/ActivateTestedPluginDependencies.php @@ -47,7 +47,6 @@ private function requiredPlugins(string $pluginName): array return array_filter( array_map('trim', explode(',', $requiredPluginsField)), - static fn (string $value): bool => !empty($value), ); } }