From cd94796538f1d560727e16095537bb51a8a9dcd3 Mon Sep 17 00:00:00 2001 From: Luca Tumedei Date: Mon, 29 Jul 2024 08:59:49 +0200 Subject: [PATCH] refactor(WPTestCase) update to support PHPUnit 10 --- composer.json | 1 + src/TestCase/WPTestCase.php | 90 ++++-- ...rolTestCaseOverridingTestCasePHPUnit10.php | 33 +++ tests/_support/StubClassFactory.php | 173 +++++++++--- .../_generated/WploaderTesterActions.php | 2 +- .../lucatume/WPBrowser/Command/RunAllTest.php | 2 + .../Extension/DockerComposeControllerTest.php | 10 +- .../WPBrowser/Module/WPFilesystemTest.php | 18 +- .../WPBrowser/Module/WPLoaderTest.php | 264 ++++++++++++++---- tests/wploadersuite/BackupControlTest.php | 60 ++++ 10 files changed, 511 insertions(+), 142 deletions(-) create mode 100644 tests/_data/files/BackupControlTestCaseOverridingTestCasePHPUnit10.php create mode 100644 tests/wploadersuite/BackupControlTest.php diff --git a/composer.json b/composer.json index 7dd4a581e..3a0fdd003 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "ext-curl": "*", "ext-zip": "*", "composer-runtime-api": "^2.2", + "phpunit/phpunit": "<=12.0.0", "codeception/codeception": "^5.0", "codeception/module-asserts": "^2.0 || ^3.0", "codeception/module-phpbrowser": "^2.0 || ^3.0", diff --git a/src/TestCase/WPTestCase.php b/src/TestCase/WPTestCase.php index 607220788..f3f1e8e63 100644 --- a/src/TestCase/WPTestCase.php +++ b/src/TestCase/WPTestCase.php @@ -8,10 +8,12 @@ use Codeception\Module; use Codeception\Test\Unit; use lucatume\WPBrowser\Module\WPQueries; +use ReflectionClass; use ReflectionException; use ReflectionMethod; use ReflectionProperty; use WP_UnitTestCase; +use PHPUnit\Runner\Version as PHPUnitVersion; /** * @method static commit_transaction() @@ -140,7 +142,7 @@ class WPTestCase extends Unit ]; /** - * Backup, and reset, static class attributes between tests. + * Backup, and reset, static class attributes between tests for PHPUnit < 10.0.0. * * @var bool */ @@ -148,6 +150,7 @@ class WPTestCase extends Unit /** * A list of static attributes that should not be backed up as they are wired to explode when doing so. + * PHPUnit < 10.0.0. * * @var array> */ @@ -170,17 +173,11 @@ class WPTestCase extends Unit private ?float $requestTimeFloat = null; private ?int $requestTime = null; - /** - * @param array $data - * @param string $dataName - * @throws ReflectionException - */ - public function __construct(?string $name = null, array $data = [], $dataName = '') + private function initBackupGlobalsProperties():void { global $_wpTestsBackupGlobals, - $_wpTestsBackupGlobalsExcludeList, - $_wpTestsBackupStaticAttributes, - $_wpTestsBackupStaticAttributesExcludeList; + $_wpTestsBackupGlobalsExcludeList; + $phpunitVersion = (int)PHPUnitVersion::series(); $backupGlobalsReflectionProperty = new ReflectionProperty($this, 'backupGlobals'); $backupGlobalsReflectionProperty->setAccessible(true); @@ -189,12 +186,13 @@ public function __construct(?string $name = null, array $data = [], $dataName = $this->backupGlobals = $_wpTestsBackupGlobals; } - if (property_exists($this, 'backupGlobalsExcludeList')) { - $backupGlobalsExcludeListReflectionProperty = new ReflectionProperty($this, 'backupGlobalsExcludeList'); - } else { + if ($phpunitVersion < 9) { // Older versions of PHPUnit. $backupGlobalsExcludeListReflectionProperty = new ReflectionProperty($this, 'backupGlobalsBlacklist'); + } else { + $backupGlobalsExcludeListReflectionProperty = new ReflectionProperty($this, 'backupGlobalsExcludeList'); } + $backupGlobalsExcludeListReflectionProperty->setAccessible(true); $isDefinedInThis = $backupGlobalsExcludeListReflectionProperty->getDeclaringClass() ->getName() !== WPTestCase::class; @@ -207,8 +205,16 @@ public function __construct(?string $name = null, array $data = [], $dataName = $_wpTestsBackupGlobalsExcludeList ); } + } + + private function initBackupStaticPropertiesForPHPUnit( + string $backupStaticAttributesPropertyName, + string $backupStaticAttributesExcludeListPropertyName + ): void { + global $_wpTestsBackupStaticAttributes, + $_wpTestsBackupStaticAttributesExcludeList; - $backupStaticAttributesReflectionProperty = new ReflectionProperty($this, 'backupStaticAttributes'); + $backupStaticAttributesReflectionProperty = new ReflectionProperty($this, $backupStaticAttributesPropertyName); $backupStaticAttributesReflectionProperty->setAccessible(true); $isDefinedInThis = $backupStaticAttributesReflectionProperty->getDeclaringClass() ->getName() !== WPTestCase::class; @@ -216,18 +222,10 @@ public function __construct(?string $name = null, array $data = [], $dataName = $this->backupStaticAttributes = $_wpTestsBackupStaticAttributes; } - if (property_exists($this, 'backupStaticAttributesExcludeList')) { - $backupStaticAttributesExcludeListReflectionProperty = new ReflectionProperty( - $this, - 'backupStaticAttributesExcludeList' - ); - } else { - // Older versions of PHPUnit. - $backupStaticAttributesExcludeListReflectionProperty = new ReflectionProperty( - $this, - 'backupStaticAttributesBlacklist' - ); - } + $backupStaticAttributesExcludeListReflectionProperty = new ReflectionProperty( + $this, + $backupStaticAttributesExcludeListPropertyName + ); $backupStaticAttributesExcludeListReflectionProperty->setAccessible(true); $isDefinedInThis = $backupStaticAttributesExcludeListReflectionProperty->getDeclaringClass() ->getName() !== WPTestCase::class; @@ -240,6 +238,44 @@ public function __construct(?string $name = null, array $data = [], $dataName = $_wpTestsBackupStaticAttributesExcludeList ); } + } + + private function initBackupStaticPropertiesForPHPUnitGte10(): void + { + global $_wpTestsBackupStaticAttributes, + $_wpTestsBackupStaticAttributesExcludeList; + + $backupStaticProperties = property_exists($this, 'backupStaticProperties') ? + $this->backupStaticProperties : + $_wpTestsBackupStaticAttributes; + // @phpstan-ignore-next-line exists in PHPUnit >= 10.0.0 + $this->setBackupStaticProperties($backupStaticProperties); + + $backupStaticPropertiesExcludeList = property_exists($this, 'backupStaticPropertiesExcludeList') ? + $this->backupStaticPropertiesExcludeList : + array_merge($this->backupStaticAttributesExcludeList, $_wpTestsBackupStaticAttributesExcludeList); + // @phpstan-ignore-next-line exists in PHPUnit >= 10.0.0 + $this->setBackupStaticPropertiesExcludeList($backupStaticPropertiesExcludeList); + } + + /** + * @param array $data + * @param string $dataName + * @throws ReflectionException + */ + public function __construct(?string $name = null, array $data = [], $dataName = '') + { + $this->initBackupGlobalsProperties(); + + $phpunitVersion = (int)PHPUnitVersion::series(); + + if ($phpunitVersion < 9) { + $this->initBackupStaticPropertiesForPHPUnit('backupStaticAttributes', 'backupStaticAttributesBlacklist'); + } elseif ($phpunitVersion === 9) { + $this->initBackupStaticPropertiesForPHPUnit('backupStaticAttributes', 'backupStaticAttributesExcludeList'); + } else { + $this->initBackupStaticPropertiesForPHPUnitGte10(); + } parent::__construct($name ?: 'testMethod', $data, $dataName); } @@ -376,7 +412,7 @@ private function isCoreTestCaseProperty(string $name): bool if ($this->coreTestCaseProperties === null) { $this->coreTestCaseProperties = array_map( static fn(ReflectionProperty $p) => $p->getName(), - (new \ReflectionClass(self::getCoreTestCase()))->getProperties() + (new ReflectionClass(self::getCoreTestCase()))->getProperties() ); } diff --git a/tests/_data/files/BackupControlTestCaseOverridingTestCasePHPUnit10.php b/tests/_data/files/BackupControlTestCaseOverridingTestCasePHPUnit10.php new file mode 100644 index 000000000..1a82d83e8 --- /dev/null +++ b/tests/_data/files/BackupControlTestCaseOverridingTestCasePHPUnit10.php @@ -0,0 +1,33 @@ +_before(); + } + + public function testBackupGlobalsIsFalse(): void + { + $this->assertFalse($this->backupGlobals); + } + + public function testWillAlterStoreStaticAttribute(): void + { + BackupControlTestCaseOverridingStore::$staticAttribute = 'updated_value'; + $this->assertTrue(true); // Useless assertion to avoid the test to be marked as risky. } + } +} diff --git a/tests/_support/StubClassFactory.php b/tests/_support/StubClassFactory.php index 0ebb8c234..c7d1b01de 100644 --- a/tests/_support/StubClassFactory.php +++ b/tests/_support/StubClassFactory.php @@ -5,74 +5,129 @@ use Codeception\Stub; use Exception; use lucatume\WPBrowser\Utils\Property; -use PHPUnit\Event\Runtime\PHPUnit; -use PHPUnit\Runner\Version; +use PHPUnit\Runner\Version as PHPUnitVersion; use ReflectionException; use ReflectionMethod; class StubClassFactory { - private static ?int $phpunitVersion = null; - private static string $classTemplate = 'class %1$s extends %2$s + private static string $classTemplatePhpUnitLt10 = 'class %1$s extends %2$s { public function __construct(%3$s) { - $this->_stub = %4$s::connectInvocationMocker($this); + $this->__phpunit_originalObject = %4$s::getPhpunitOriginalObject(%1$s"); + $this->__phpunit_returnValueGeneration = %4$s::getPhpunitReturnValueGeneration("%1$s"); + $this->__phpunit_invocationMocker = %4$s::getPhpunitInvocationMocker("%1$s"); %4$s::assertConstructorConditions("%1$s", func_get_args()); + %4$s::setMockForClassName("%1$s", $this); } }'; - private static array $stubParametersByClassName = []; + private static string $classTemplatePhpUnitEq10 = 'class %1$s extends %2$s +{ + public function __construct(%3$s) + { + $this->__phpunit_returnValueGeneration = %4$s::getPhpunitReturnValueGeneration("%1$s"); + $this->__phpunit_invocationMocker = %4$s::getPhpunitInvocationMocker("%1$s"); + %4$s::assertConstructorConditions("%1$s", func_get_args()); + %4$s::setMockForClassName("%1$s", $this); + } +}'; + private static string $classTemplatePhpUnitGt10 = 'class %1$s extends %2$s +{ + use \PHPUnit\Framework\MockObject\StubApi; + + public function __construct(%3$s) + { + $this->__phpunit_state = %4$s::getPHPUnitStateObject("%1$s"); + %4$s::assertConstructorConditions("%1$s", func_get_args()); + %4$s::setMockForClassName("%1$s", $this); + } +}'; + /** + * @var array + */ private static array $constructorAssertions = []; + /** + * @var array + */ + private static mixed $stubByClassName = []; + /** + * @var array + */ + private static array $mockByClassName = []; + + public static function setMockForClassName(string $mockClassName, object $mock): void + { + self::$mockByClassName[$mockClassName] = $mock; + } + public static function tearDown(): void { - self::$stubParametersByClassName = []; + self::$stubByClassName = []; self::$constructorAssertions = []; + self::$mockByClassName = []; } - private static function getPHPUnitVersion(): int + /** + * @throws ReflectionException + */ + public static function getPhpunitOriginalObject(string $mockClassName): object { - if (self::$phpunitVersion === null) { - self::$phpunitVersion = class_exists('PHPUnit\Runner\Version') ? - (int)\PHPUnit\Runner\Version::id() - : (int)\PHPUnit_Runner_Version::id(); + $value = Property::readPrivate(self::$stubByClassName[$mockClassName], '__phpunit_originalObject'); + + if (!is_object($value)) { + throw new ReflectionException('No original object found for ' . $mockClassName); } - return self::$phpunitVersion; + return $value; } /** - * @throws Exception + * @throws ReflectionException */ - public static function connectInvocationMocker(object $mock): void + public static function getPhpunitReturnValueGeneration(string $mockClassName): object { - $mockClassName = get_class($mock); - [$class, $parameters] = self::$stubParametersByClassName[$mockClassName]; - $stub = Stub::makeEmpty($class, $parameters); - $phpunitVersion = self::getPHPUnitVersion(); + $value = Property::readPrivate(self::$stubByClassName[$mockClassName], '__phpunit_returnValueGeneration'); - if ($phpunitVersion < 10) { - Property::setPrivateProperties($mock, [ - '__phpunit_originalObject' => Property::readPrivate($stub, '__phpunit_originalObject'), - '__phpunit_returnValueGeneration' => Property::readPrivate($stub, '__phpunit_returnValueGeneration'), - '__phpunit_invocationMocker' => Property::readPrivate($stub, '__phpunit_invocationMocker'), - ]); - } elseif ($phpunitVersion === 10) { - Property::setPrivateProperties($mock, [ - '__phpunit_returnValueGeneration' => Property::readPrivate($stub, '__phpunit_returnValueGeneration'), - '__phpunit_invocationMocker' => Property::readPrivate($stub, '__phpunit_invocationMocker'), - ]); - } else { - // PHPUnit >= 10.0.0. - Property::setPrivateProperties( - $mock, - ['__phpunit_state' => Property::readPrivate($stub, '__phpunit_state')] - ); + if (!is_object($value)) { + throw new ReflectionException('No return value generation found for ' . $mockClassName); } - unset($stub); + return $value; } + /** + * @throws ReflectionException + */ + public static function getPhpunitInvocationMocker(string $mockClassName): object + { + $value = Property::readPrivate(self::$stubByClassName[$mockClassName], '__phpunit_invocationMocker'); + + if (!is_object($value)) { + throw new ReflectionException('No invocation mocker found for ' . $mockClassName); + } + + return $value; + } + + /** + * @throws ReflectionException + */ + public static function getPHPUnitStateObject(string $mockClassName): object + { + $value = Property::readPrivate(self::$stubByClassName[$mockClassName], '__phpunit_state'); + + if (!is_object($value)) { + throw new ReflectionException('No PHPUnit state object found for ' . $mockClassName); + } + + return $value; + } + + /** + * @param array $args + */ public static function assertConstructorConditions(string $mockClassName, array $args): void { if (!isset(self::$constructorAssertions[$mockClassName])) { @@ -82,17 +137,22 @@ public static function assertConstructorConditions(string $mockClassName, array } /** - * @throws ReflectionException + * @param class-string $class + * @param array $parameters + * * @throws Exception + * @throws ReflectionException */ public static function makeEmptyClass(string $class, array $parameters): string { $classBasename = basename(str_replace('\\', '/', $class)); $mockClassName = $classBasename . '_' . substr(md5(microtime()), 0, 8); $constructorStringDump = (new ReflectionMethod($class, '__construct'))->__toString(); - preg_match_all('/Parameter #\\d+ \\[ <(?:optional|required)> (?.*) ]/u', + preg_match_all( + '/Parameter #\\d+ \\[ <(?:optional|required)> (?.*) ]/u', $constructorStringDump, - $matches); + $matches + ); $constructorParams = ''; if (!empty($matches)) { $constructorParams = implode( @@ -108,17 +168,42 @@ public static function makeEmptyClass(string $class, array $parameters): string unset($parameters['__construct']); } + foreach ($parameters as &$value) { + if ($value === '__itself') { + $value = fn() => self::getMockByClassName($mockClassName); + } + } + $codeceptionStub = Stub::makeEmpty($class, $parameters); - $classCode = sprintf(self::$classTemplate, + $phpunitVersion = (int)PHPUnitVersion::series(); + if ($phpunitVersion < 10) { + $classTemplate = self::$classTemplatePhpUnitLt10; + } elseif ($phpunitVersion === 10) { + $classTemplate = self::$classTemplatePhpUnitEq10; + } else { + $classTemplate = self::$classTemplatePhpUnitGt10; + } + + $classCode = sprintf( + $classTemplate, $mockClassName, get_class($codeceptionStub), $constructorParams, - self::class); - unset($codeceptionStub); + self::class + ); + eval($classCode); - self::$stubParametersByClassName[$mockClassName] = [$class, $parameters]; + self::$stubByClassName[$mockClassName] = $codeceptionStub; return $mockClassName; } + + /** + * @param string $mockClassName + */ + private static function getMockByClassName(string $mockClassName): object + { + return self::$mockByClassName[$mockClassName]; + } } diff --git a/tests/_support/_generated/WploaderTesterActions.php b/tests/_support/_generated/WploaderTesterActions.php index 28ee75aa8..3e5eb5c5e 100644 --- a/tests/_support/_generated/WploaderTesterActions.php +++ b/tests/_support/_generated/WploaderTesterActions.php @@ -1,4 +1,4 @@ - fn() => yield from ["Running suite\n", "Done\n"], 'isSuccessful' => fn() => true, + 'setTimeout' => '__itself', ]; $this->setClassMock(Process::class, $this->makeEmptyClass(Process::class, $mockParams)); $this->setMethodReturn(Configuration::class, 'suites', ['suite-1', 'suite-2', 'suite-3']); @@ -84,6 +85,7 @@ public function should_return_1_if_any_suite_fails(int $failingSuite, string $ex 'isSuccessful' => function () use ($failingSuite, &$currentSuite) { return $currentSuite++ !== $failingSuite; }, + 'setTimeout' => '__itself', ]; $this->setClassMock(Process::class, $this->makeEmptyClass(Process::class, $mockParams)); $this->setMethodReturn(Configuration::class, 'suites', ['suite-1', 'suite-2', 'suite-3']); diff --git a/tests/unit/lucatume/WPBrowser/Extension/DockerComposeControllerTest.php b/tests/unit/lucatume/WPBrowser/Extension/DockerComposeControllerTest.php index 3885f853b..183e11e05 100644 --- a/tests/unit/lucatume/WPBrowser/Extension/DockerComposeControllerTest.php +++ b/tests/unit/lucatume/WPBrowser/Extension/DockerComposeControllerTest.php @@ -150,7 +150,8 @@ public function should_up_stack_correctly(): void $this->makeEmptyClass(Process::class, [ '__construct' => static function ($command, ...$args) use (&$constructCommands) { $constructCommands[] = $command; - } + }, + 'mustRun' => '__itself' ]) ); @@ -227,6 +228,7 @@ public function should_correctly_handle_stack_lifecycle(): void '__construct' => static function () use (&$constructed) { $constructed++; }, + 'mustRun' => '__itself', 'stop' => 0 ]) ); @@ -283,7 +285,9 @@ public function should_throw_if_docker_compose_start_fails(): void */ public function should_throw_if_running_file_cannot_be_written(): void { - $this->setClassMock(Process::class, $this->makeEmptyClass(Process::class, [])); + $this->setClassMock(Process::class, $this->makeEmptyClass(Process::class, [ + 'mustRun' => '__itself', + ])); $config = ['suites' => ['end2end'], 'compose-file' => 'docker-compose.yml']; $options = []; @@ -341,6 +345,7 @@ public function should_throw_if_running_file_cannot_be_removed_while_stopping(): $this->setClassMock( Process::class, $this->makeEmptyClass(Process::class, [ + 'mustRun' => '__itself', 'stop' => 0 ]) ); @@ -373,6 +378,7 @@ public function should_produce_information_correctly(): void $this->setClassMock( Process::class, $this->makeEmptyClass(Process::class, [ + 'mustRun' => '__itself', 'getOutput' => static function () { return Yaml::dump(['services' => ['foo' => ['ports' => ['8088:80']]]]); }, diff --git a/tests/unit/lucatume/WPBrowser/Module/WPFilesystemTest.php b/tests/unit/lucatume/WPBrowser/Module/WPFilesystemTest.php index 6edf81a4d..ade66ccb7 100644 --- a/tests/unit/lucatume/WPBrowser/Module/WPFilesystemTest.php +++ b/tests/unit/lucatume/WPBrowser/Module/WPFilesystemTest.php @@ -999,7 +999,7 @@ public function it_should_allow_having_a_plugin_with_code(): void $this->assertEquals(Strings::normalizeNewLine($expected), Strings::normalizeNewLine(file_get_contents($pluginFile))); - $sut->_after(new class extends Unit { + $sut->_after(new class('test-test-test') extends Unit { }); $this->assertFileNotExists($pluginFile); @@ -1042,7 +1042,7 @@ public function it_should_allow_having_a_single_file_plugin_with_code(): void $this->assertEquals(Strings::normalizeNewLine($expected), Strings::normalizeNewLine(file_get_contents($pluginFile))); - $sut->_after(new class extends Unit { + $sut->_after(new class('test-test-test') extends Unit { }); $this->assertFileNotExists($pluginFile); @@ -1087,7 +1087,7 @@ public function it_should_allow_having_a_mu_plugin_with_code(): void $this->assertEquals(Strings::normalizeNewLine($expected), Strings::normalizeNewLine(file_get_contents($muPluginFile))); - $sut->_after(new class extends Unit { + $sut->_after(new class('test-test-test') extends Unit { }); $this->assertFileNotExists($muPluginFile); @@ -1139,7 +1139,7 @@ public function it_should_allow_having_a_theme_with_code(): void $this->assertEquals(Strings::normalizeNewLine($expectedIndex), Strings::normalizeNewLine(file_get_contents($themeIndexFile))); - $sut->_after(new class extends Unit { + $sut->_after(new class('test-test-test') extends Unit { }); $this->assertFileNotExists($themeStyleFile); @@ -1195,7 +1195,7 @@ public function it_should_allow_having_a_theme_with_code_and_functions_file(): v $this->assertEquals(Strings::normalizeNewLine($expectedIndex), Strings::normalizeNewLine(file_get_contents($themeFunctionsFile))); - $sut->_after(new class extends Unit { + $sut->_after(new class('test-test-test') extends Unit { }); $this->assertFileNotExists($themeStyleFile); @@ -1242,7 +1242,7 @@ public function should_allow_opening_php_tag_when_having_plugin(): void $this->assertEquals(Strings::normalizeNewLine($expected), Strings::normalizeNewLine(file_get_contents($pluginFile))); - $sut->_after(new class extends Unit { + $sut->_after(new class('test-test-test') extends Unit { }); $this->assertFileNotExists($pluginFile); @@ -1289,7 +1289,7 @@ public function should_allow_the_opening_php_tag_when_having_a_mu_plugin(): void $this->assertEquals(Strings::normalizeNewLine($expected), Strings::normalizeNewLine(file_get_contents($muPluginFile))); - $sut->_after(new class extends Unit { + $sut->_after(new class('test-test-test') extends Unit { }); $this->assertFileNotExists($muPluginFile); @@ -1346,7 +1346,7 @@ public function should_allow_the_opening_php_tag_when_having_a_theme(): void $this->assertEquals(Strings::normalizeNewLine($expectedIndex), Strings::normalizeNewLine(file_get_contents($themeFunctionsFile))); - $sut->_after(new class extends Unit { + $sut->_after(new class('test-test-test') extends Unit { }); $this->assertFileNotExists($themeStyleFile); @@ -1401,7 +1401,7 @@ public function should_allow_using_different_directory_separators_to_have_plugin $this->assertEquals(Strings::normalizeNewLine($expected), Strings::normalizeNewLine(file_get_contents($pluginFile))); - $sut->_after(new class extends Unit { + $sut->_after(new class('test-test-test') extends Unit { }); $this->assertFileNotExists($pluginFile); diff --git a/tests/unit/lucatume/WPBrowser/Module/WPLoaderTest.php b/tests/unit/lucatume/WPBrowser/Module/WPLoaderTest.php index 88bdb64f0..52e42cc1f 100644 --- a/tests/unit/lucatume/WPBrowser/Module/WPLoaderTest.php +++ b/tests/unit/lucatume/WPBrowser/Module/WPLoaderTest.php @@ -30,7 +30,10 @@ use lucatume\WPBrowser\WordPress\InstallationState\Scaffolded; use PHPUnit\Framework\Assert; use PHPUnit\Framework\TestResult; +use PHPUnit\Runner\Version as PHPUnitVersion; +use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry; use stdClass; +use Symfony\Component\VarDumper\VarDumper; use tad\Codeception\SnapshotAssertions\SnapshotAssertions; use UnitTester; use WP_Theme; @@ -127,15 +130,6 @@ public function unsetEnvVars(): void } } - /** - * @return WPLoader - */ - private function module(array $moduleContainerConfig = [], ?array $moduleConfig = null): WPLoader - { - $this->mockModuleContainer = new ModuleContainer(new Di(), $moduleContainerConfig); - return new WPLoader($this->mockModuleContainer, ($moduleConfig ?? $this->config)); - } - /** * It should throw if cannot connect to the database * @@ -157,6 +151,15 @@ public function should_throw_if_cannot_connect_to_the_database(): void $this->module()->_initialize(); } + /** + * @return WPLoader + */ + private function module(array $moduleContainerConfig = [], ?array $moduleConfig = null): WPLoader + { + $this->mockModuleContainer = new ModuleContainer(new Di(), $moduleContainerConfig); + return new WPLoader($this->mockModuleContainer, ($moduleConfig ?? $this->config)); + } + /** * It should throw if wpRootFolder is not valid * @@ -1551,7 +1554,7 @@ public function should_rethrow_on_failure_to_load_a_dump_file(): void $this->expectException(ModuleException::class); $this->assertInIsolation(static function () use ($wpLoader, $dumpFiles) { - uopz_set_return('fopen', function (string $file, ...$args)use($dumpFiles) { + uopz_set_return('fopen', function (string $file, ...$args) use ($dumpFiles) { return in_array($file, $dumpFiles, true) ? false : fopen($file, ...$args); }, true); $wpLoader->_initialize(); @@ -1923,8 +1926,18 @@ public function should_not_backup_globals_by_default(): void 'dbUrl' => $db->getDbUrl(), ]; $wpLoader = $this->module(); + $serializedPhpunitConfiguration = (int)PHPUnitVersion::series() >= 10 ? + serialize(ConfigurationRegistry::get()) + : null; + + $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile, $serializedPhpunitConfiguration) { + if ((int)PHPUnitVersion::series() >= 10) { + $reflector = new \ReflectionClass(ConfigurationRegistry::class); + $instanceProp = $reflector->getProperty('instance'); + $instanceProp->setAccessible(true); + $instanceProp->setValue(unserialize($serializedPhpunitConfiguration)); + } - $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile) { $wpLoader->_initialize(); Assert::assertTrue(function_exists('do_action')); @@ -1932,10 +1945,14 @@ public function should_not_backup_globals_by_default(): void require_once $testcaseFile; $testCase = new \BackupControlTestCase('testBackupGlobalsIsFalse'); - /** @var TestResult $result */ - $result = $testCase->run(); - - Assert::assertTrue($result->wasSuccessful()); + if ((int)PHPUnitVersion::series() >= 10) { + $testCase->run(); + $status = $testCase->status(); + Assert::assertTrue($status->isSuccess()); + } else { + $result = $testCase->run(); + Assert::assertTrue($result->wasSuccessful()); + } }); } @@ -1965,6 +1982,9 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w ); $testcaseFile = codecept_data_dir('files/BackupControlTestCase.php'); $overridingTestCaseFile = codecept_data_dir('files/BackupControlTestCaseOverridingTestCase.php'); + $serializedPhpunitConfiguration = (int)PHPUnitVersion::series() >= 10 ? + serialize(ConfigurationRegistry::get()) + : null; // Set`WPLoader.backupGlobals` to `false`. $this->config = [ @@ -1974,7 +1994,14 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w ]; $wpLoader = $this->module(); - $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile) { + $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile, $serializedPhpunitConfiguration) { + if ((int)PHPUnitVersion::series() >= 10) { + $reflector = new \ReflectionClass(ConfigurationRegistry::class); + $instanceProp = $reflector->getProperty('instance'); + $instanceProp->setAccessible(true); + $instanceProp->setValue(unserialize($serializedPhpunitConfiguration)); + } + $wpLoader->_initialize(); Assert::assertTrue(function_exists('do_action')); @@ -1982,10 +2009,15 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w require_once $testcaseFile; $testCase = new \BackupControlTestCase('testBackupGlobalsIsFalse'); - /** @var TestResult $result */ - $result = $testCase->run(); - - Assert::assertTrue($result->wasSuccessful()); + if ((int)PHPUnitVersion::series() >= 10) { + $testCase->run(); + $status = $testCase->status(); + Assert::assertTrue($status->isSuccess()); + } else { + /** @var TestResult $result */ + $result = $testCase->run(); + Assert::assertTrue($result->wasSuccessful()); + } }); // Set `WPLoader.backupGlobals` to `true`. @@ -1996,7 +2028,13 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w ]; $wpLoader = $this->module(); - $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile) { + $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile, $serializedPhpunitConfiguration) { + if ((int)PHPUnitVersion::series() >= 10) { + $reflector = new \ReflectionClass(ConfigurationRegistry::class); + $instanceProp = $reflector->getProperty('instance'); + $instanceProp->setAccessible(true); + $instanceProp->setValue(unserialize($serializedPhpunitConfiguration)); + } $wpLoader->_initialize(); Assert::assertTrue(function_exists('do_action')); @@ -2004,10 +2042,15 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w require_once $testcaseFile; $testCase = new \BackupControlTestCase('testBackupGlobalsIsTrue'); - /** @var TestResult $result */ - $result = $testCase->run(); - - Assert::assertTrue($result->wasSuccessful()); + if ((int)PHPUnitVersion::series() >= 10) { + $testCase->run(); + $status = $testCase->status(); + Assert::assertTrue($status->isSuccess()); + } else { + /** @var TestResult $result */ + $result = $testCase->run(); + Assert::assertTrue($result->wasSuccessful()); + } }); // Do not set `WPLoader.backupGlobals`, but use the default value of `false`. @@ -2017,7 +2060,13 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w ]; $wpLoader = $this->module(); - $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile) { + $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile, $serializedPhpunitConfiguration) { + if ((int)PHPUnitVersion::series() >= 10) { + $reflector = new \ReflectionClass(ConfigurationRegistry::class); + $instanceProp = $reflector->getProperty('instance'); + $instanceProp->setAccessible(true); + $instanceProp->setValue(unserialize($serializedPhpunitConfiguration)); + } $wpLoader->_initialize(); Assert::assertTrue(function_exists('do_action')); @@ -2025,10 +2074,16 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w require_once $testcaseFile; $testCase = new \BackupControlTestCase('testBackupGlobalsIsFalse'); - /** @var TestResult $result */ - $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + if ((int)PHPUnitVersion::series() >= 10) { + $testCase->run(); + $status = $testCase->status(); + Assert::assertTrue($status->isSuccess()); + } else { + /** @var TestResult $result */ + $result = $testCase->run(); + Assert::assertTrue($result->wasSuccessful()); + } }); // Set `WPLoader.backupGlobals` to `true`, but use a use-case that sets it explicitly to `false`. @@ -2039,7 +2094,13 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w ]; $wpLoader = $this->module(); - $this->assertInIsolation(static function () use ($wpLoader, $overridingTestCaseFile) { + $this->assertInIsolation(static function () use ($wpLoader, $overridingTestCaseFile, $serializedPhpunitConfiguration) { + if ((int)PHPUnitVersion::series() >= 10) { + $reflector = new \ReflectionClass(ConfigurationRegistry::class); + $instanceProp = $reflector->getProperty('instance'); + $instanceProp->setAccessible(true); + $instanceProp->setValue(unserialize($serializedPhpunitConfiguration)); + } $wpLoader->_initialize(); Assert::assertTrue(function_exists('do_action')); @@ -2047,10 +2108,16 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w require_once $overridingTestCaseFile; $testCase = new \BackupControlTestCaseOverridingTestCase('testBackupGlobalsIsFalse'); - /** @var TestResult $result */ - $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + if ((int)PHPUnitVersion::series() >= 10) { + $testCase->run(); + $status = $testCase->status(); + Assert::assertTrue($status->isSuccess()); + } else { + /** @var TestResult $result */ + $result = $testCase->run(); + Assert::assertTrue($result->wasSuccessful()); + } }); $this->config = [ @@ -2060,7 +2127,13 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w $wpLoader = $this->module(); // Test that globals defined before the test runs should not be backed up by default. - $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile) { + $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile, $serializedPhpunitConfiguration) { + if ((int)PHPUnitVersion::series() >= 10) { + $reflector = new \ReflectionClass(ConfigurationRegistry::class); + $instanceProp = $reflector->getProperty('instance'); + $instanceProp->setAccessible(true); + $instanceProp->setValue(unserialize($serializedPhpunitConfiguration)); + } $wpLoader->_initialize(); Assert::assertTrue(function_exists('do_action')); @@ -2072,10 +2145,16 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w require_once $testcaseFile; $testCase = new \BackupControlTestCase('testWillUpdateTheValueOfGlobalVar'); - /** @var TestResult $result */ - $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + if ((int)PHPUnitVersion::series() >= 10) { + $testCase->run(); + $status = $testCase->status(); + Assert::assertTrue($status->isSuccess()); + } else { + /** @var TestResult $result */ + $result = $testCase->run(); + Assert::assertTrue($result->wasSuccessful()); + } // Check that the value of the global variable has been updated. Assert::assertEquals('updated_value', $_wpbrowser_test_global_var); @@ -2089,7 +2168,13 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w $wpLoader = $this->module(); // Test that adding a global to the list of `backupGlobalsExcludeList` will not back it up. - $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile) { + $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile, $serializedPhpunitConfiguration) { + if ((int)PHPUnitVersion::series() >= 10) { + $reflector = new \ReflectionClass(ConfigurationRegistry::class); + $instanceProp = $reflector->getProperty('instance'); + $instanceProp->setAccessible(true); + $instanceProp->setValue(unserialize($serializedPhpunitConfiguration)); + } $wpLoader->_initialize(); Assert::assertTrue(function_exists('do_action')); @@ -2101,10 +2186,16 @@ public function should_allow_controlling_the_backup_of_global_variables_in_the_w require_once $testcaseFile; $testCase = new \BackupControlTestCase('testWillUpdateTheValueOfGlobalVar'); - /** @var TestResult $result */ - $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + if ((int)PHPUnitVersion::series() >= 10) { + $testCase->run(); + $status = $testCase->status(); + Assert::assertTrue($status->isSuccess()); + } else { + /** @var TestResult $result */ + $result = $testCase->run(); + Assert::assertTrue($result->wasSuccessful()); + } // Check that the value of the global variable has been updated. Assert::assertEquals('updated_value', $_wpbrowser_test_global_var); @@ -2136,7 +2227,11 @@ public function should_allow_controlling_the_backup_of_static_attributes_in_the_ 'Test' ); $testcaseFile = codecept_data_dir('files/BackupControlTestCase.php'); - $overridingTestCaseFile = codecept_data_dir('files/BackupControlTestCaseOverridingTestCase.php'); + if ((int)PHPUnitVersion::series() >= 10) { + $overridingTestCaseFile = codecept_data_dir('files/BackupControlTestCaseOverridingTestCasePHPUnit10.php'); + } else { + $overridingTestCaseFile = codecept_data_dir('files/BackupControlTestCaseOverridingTestCase.php'); + } // Set`WPLoader.backupStaticAttributes` to `false`. $this->config = [ @@ -2145,8 +2240,17 @@ public function should_allow_controlling_the_backup_of_static_attributes_in_the_ 'backupStaticAttributes' => false, ]; $wpLoader = $this->module(); - - $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile) { + $serializedPhpunitConfiguration = (int)PHPUnitVersion::series() >= 10 ? + serialize(ConfigurationRegistry::get()) + : null; + + $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile, $serializedPhpunitConfiguration) { + if ((int)PHPUnitVersion::series() >= 10) { + $reflector = new \ReflectionClass(ConfigurationRegistry::class); + $instanceProp = $reflector->getProperty('instance'); + $instanceProp->setAccessible(true); + $instanceProp->setValue(unserialize($serializedPhpunitConfiguration)); + } $wpLoader->_initialize(); Assert::assertTrue(function_exists('do_action')); @@ -2154,10 +2258,16 @@ public function should_allow_controlling_the_backup_of_static_attributes_in_the_ require_once $testcaseFile; $testCase = new \BackupControlTestCase('testWillAlterStoreStaticAttribute'); - /** @var TestResult $result */ - $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + if ((int)PHPUnitVersion::series() >= 10) { + $testCase->run(); + $status = $testCase->status(); + Assert::assertTrue($status->isSuccess()); + } else { + /** @var TestResult $result */ + $result = $testCase->run(); + Assert::assertTrue($result->wasSuccessful()); + } Assert::assertEquals('updated_value', \BackupControlTestCaseStore::$staticAttribute); }); @@ -2169,7 +2279,13 @@ public function should_allow_controlling_the_backup_of_static_attributes_in_the_ ]; $wpLoader = $this->module(); - $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile) { + $this->assertInIsolation(static function () use ($wpLoader, $testcaseFile, $serializedPhpunitConfiguration) { + if ((int)PHPUnitVersion::series() >= 10) { + $reflector = new \ReflectionClass(ConfigurationRegistry::class); + $instanceProp = $reflector->getProperty('instance'); + $instanceProp->setAccessible(true); + $instanceProp->setValue(unserialize($serializedPhpunitConfiguration)); + } $wpLoader->_initialize(); Assert::assertTrue(function_exists('do_action')); @@ -2177,10 +2293,16 @@ public function should_allow_controlling_the_backup_of_static_attributes_in_the_ require_once $testcaseFile; $testCase = new \BackupControlTestCase('testWillAlterStoreStaticAttribute'); - /** @var TestResult $result */ - $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + if ((int)PHPUnitVersion::series() >= 10) { + $testCase->run(); + $status = $testCase->status(); + Assert::assertTrue($status->isSuccess()); + } else { + /** @var TestResult $result */ + $result = $testCase->run(); + Assert::assertTrue($result->wasSuccessful()); + } Assert::assertEquals('updated_value', \BackupControlTestCaseStore::$staticAttribute); }); @@ -2193,7 +2315,13 @@ public function should_allow_controlling_the_backup_of_static_attributes_in_the_ ]; $wpLoader = $this->module(); - $this->assertInIsolation(static function () use ($wpLoader, $overridingTestCaseFile) { + $this->assertInIsolation(static function () use ($wpLoader, $overridingTestCaseFile, $serializedPhpunitConfiguration) { + if ((int)PHPUnitVersion::series() >= 10) { + $reflector = new \ReflectionClass(ConfigurationRegistry::class); + $instanceProp = $reflector->getProperty('instance'); + $instanceProp->setAccessible(true); + $instanceProp->setValue(unserialize($serializedPhpunitConfiguration)); + } $wpLoader->_initialize(); Assert::assertTrue(function_exists('do_action')); @@ -2201,10 +2329,16 @@ public function should_allow_controlling_the_backup_of_static_attributes_in_the_ require_once $overridingTestCaseFile; $testCase = new \BackupControlTestCaseOverridingTestCase('testWillAlterStoreStaticAttribute'); - /** @var TestResult $result */ - $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + if ((int)PHPUnitVersion::series() >= 10) { + $testCase->run(); + $status = $testCase->status(); + Assert::assertTrue($status->isSuccess()); + } else { + /** @var TestResult $result */ + $result = $testCase->run(); + Assert::assertTrue($result->wasSuccessful()); + } Assert::assertEquals('updated_value', \BackupControlTestCaseOverridingStore::$staticAttribute); }); @@ -2222,7 +2356,13 @@ public function should_allow_controlling_the_backup_of_static_attributes_in_the_ $wpLoader = $this->module(); $this->assertInIsolation( - static function () use ($wpLoader, $testcaseFile) { + static function () use ($wpLoader, $testcaseFile, $serializedPhpunitConfiguration) { + if ((int)PHPUnitVersion::series() >= 10) { + $reflector = new \ReflectionClass(ConfigurationRegistry::class); + $instanceProp = $reflector->getProperty('instance'); + $instanceProp->setAccessible(true); + $instanceProp->setValue(unserialize($serializedPhpunitConfiguration)); + } $wpLoader->_initialize(); Assert::assertTrue(function_exists('do_action')); @@ -2230,10 +2370,16 @@ static function () use ($wpLoader, $testcaseFile) { require_once $testcaseFile; $testCase = new \BackupControlTestCase('testWillAlterStoreStaticAttribute'); - /** @var TestResult $result */ - $result = $testCase->run(); - Assert::assertTrue($result->wasSuccessful()); + if ((int)PHPUnitVersion::series() >= 10) { + $testCase->run(); + $status = $testCase->status(); + Assert::assertTrue($status->isSuccess()); + } else { + /** @var TestResult $result */ + $result = $testCase->run(); + Assert::assertTrue($result->wasSuccessful()); + } Assert::assertEquals('updated_value', \BackupControlTestCaseStore::$staticAttribute); Assert::assertEquals('initial_value', \BackupControlTestCaseStore::$staticAttributeTwo); diff --git a/tests/wploadersuite/BackupControlTest.php b/tests/wploadersuite/BackupControlTest.php new file mode 100644 index 000000000..fd9f41619 --- /dev/null +++ b/tests/wploadersuite/BackupControlTest.php @@ -0,0 +1,60 @@ +_before(); + } + + public function testBackupGlobalsIsFalse(): void + { + $this->assertFalse($this->backupGlobals); + } + + public function testBackupGlobalsIsTrue(): void + { + $this->assertTrue($this->backupGlobals); + } + + public function testWillUpdateTheValueOfGlobalVar(): void + { + global $_wpbrowser_test_global_var; + $_wpbrowser_test_global_var = 'updated_value'; + $this->assertTrue(true); // Useless assertion to avoid the test to be marked as risky. + } + + public function testWillAlterStoreStaticAttribute(): void + { + BackupControlTestCaseStore::$staticAttribute = 'updated_value'; + BackupControlTestCaseStore::$staticAttributeTwo = 'updated_value'; + BackupControlTestCaseStore::$staticAttributeThree = 'updated_value'; + BackupControlTestCaseStore::$staticAttributeFour = 'updated_value'; + BackupControlTestCaseStoreTwo::$staticAttribute = 'updated_value'; + BackupControlTestCaseStoreTwo::$staticAttributeTwo = 'updated_value'; + BackupControlTestCaseStoreTwo::$staticAttributeThree = 'updated_value'; + BackupControlTestCaseStoreTwo::$staticAttributeFour = 'updated_value'; + $this->assertTrue(true); // Useless assertion to avoid the test to be marked as risky. + } +}