diff --git a/ChangeLog-12.3.md b/ChangeLog-12.3.md index fa676033317..6837692ba06 100644 --- a/ChangeLog-12.3.md +++ b/ChangeLog-12.3.md @@ -2,6 +2,12 @@ All notable changes of the PHPUnit 12.3 release series are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles. +## [12.3.11] - 2025-09-14 + +### Changed + +* [#6366](https://github.com/sebastianbergmann/phpunit/issues/6366): Exclude `__sleep()` and `__wakeup()` from test double code generation on PHP >= 8.5 + ## [12.3.10] - 2025-09-11 ### Changed @@ -110,6 +116,7 @@ All notable changes of the PHPUnit 12.3 release series are documented in this fi * [#6229](https://github.com/sebastianbergmann/phpunit/issues/6229): `Configuration::excludeTestSuite()`, use `Configuration::excludeTestSuites()` instead * [#6246](https://github.com/sebastianbergmann/phpunit/issues/6246): Using `#[CoversNothing]` on a test method +[12.3.11]: https://github.com/sebastianbergmann/phpunit/compare/12.3.10...12.3.11 [12.3.10]: https://github.com/sebastianbergmann/phpunit/compare/12.3.9...12.3.10 [12.3.9]: https://github.com/sebastianbergmann/phpunit/compare/12.3.8...12.3.9 [12.3.8]: https://github.com/sebastianbergmann/phpunit/compare/12.3.7...12.3.8 diff --git a/composer.json b/composer.json index 255c164a028..2abc211fd23 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,7 @@ "phpunit/php-invoker": "^6.0.0", "phpunit/php-text-template": "^5.0.0", "phpunit/php-timer": "^8.0.0", - "sebastian/cli-parser": "^4.0.0", + "sebastian/cli-parser": "^4.1.0", "sebastian/comparator": "^7.1.3", "sebastian/diff": "^7.0.0", "sebastian/environment": "^8.0.3", diff --git a/composer.lock b/composer.lock index bf35742c106..dec697505a6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0697e07360572838b2e8fe52d85866ad", + "content-hash": "0cb3967f08321287ed41324627a7d07b", "packages": [ { "name": "myclabs/deep-copy", @@ -578,16 +578,16 @@ }, { "name": "sebastian/cli-parser", - "version": "4.0.0", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "6d584c727d9114bcdc14c86711cd1cad51778e7c" + "reference": "8fd93be538992d556aaa45c74570129448a42084" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/6d584c727d9114bcdc14c86711cd1cad51778e7c", - "reference": "6d584c727d9114bcdc14c86711cd1cad51778e7c", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/8fd93be538992d556aaa45c74570129448a42084", + "reference": "8fd93be538992d556aaa45c74570129448a42084", "shasum": "" }, "require": { @@ -599,7 +599,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "4.1-dev" } }, "autoload": { @@ -623,15 +623,27 @@ "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/4.0.0" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/4.1.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/cli-parser", + "type": "tidelift" } ], - "time": "2025-02-07T04:53:50+00:00" + "time": "2025-09-13T14:16:18+00:00" }, { "name": "sebastian/comparator", diff --git a/src/Framework/MockObject/Generator/Generator.php b/src/Framework/MockObject/Generator/Generator.php index f52ba60cab3..4a50ccb0a40 100644 --- a/src/Framework/MockObject/Generator/Generator.php +++ b/src/Framework/MockObject/Generator/Generator.php @@ -64,20 +64,9 @@ final class Generator use TemplateLoader; /** - * @var non-empty-array + * @var null|non-empty-array */ - private const array EXCLUDED_METHOD_NAMES = [ - '__CLASS__' => true, - '__DIR__' => true, - '__FILE__' => true, - '__FUNCTION__' => true, - '__LINE__' => true, - '__METHOD__' => true, - '__NAMESPACE__' => true, - '__TRAIT__' => true, - '__clone' => true, - '__halt_compiler' => true, - ]; + private static ?array $excludedMethodNames = null; /** * @var array @@ -651,7 +640,27 @@ private function canMethodBeDoubled(ReflectionMethod $method): bool private function isMethodNameExcluded(string $name): bool { - return isset(self::EXCLUDED_METHOD_NAMES[$name]); + if (self::$excludedMethodNames === null) { + self::$excludedMethodNames = [ + '__CLASS__' => true, + '__DIR__' => true, + '__FILE__' => true, + '__FUNCTION__' => true, + '__LINE__' => true, + '__METHOD__' => true, + '__NAMESPACE__' => true, + '__TRAIT__' => true, + '__clone' => true, + '__halt_compiler' => true, + ]; + + if (version_compare(PHP_VERSION, '8.5', '>=')) { + self::$excludedMethodNames['__sleep'] = true; + self::$excludedMethodNames['__wakeup'] = true; + } + } + + return isset(self::$excludedMethodNames[$name]); } /** diff --git a/src/Runner/ShutdownHandler.php b/src/Runner/ShutdownHandler.php index 019c245ef03..faecf088c31 100644 --- a/src/Runner/ShutdownHandler.php +++ b/src/Runner/ShutdownHandler.php @@ -46,7 +46,13 @@ private static function register(): void register_shutdown_function( static function (): void { - print rtrim(self::$message) . PHP_EOL; + $message = rtrim(self::$message); + + if ($message === '') { + return; + } + + print $message . PHP_EOL; }, ); } diff --git a/src/Runner/Version.php b/src/Runner/Version.php index 0dc3f4b854d..e3104998581 100644 --- a/src/Runner/Version.php +++ b/src/Runner/Version.php @@ -35,7 +35,7 @@ public static function id(): string } if (self::$version === '') { - self::$version = (new VersionId('12.3.10', dirname(__DIR__, 2)))->asString(); + self::$version = (new VersionId('12.3.11', dirname(__DIR__, 2)))->asString(); } return self::$version; diff --git a/tests/end-to-end/_files/WithExitTest.php b/tests/end-to-end/_files/WithExitTest.php new file mode 100644 index 00000000000..c3e6c641c5e --- /dev/null +++ b/tests/end-to-end/_files/WithExitTest.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestFixture; + +use PHPUnit\Framework\TestCase; + +final class WithExitTest extends TestCase +{ + public function testWithMessage(): void + { + $this->assertTrue(true); + + exit('message'); + } + + public function testWithoutMessage(): void + { + $this->assertTrue(true); + + exit(1); + } +} diff --git a/tests/end-to-end/cli/shutdown-handler-with-message.phpt b/tests/end-to-end/cli/shutdown-handler-with-message.phpt new file mode 100644 index 00000000000..03f69137985 --- /dev/null +++ b/tests/end-to-end/cli/shutdown-handler-with-message.phpt @@ -0,0 +1,29 @@ +--TEST-- +Shutdown Handler: exit(1) +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +Runtime: %s + +messageFatal error: Premature end of PHP process when running PHPUnit\TestFixture\WithExitTest::testWithMessage. +---- diff --git a/tests/end-to-end/cli/shutdown-handler-without-message.phpt b/tests/end-to-end/cli/shutdown-handler-without-message.phpt new file mode 100644 index 00000000000..019a4bb9ece --- /dev/null +++ b/tests/end-to-end/cli/shutdown-handler-without-message.phpt @@ -0,0 +1,29 @@ +--TEST-- +Shutdown Handler: exit('message') +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +Runtime: %s + +Fatal error: Premature end of PHP process when running PHPUnit\TestFixture\WithExitTest::testWithoutMessage. +---- diff --git a/tests/end-to-end/regression/6366.phpt b/tests/end-to-end/regression/6366.phpt new file mode 100644 index 00000000000..98bf01d154b --- /dev/null +++ b/tests/end-to-end/regression/6366.phpt @@ -0,0 +1,21 @@ +--TEST-- +https://github.com/sebastianbergmann/phpunit/issues/6366 +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +Runtime: %s + +. 1 / 1 (100%) + +Time: %s, Memory: %s + +OK (1 test, 0 assertions) diff --git a/tests/end-to-end/regression/6366/Issue6366Test.php b/tests/end-to-end/regression/6366/Issue6366Test.php new file mode 100644 index 00000000000..c393793f16e --- /dev/null +++ b/tests/end-to-end/regression/6366/Issue6366Test.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestFixture\Issue6366; + +use Exception; +use PHPUnit\Framework\Attributes\DoesNotPerformAssertions; +use PHPUnit\Framework\TestCase; + +final class Issue6366Test extends TestCase +{ + #[DoesNotPerformAssertions] + public function testOne(): void + { + $this->createStub(Exception::class); + } +} diff --git a/tools/.phpstan/composer.json b/tools/.phpstan/composer.json index 2e674adf4fd..ecb62168246 100644 --- a/tools/.phpstan/composer.json +++ b/tools/.phpstan/composer.json @@ -1,6 +1,6 @@ { "require-dev": { - "phpstan/phpstan": "^2.1.23", + "phpstan/phpstan": "^2.1.25", "phpstan/extension-installer": "^1.4.3", "phpstan/phpstan-strict-rules": "^2.0.6", "tomasvotruba/type-coverage": "^2.0.2", diff --git a/tools/.phpstan/composer.lock b/tools/.phpstan/composer.lock index e5ce16eeef6..902d6284d5c 100644 --- a/tools/.phpstan/composer.lock +++ b/tools/.phpstan/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1226bfef6211b40ec3c2ef7b457dae05", + "content-hash": "5effadb282f0e5feb14a24a137a23ed5", "packages": [], "packages-dev": [ { @@ -219,16 +219,16 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.23", + "version": "2.1.25", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "a34502adbbd5c2366b5a97679848a5ace4f6f2f5" + "reference": "4087d28bd252895874e174d65e26b2c202ed893a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a34502adbbd5c2366b5a97679848a5ace4f6f2f5", - "reference": "a34502adbbd5c2366b5a97679848a5ace4f6f2f5", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/4087d28bd252895874e174d65e26b2c202ed893a", + "reference": "4087d28bd252895874e174d65e26b2c202ed893a", "shasum": "" }, "require": { @@ -273,7 +273,7 @@ "type": "github" } ], - "time": "2025-09-10T11:42:22+00:00" + "time": "2025-09-12T14:26:42+00:00" }, { "name": "phpstan/phpstan-strict-rules", diff --git a/tools/.phpstan/vendor/composer/installed.json b/tools/.phpstan/vendor/composer/installed.json index 3b7c03c4c98..89ea39e94d7 100644 --- a/tools/.phpstan/vendor/composer/installed.json +++ b/tools/.phpstan/vendor/composer/installed.json @@ -221,17 +221,17 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.23", - "version_normalized": "2.1.23.0", + "version": "2.1.25", + "version_normalized": "2.1.25.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "a34502adbbd5c2366b5a97679848a5ace4f6f2f5" + "reference": "4087d28bd252895874e174d65e26b2c202ed893a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a34502adbbd5c2366b5a97679848a5ace4f6f2f5", - "reference": "a34502adbbd5c2366b5a97679848a5ace4f6f2f5", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/4087d28bd252895874e174d65e26b2c202ed893a", + "reference": "4087d28bd252895874e174d65e26b2c202ed893a", "shasum": "" }, "require": { @@ -240,7 +240,7 @@ "conflict": { "phpstan/phpstan-shim": "*" }, - "time": "2025-09-10T11:42:22+00:00", + "time": "2025-09-12T14:26:42+00:00", "bin": [ "phpstan", "phpstan.phar" diff --git a/tools/.phpstan/vendor/composer/installed.php b/tools/.phpstan/vendor/composer/installed.php index 63ef917249d..1fd260d0e45 100644 --- a/tools/.phpstan/vendor/composer/installed.php +++ b/tools/.phpstan/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => '__root__', 'pretty_version' => '12.3.x-dev', 'version' => '12.3.9999999.9999999-dev', - 'reference' => '72b3b553bf4d7920b22832d045532000ad0c4c63', + 'reference' => '8b89a4ab366be08b1d92369bf39b56d64fef2b3b', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -13,7 +13,7 @@ '__root__' => array( 'pretty_version' => '12.3.x-dev', 'version' => '12.3.9999999.9999999-dev', - 'reference' => '72b3b553bf4d7920b22832d045532000ad0c4c63', + 'reference' => '8b89a4ab366be08b1d92369bf39b56d64fef2b3b', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -47,9 +47,9 @@ 'dev_requirement' => true, ), 'phpstan/phpstan' => array( - 'pretty_version' => '2.1.23', - 'version' => '2.1.23.0', - 'reference' => 'a34502adbbd5c2366b5a97679848a5ace4f6f2f5', + 'pretty_version' => '2.1.25', + 'version' => '2.1.25.0', + 'reference' => '4087d28bd252895874e174d65e26b2c202ed893a', 'type' => 'library', 'install_path' => __DIR__ . '/../phpstan/phpstan', 'aliases' => array(), diff --git a/tools/.phpstan/vendor/phpstan/extension-installer/src/GeneratedConfig.php b/tools/.phpstan/vendor/phpstan/extension-installer/src/GeneratedConfig.php index 4febed04ecd..dfb3eb01854 100644 --- a/tools/.phpstan/vendor/phpstan/extension-installer/src/GeneratedConfig.php +++ b/tools/.phpstan/vendor/phpstan/extension-installer/src/GeneratedConfig.php @@ -12,7 +12,7 @@ final class GeneratedConfig public const EXTENSIONS = array ( 'ergebnis/phpstan-rules' => array ( - 'install_path' => '/Users/sb/Work/OpenSource/phpunit/tools/.phpstan/vendor/ergebnis/phpstan-rules', + 'install_path' => '/usr/local/src/phpunit/tools/.phpstan/vendor/ergebnis/phpstan-rules', 'relative_install_path' => '../../../ergebnis/phpstan-rules', 'extra' => array ( @@ -26,7 +26,7 @@ final class GeneratedConfig ), 'phpstan/phpstan-strict-rules' => array ( - 'install_path' => '/Users/sb/Work/OpenSource/phpunit/tools/.phpstan/vendor/phpstan/phpstan-strict-rules', + 'install_path' => '/usr/local/src/phpunit/tools/.phpstan/vendor/phpstan/phpstan-strict-rules', 'relative_install_path' => '../../phpstan-strict-rules', 'extra' => array ( @@ -40,7 +40,7 @@ final class GeneratedConfig ), 'tomasvotruba/type-coverage' => array ( - 'install_path' => '/Users/sb/Work/OpenSource/phpunit/tools/.phpstan/vendor/tomasvotruba/type-coverage', + 'install_path' => '/usr/local/src/phpunit/tools/.phpstan/vendor/tomasvotruba/type-coverage', 'relative_install_path' => '../../../tomasvotruba/type-coverage', 'extra' => array ( diff --git a/tools/.phpstan/vendor/phpstan/phpstan/bootstrap.php b/tools/.phpstan/vendor/phpstan/phpstan/bootstrap.php index a5d341bfdb3..ac3e269c1f1 100644 --- a/tools/.phpstan/vendor/phpstan/phpstan/bootstrap.php +++ b/tools/.phpstan/vendor/phpstan/phpstan/bootstrap.php @@ -92,6 +92,16 @@ final public static function loadClass(string $class): void { require_once 'phar://' . __DIR__ . '/phpstan.phar/vendor/symfony/polyfill-php81/Php81.php'; require_once 'phar://' . __DIR__ . '/phpstan.phar/vendor/symfony/polyfill-php81/bootstrap.php'; } + + if ( + PHP_VERSION_ID < 80300 + && empty ($GLOBALS['__composer_autoload_files']['662a729f963d39afe703c9d9b7ab4a8c']) + && !class_exists(\Symfony\Polyfill\Php83\Php83::class, false) + ) { + $GLOBALS['__composer_autoload_files']['662a729f963d39afe703c9d9b7ab4a8c'] = true; + require_once 'phar://' . __DIR__ . '/phpstan.phar/vendor/symfony/polyfill-php83/Php83.php'; + require_once 'phar://' . __DIR__ . '/phpstan.phar/vendor/symfony/polyfill-php83/bootstrap.php'; + } } $filename = str_replace('\\', DIRECTORY_SEPARATOR, $class); diff --git a/tools/.phpstan/vendor/phpstan/phpstan/phpstan.phar b/tools/.phpstan/vendor/phpstan/phpstan/phpstan.phar index 3ba5d45a80c..d643c73425a 100755 Binary files a/tools/.phpstan/vendor/phpstan/phpstan/phpstan.phar and b/tools/.phpstan/vendor/phpstan/phpstan/phpstan.phar differ diff --git a/tools/.phpstan/vendor/phpstan/phpstan/phpstan.phar.asc b/tools/.phpstan/vendor/phpstan/phpstan/phpstan.phar.asc index 54ba198d69b..921c1285bdf 100644 --- a/tools/.phpstan/vendor/phpstan/phpstan/phpstan.phar.asc +++ b/tools/.phpstan/vendor/phpstan/phpstan/phpstan.phar.asc @@ -1,16 +1,16 @@ -----BEGIN PGP SIGNATURE----- -iQIzBAABCgAdFiEEynwsejDI6OEnSoR2UcZzBf/C5cAFAmjBY/oACgkQUcZzBf/C -5cCNOBAAitJwWS4FvpgTZ1SaBxsuKlu+AT55StiEfWY7NV7L1AuQUR39T/MPAJr1 -wzWune3Gx+Hlrwx6x2KPW83Xoi41L8xKz1xV1bBGQjj0k4ERdjdnogl/0sBBjnAz -yn4qPYS4MBxhooK+hC0/2lmUHxi58ja48mRn7cP59LUB+pc4ygGWJxaH03Ukb108 -cQGBdek0l2+1frmQZMDPPfYOdCenllNxlo3J+QfIF1+vJNklaHQ42YcgKVsJWtdo -hXRb5JNHs5TcV7phYoZdigtIcNBEwjvBgHU5klTgQgrE10pehwhrMryDw6oc/ckq -GafRJXTR4Px0jdNKSB9Lg7bRCc8umAxk4/K2KFLs15kMEiqglZ+EwYze0LbC9zBc -7uwKkTo4+NwM9pGrCJONQx3Ly9zYnv3Eb8PuRUC4l79gKNAPkr4nrIqNDitS1ky4 -C7cM4TJ8qK+S8BZfqm/tfLwLQGlbaHzHeT8JryjE+wPCKKEfIEExdAStWN89jqn7 -hRtBjWwHH6O4mOpXgfQD/RDhpWO5eN4YhVrGP6KaUk8E04ZFxz5alT4VZCVFwrO/ -t26CRlUNHfdEA59M8uqhj9Y572hX+sDCIBo13V7pvBWfHcjWsh109C3ZC3KC7hz4 -7aZL429Ax3S34M0HRmzHnCPHEPdGU/M4Qm5DXtZHH+o6SoqqxTw= -=9Z7b +iQIzBAABCgAdFiEEynwsejDI6OEnSoR2UcZzBf/C5cAFAmjELX8ACgkQUcZzBf/C +5cCVdg//U69LB4uyv+6rxEnJXtX0qvEQUFqHyQ+ItvKUu04RUxddc+9mfgWn674N +ArtC1688BhbUVCW+bRnwbfj2EFQOMr1xCflz+RhrfYA9Jlgj3VrnTnOpUjfyBZJm +K2uEWDmJ7f5aupP0XszZN2ktfn7mSsc5r8c67RzPl5B5+p4CfC48CVwHkdrw6UBV +pntQlR1Ax81Qcool+WaqXHCAu/n7bT83PCQQSLhxDKZHc6GJJPmK1+Jw7BglAtdo +dRW7fFi/6SZ4FzmX7g/8rG+d02pWFP3OMIC98qFZPxM9b7PdZ7tBvYClFJwgBp55 +tdxAgXkll8QI1czdinIJsE0wlqmVWe1TUZegFpNjQQpQjKVqhhc7hmcGC+N2nP1W +lfTC8l/VH2QalwItgOVOrinMGI+voOGV7R3gI/GG3ZOUAkG3bsk5I57sw5BgRpi7 +rUgmPg+oMi6UIH1d7PLTBxnRpRIV0XMyirUYePPjUOPL5dvJM7BznSq8LzZ5wf4I +3chJ9u+gyw5cF8ot4HyJD4NWUvr2R50Gs7ScL9HnSOvqr2dbrLTNepAjbWZn2nUj +JIL0ff9zx8Fv62IpD4HiR/ukU7kfPJuJ3hVZonn7kSpcW23Wfs6aOHKJOkPMZKcV +9p/YQl824COpVO/xxxXI+W2Z5AohWDoEix4jZ/7k8dAgO56lvKU= +=a7mV -----END PGP SIGNATURE-----