Skip to content

Commit c9309d4

Browse files
authored
Update PHPUnit to version 11 (#7577)
1 parent 9e4ab7b commit c9309d4

9 files changed

Lines changed: 83 additions & 72 deletions

File tree

co-phpunit

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,10 @@ if (!version_compare(PHP_VERSION, PHP_VERSION, '=')) {
1313
fwrite(STDERR, sprintf('%s declares an invalid value for PHP_VERSION.' . PHP_EOL . 'This breaks fundamental functionality such as version_compare().' . PHP_EOL . 'Please use a different PHP interpreter.' . PHP_EOL, PHP_BINARY));
1414
die(1);
1515
}
16-
if (version_compare('8.1.0', PHP_VERSION, '>')) {
17-
fwrite(STDERR, sprintf('This version of PHPUnit requires PHP >= 8.1.' . PHP_EOL . 'You are using PHP %s (%s).' . PHP_EOL, PHP_VERSION, PHP_BINARY));
16+
if (version_compare('8.2.0', PHP_VERSION, '>')) {
17+
fwrite(STDERR, sprintf('This version of PHPUnit requires PHP >= 8.2.' . PHP_EOL . 'You are using PHP %s (%s).' . PHP_EOL, PHP_VERSION, PHP_BINARY));
1818
die(1);
1919
}
20-
$requiredExtensions = ['dom', 'json', 'libxml', 'mbstring', 'tokenizer', 'xml', 'xmlwriter'];
21-
$unavailableExtensions = array_filter($requiredExtensions, static function ($extension) {
22-
return !extension_loaded($extension);
23-
});
24-
if ([] !== $unavailableExtensions) {
25-
fwrite(STDERR, sprintf('PHPUnit requires the "%s" extensions, but the "%s" %s not available.' . PHP_EOL, implode('", "', $requiredExtensions), implode('", "', $unavailableExtensions), count($unavailableExtensions) === 1 ? 'extension is' : 'extensions are'));
26-
die(1);
27-
}
28-
unset($requiredExtensions, $unavailableExtensions);
2920
if (!ini_get('date.timezone')) {
3021
ini_set('date.timezone', 'UTC');
3122
}
@@ -45,6 +36,19 @@ if (!defined('PHPUNIT_COMPOSER_INSTALL')) {
4536
fwrite(STDERR, 'You need to set up the project dependencies using Composer:' . PHP_EOL . PHP_EOL . ' composer install' . PHP_EOL . PHP_EOL . 'You can learn all about Composer on https://getcomposer.org/.' . PHP_EOL);
4637
die(1);
4738
}
39+
require PHPUNIT_COMPOSER_INSTALL;
40+
$requiredExtensions = ['dom', 'json', 'libxml', 'mbstring', 'tokenizer', 'xml', 'xmlwriter'];
41+
$unavailableExtensions = array_filter($requiredExtensions, static function ($extension) {
42+
return !extension_loaded($extension);
43+
});
44+
// Workaround for https://github.com/sebastianbergmann/phpunit/issues/5662
45+
if (!function_exists('ctype_alnum')) {
46+
$unavailableExtensions[] = 'ctype';
47+
}
48+
if ([] !== $unavailableExtensions) {
49+
fwrite(STDERR, sprintf('PHPUnit requires the "%s" extensions, but the "%s" %s not available.' . PHP_EOL, implode('", "', $requiredExtensions), implode('", "', $unavailableExtensions), count($unavailableExtensions) === 1 ? 'extension is' : 'extensions are'));
50+
die(1);
51+
}
4852
(function () {
4953
$prepend = null;
5054
foreach ($_SERVER["argv"] as $index => $argv) {
@@ -68,12 +72,12 @@ if (!defined('PHPUNIT_COMPOSER_INSTALL')) {
6872
require $prepend;
6973
}
7074
})();
71-
require PHPUNIT_COMPOSER_INSTALL;
75+
unset($requiredExtensions, $unavailableExtensions);
7276
$code = 0;
7377
Swoole\Coroutine::set(['hook_flags' => SWOOLE_HOOK_ALL, 'exit_condition' => function () {
7478
return Swoole\Coroutine::stats()['coroutine_num'] === 0;
7579
}]);
76-
Swoole\Coroutine\run(function () use(&$code) {
80+
Swoole\Coroutine\run(function () use (&$code) {
7781
$code = (new PHPUnit\TextUI\Application())->run($_SERVER['argv']);
7882
Swoole\Timer::clearAll();
7983
Hyperf\Coordinator\CoordinatorManager::until(Hyperf\Coordinator\Constants::WORKER_EXIT)->resume();

composer.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"hyperf/macroable": "~3.2.0",
2323
"hyperf/stringable": "~3.2.0",
2424
"hyperf/support": "~3.2.0",
25-
"phpunit/phpunit": "^10.0",
25+
"phpunit/phpunit": "^11.0",
2626
"psr/container": "^1.0 || ^2.0",
2727
"symfony/http-foundation": "^6.0 || ^7.0"
2828
},
@@ -32,7 +32,10 @@
3232
"autoload": {
3333
"psr-4": {
3434
"Hyperf\\Testing\\": "src/"
35-
}
35+
},
36+
"files": [
37+
"phpunit-patch.php"
38+
]
3639
},
3740
"autoload-dev": {
3841
"psr-4": {

phpunit-patch.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* This file is part of Hyperf.
6+
*
7+
* @link https://www.hyperf.io
8+
* @document https://hyperf.wiki
9+
* @contact group@hyperf.io
10+
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
11+
*/
12+
use Composer\Autoload\ClassLoader;
13+
use PHPUnit\Framework\TestCase;
14+
15+
(function () {
16+
/** @var null|ClassLoader $classLoader */
17+
$classLoader = null;
18+
foreach ([
19+
__DIR__ . '/../../vendor/autoload.php',
20+
__DIR__ . '/../../autoload.php',
21+
] as $file) {
22+
if (file_exists($file)) {
23+
$classLoader = require $file;
24+
break;
25+
}
26+
}
27+
if (! $classLoader instanceof ClassLoader) {
28+
return;
29+
}
30+
if ($file = $classLoader->findFile(TestCase::class)) {
31+
$content = file_get_contents($file);
32+
$replace = 'public function runBare';
33+
if (strpos($content, $find = 'final ' . $replace) !== false) {
34+
$content = str_replace($find, $replace, $content);
35+
file_put_contents($file, $content);
36+
}
37+
}
38+
})();

src/Concerns/RunTestsInCoroutine.php

Lines changed: 20 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -18,65 +18,34 @@
1818
use Swoole\Timer;
1919
use Throwable;
2020

21-
/**
22-
* @method string name()
23-
*/
2421
trait RunTestsInCoroutine
2522
{
2623
protected bool $enableCoroutine = true;
2724

28-
protected string $realTestName = '';
29-
30-
final protected function runTestsInCoroutine(...$arguments)
25+
public function runBare(): void
3126
{
32-
parent::setName($this->realTestName);
33-
34-
$testResult = null;
35-
$exception = null;
36-
37-
/* @phpstan-ignore-next-line */
38-
\Swoole\Coroutine\run(function () use (&$testResult, &$exception, $arguments) {
39-
try {
40-
$this->invokeBeforeHookMethods();
41-
$testResult = $this->{$this->realTestName}(...$arguments);
42-
} catch (Throwable $e) {
43-
$exception = $e;
44-
} finally {
45-
$this->invokeAfterHookMethods();
46-
Timer::clearAll();
47-
CoordinatorManager::until(Constants::WORKER_EXIT)->resume();
27+
if ($this->enableCoroutine && extension_loaded('swoole') && Coroutine::getCid() === -1) {
28+
$exception = null;
29+
30+
/* @phpstan-ignore-next-line */
31+
\Swoole\Coroutine\run(function () use (&$exception) {
32+
try {
33+
parent::runBare();
34+
} catch (Throwable $e) {
35+
$exception = $e;
36+
} finally {
37+
Timer::clearAll();
38+
CoordinatorManager::until(Constants::WORKER_EXIT)->resume();
39+
}
40+
});
41+
42+
if ($exception) {
43+
throw $exception;
4844
}
49-
});
50-
51-
if ($exception) {
52-
throw $exception;
53-
}
54-
55-
return $testResult;
56-
}
5745

58-
final protected function runTest(): mixed
59-
{
60-
if (extension_loaded('swoole') && Coroutine::getCid() === -1 && $this->enableCoroutine) {
61-
$this->realTestName = $this->name();
62-
parent::setName('runTestsInCoroutine');
46+
return;
6347
}
6448

65-
/* @phpstan-ignore-next-line */
66-
return parent::runTest();
67-
}
68-
69-
private function invokeBeforeHookMethods(): void
70-
{
71-
if (method_exists($this, 'beforeTestInCoroutine')) {
72-
call_user_func([$this, 'beforeTestInCoroutine']);
73-
}
74-
}
75-
76-
private function invokeAfterHookMethods(): void
77-
{
78-
if (method_exists($this, 'afterTestInCoroutine')) {
79-
call_user_func([$this, 'afterTestInCoroutine']);
80-
}
49+
parent::runBare();
8150
}
8251
}

src/Constraint/ArraySubset.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use ArrayObject;
1616
use PHPUnit\Framework\Constraint\Constraint;
1717
use PHPUnit\Framework\ExpectationFailedException;
18+
use PHPUnit\Util\Exporter;
1819
use SebastianBergmann\Comparator\ComparisonFailure;
1920
use Traversable;
2021

@@ -94,7 +95,7 @@ public function evaluate($other, string $description = '', bool $returnResult =
9495
*/
9596
public function toString(): string
9697
{
97-
return 'has the subset ' . $this->exporter()->export($this->subset);
98+
return 'has the subset ' . Exporter::export($this->subset);
9899
}
99100

100101
/**

src/TestCase.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,14 @@
2020

2121
/**
2222
* @internal
23-
* @coversNothing
2423
*/
2524
abstract class TestCase extends \PHPUnit\Framework\TestCase
2625
{
2726
use Concerns\InteractsWithContainer;
27+
use Concerns\InteractsWithDatabase;
2828
use Concerns\InteractsWithModelFactory;
2929
use Concerns\MakesHttpRequests;
3030
use Concerns\RunTestsInCoroutine;
31-
use Concerns\InteractsWithDatabase;
3231

3332
/**
3433
* The callbacks that should be run after the application is created.

tests/ClientTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545

4646
/**
4747
* @internal
48-
* @coversNothing
4948
*/
5049
#[CoversNothing]
5150
class ClientTest extends TestCase

tests/DebugTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
/**
2121
* @internal
22-
* @coversNothing
2322
*/
2423
#[CoversNothing]
2524
class DebugTest extends TestCase

tests/HttpClientTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
/**
2525
* @internal
26-
* @coversNothing
2726
*/
2827
#[CoversNothing]
2928
class HttpClientTest extends TestCase

0 commit comments

Comments
 (0)