From e143018256eb130c784ba57f736cd11b6660dcff Mon Sep 17 00:00:00 2001 From: batyrmastyr Date: Sun, 24 Aug 2025 13:15:30 +0300 Subject: [PATCH] adapt to PhpUnit 10+ --- composer.json | 10 +- config/params.php | 3 +- phpunit.xml.dist | 13 +- src/Inspector/Command/PHPUnitCommand.php | 4 +- src/Inspector/Test/PHPUnitJSONReporter.php | 178 ++++++++++----------- src/Inspector/Test/PHPUnitTracer.php | 24 +++ 6 files changed, 129 insertions(+), 103 deletions(-) create mode 100644 src/Inspector/Test/PHPUnitTracer.php diff --git a/composer.json b/composer.json index 792d0ea..bfb5cdf 100644 --- a/composer.json +++ b/composer.json @@ -63,16 +63,16 @@ "require-dev": { "codeception/codeception": "^5.0", "maglnet/composer-require-checker": "^4.2", - "phpunit/phpunit": "^10.5", + "phpunit/phpunit": "10 - 12", "rector/rector": "^2.1.1", "roave/infection-static-analysis-plugin": "^1.30", "spatie/phpunit-watcher": "^1.23", - "vimeo/psalm": "^5.15 || ^6.12", + "vimeo/psalm": "^5.22 || ^6.12", "yiisoft/active-record": "dev-master", "yiisoft/assets": "^5.1", "yiisoft/csrf": "^2.0", - "yiisoft/db": "1.2 as dev-master", - "yiisoft/db-sqlite": "^1.0", + "yiisoft/db": "dev-master as 2.0.0", + "yiisoft/db-sqlite": "dev-master as 2.0.0", "yiisoft/psr-dummy-provider": "^1.0", "yiisoft/router-fastroute": "^4.0", "yiisoft/test-support": "^3.0", @@ -110,7 +110,7 @@ } }, "scripts": { - "test": "phpunit --testdox --no-interaction", + "test": "phpunit --testdox", "test-watch": "phpunit-watcher watch" }, "config": { diff --git a/config/params.php b/config/params.php index 5351837..50653c2 100644 --- a/config/params.php +++ b/config/params.php @@ -3,13 +3,14 @@ declare(strict_types=1); use Codeception\Extension; +use PHPUnit\Framework\Test; use Yiisoft\Yii\Debug\Api\Debug\Middleware\DebugHeaders; use Yiisoft\Yii\Debug\Api\Inspector\Command\CodeceptionCommand; use Yiisoft\Yii\Debug\Api\Inspector\Command\PHPUnitCommand; use Yiisoft\Yii\Debug\Api\Inspector\Command\PsalmCommand; $testCommands = []; -if (class_exists(PHPUnit\Framework\Test::class)) { +if (interface_exists(Test::class)) { $testCommands[PHPUnitCommand::COMMAND_NAME] = PHPUnitCommand::class; } if (class_exists(Extension::class)) { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 11752e2..569d320 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -2,12 +2,13 @@ @@ -21,9 +22,9 @@ - + ./src - + diff --git a/src/Inspector/Command/PHPUnitCommand.php b/src/Inspector/Command/PHPUnitCommand.php index 16bd4e2..1832c95 100644 --- a/src/Inspector/Command/PHPUnitCommand.php +++ b/src/Inspector/Command/PHPUnitCommand.php @@ -39,9 +39,9 @@ public function run(): CommandResponse $extension = PHPUnitJSONReporter::class; $params = [ 'vendor/bin/phpunit', - '--printer', + '--extension', $extension, - '-vvv', + '--no-coverage -vvv', ]; $process = new Process($params); diff --git a/src/Inspector/Test/PHPUnitJSONReporter.php b/src/Inspector/Test/PHPUnitJSONReporter.php index c208637..af615e6 100644 --- a/src/Inspector/Test/PHPUnitJSONReporter.php +++ b/src/Inspector/Test/PHPUnitJSONReporter.php @@ -4,135 +4,135 @@ namespace Yiisoft\Yii\Debug\Api\Inspector\Test; -use PHPUnit\Framework\AssertionFailedError; -use PHPUnit\Framework\Test; -use PHPUnit\Framework\TestCase; -use PHPUnit\Framework\TestResult; -use PHPUnit\Framework\TestSuite; -use PHPUnit\Framework\Warning; -use PHPUnit\Runner\BaseTestRunner; -use PHPUnit\TextUI\ResultPrinter; -use PHPUnit\Util\TestDox\NamePrettifier; -use ReflectionClass; -use Throwable; - -/** - * @psalm-suppress InternalClass, InternalMethod, UndefinedClass - */ -class PHPUnitJSONReporter implements ResultPrinter +use PHPUnit\Event\Event; +use PHPUnit\Event\Test\ConsideredRisky; +use PHPUnit\Event\Test\Errored; +use PHPUnit\Event\Test\ErrorTriggered; +use PHPUnit\Event\Test\Failed; +use PHPUnit\Event\Test\Finished; +use PHPUnit\Event\Test\MarkedIncomplete; +use PHPUnit\Event\Test\NoticeTriggered; +use PHPUnit\Event\Test\Passed; +use PHPUnit\Event\Test\PhpNoticeTriggered; +use PHPUnit\Event\Test\PhpunitErrorTriggered; +use PHPUnit\Event\Test\PhpunitNoticeTriggered; +use PHPUnit\Event\Test\PhpunitWarningTriggered; +use PHPUnit\Event\Test\PhpWarningTriggered; +use PHPUnit\Event\Test\Skipped; +use PHPUnit\Event\Test\WarningTriggered; +use PHPUnit\Runner\Extension\Extension; +use PHPUnit\Runner\Extension\Facade; +use PHPUnit\Runner\Extension\ParameterCollection; +use PHPUnit\TextUI\Configuration\Configuration; + +class PHPUnitJSONReporter implements Extension { public const FILENAME = 'phpunit-report.json'; public const ENVIRONMENT_VARIABLE_DIRECTORY_NAME = 'REPORTER_OUTPUT_PATH'; private array $data = []; - private NamePrettifier $prettifier; public function __construct() { - $this->prettifier = new NamePrettifier(); } - public function printResult(TestResult $result): void + public function bootstrap( + Configuration $configuration, + Facade $facade, + ParameterCollection $parameters + ): void { - $path = getenv(self::ENVIRONMENT_VARIABLE_DIRECTORY_NAME) ?: getcwd(); - ksort($this->data); - - file_put_contents( - $path . DIRECTORY_SEPARATOR . self::FILENAME, - json_encode(array_values($this->data), JSON_THROW_ON_ERROR) - ); - } - - public function write(string $buffer): void - { - $this->data = []; - } - - public function addError(Test $test, Throwable $t, float $time): void - { - $this->logErroredTest($test, $t); - } - - public function addWarning(Test $test, Warning $e, float $time): void - { - $this->logErroredTest($test, $e); - } - - public function addFailure(Test $test, AssertionFailedError $e, float $time): void - { - $this->logErroredTest($test, $e); - } - - public function addIncompleteTest(Test $test, Throwable $t, float $time): void - { - $this->logErroredTest($test, $t); - } - - public function addRiskyTest(Test $test, Throwable $t, float $time): void - { - $this->logErroredTest($test, $t); - } - - public function addSkippedTest(Test $test, Throwable $t, float $time): void - { - $this->logErroredTest($test, $t); + $facade->registerTracer(new PHPUnitTracer($this)); } - public function startTestSuite(TestSuite $suite): void + public function __destruct() { + $this->saveResult(); } - public function endTestSuite(TestSuite $suite): void + public function saveResult(): void { - } + $path = getenv(self::ENVIRONMENT_VARIABLE_DIRECTORY_NAME) ?: getcwd(); + ksort($this->data); - public function startTest(Test $test): void - { + file_put_contents( + $path . DIRECTORY_SEPARATOR . self::FILENAME, + json_encode(array_values($this->data), JSON_THROW_ON_ERROR) + ); } - public function endTest(Test $test, float $time): void + public function logPassed(Passed|Finished $event): void { - if (!$test instanceof TestCase) { + $parsedName = $event->test()->id(); + if (array_key_exists($parsedName, $this->data)) { return; } - if ($test->getStatus() !== BaseTestRunner::STATUS_PASSED) { - return; - } - - $parsedName = $this->parseName($test); $this->data[$parsedName] = [ - 'file' => $this->parseFilename($test), + 'file' => $event->test()->file(), 'test' => $parsedName, + 'time' => $event->telemetryInfo()->durationSincePrevious()->asFloat(), 'status' => 'ok', 'stacktrace' => [], ]; } - private function parseName(Test $test): string + public function logErrored(Failed|MarkedIncomplete|Errored $event): void { - if ($test instanceof TestCase) { - return $test::class . '::' . $test->getName(true); + $parsedName = $event->test()->id(); + if (array_key_exists($parsedName, $this->data)) { + return; } - return $this->prettifier->prettifyTestClass($test::class); - } - - private function parseFilename(Test $test): string - { - $reflection = new ReflectionClass($test); - return $reflection->getFileName(); + $this->data[$parsedName] = [ + 'file' => $event->test()->file(), + 'test' => $parsedName, + 'time' => $event->telemetryInfo()->durationSincePrevious()->asFloat(), + 'status' => $event->throwable()->message(), + 'stacktrace' => $event->throwable()->stackTrace(), + ]; } - private function logErroredTest(Test $test, Throwable $t): void + public function logMessage(WarningTriggered|PhpWarningTriggered|PhpunitWarningTriggered|NoticeTriggered|PhpNoticeTriggered|PhpunitNoticeTriggered|ErrorTriggered|PhpunitErrorTriggered|Skipped|ConsideredRisky $event): void { - $parsedName = $this->parseName($test); + $parsedName = $event->test()->id(); + if (array_key_exists($parsedName, $this->data)) { + return; + } $this->data[$parsedName] = [ - 'file' => $this->parseFilename($test), + 'file' => $event->test()->file(), 'test' => $parsedName, - 'status' => $t->getMessage(), - 'stacktrace' => $t->getTrace(), + 'time' => $event->telemetryInfo()->durationSincePrevious()->asFloat(), + 'status' => $event->message(), + 'stacktrace' => [], ]; } + + public function log(Event $event) + { + if ($event instanceof Passed + || $event instanceof Finished + ) { + $this->logPassed($event); + } elseif ($event instanceof Failed + || $event instanceof Errored + || $event instanceof MarkedIncomplete + ) { + $this->logErrored($event); + } elseif ( + $event instanceof WarningTriggered + || $event instanceof PhpWarningTriggered + || $event instanceof PhpunitWarningTriggered + || $event instanceof NoticeTriggered + || $event instanceof PhpNoticeTriggered + || $event instanceof PhpunitNoticeTriggered + || $event instanceof ErrorTriggered + || $event instanceof PhpunitErrorTriggered + || $event instanceof Skipped + || $event instanceof ConsideredRisky + ) { + $this->logMessage($event); + } + } } diff --git a/src/Inspector/Test/PHPUnitTracer.php b/src/Inspector/Test/PHPUnitTracer.php new file mode 100644 index 0000000..bbeeb07 --- /dev/null +++ b/src/Inspector/Test/PHPUnitTracer.php @@ -0,0 +1,24 @@ +reporter->log($event); + + } +}