Created
February 8, 2024 10:29
-
-
Save upyx/372bd015bd2ba087189f6d0152eca7eb to your computer and use it in GitHub Desktop.
Simple PHPUnit 10+ extension to restore an error handler overrined by Symfony's one
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Tests\PhpUnit; | |
use PHPUnit\Event\Test\Finished; | |
use PHPUnit\Event\Test\FinishedSubscriber; | |
use PHPUnit\Event\Test\Prepared; | |
use PHPUnit\Event\Test\PreparedSubscriber; | |
use PHPUnit\Metadata\Parser\Registry as MetadataRegistry; | |
use PHPUnit\Runner\ErrorHandler; | |
use PHPUnit\Runner\Extension\Extension as PhpUnitExtension; | |
use PHPUnit\Runner\Extension\Facade; | |
use PHPUnit\Runner\Extension\ParameterCollection; | |
use PHPUnit\TextUI\Configuration\Configuration; | |
use Symfony\Bridge\PhpUnit\DeprecationErrorHandler; | |
use function restore_error_handler; | |
use function set_error_handler; | |
final class Extension implements PhpUnitExtension { | |
private static bool $errorHandlerWrapped = false; | |
public static function enablePhpUnitErrorHandler(): void { | |
if (self::$errorHandlerWrapped) { | |
return; | |
} | |
$errorHandler = set_error_handler('intval'); | |
restore_error_handler(); | |
if (!isset($errorHandler[0]) || $errorHandler instanceof DeprecationErrorHandler) { | |
return; | |
} | |
set_error_handler(static function ($type, $msg, $file, $line) use ($errorHandler) { | |
$errorHandler($type, $msg, $file, $line); | |
return ErrorHandler::instance()($type, $msg, $file, $line); | |
}); | |
self::$errorHandlerWrapped = true; | |
} | |
public static function disablePhpUnitErrorHandler(): void { | |
if (self::$errorHandlerWrapped) { | |
self::$errorHandlerWrapped = false; | |
restore_error_handler(); | |
} | |
} | |
public function bootstrap(Configuration $configuration, Facade $facade, ParameterCollection $parameters): void { | |
$facade->registerSubscriber( | |
new class() implements PreparedSubscriber { | |
public function notify(Prepared $event): void { | |
$test = $event->test(); | |
if (!$test->isTestMethod()) { | |
return; | |
} | |
$shouldErrorHandlerBeUsed = !MetadataRegistry::parser() | |
->forMethod($test->className(), $test->methodName()) | |
->isWithoutErrorHandler() | |
->isNotEmpty(); | |
if ($shouldErrorHandlerBeUsed) { | |
Extension::enablePhpUnitErrorHandler(); | |
} | |
} | |
} | |
); | |
$facade->registerSubscriber( | |
new class() implements FinishedSubscriber { | |
public function notify(Finished $event): void { | |
Extension::disablePhpUnitErrorHandler(); | |
} | |
} | |
); | |
self::disablePhpUnitErrorHandler(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<phpunit> | |
<!-- ... --> | |
<extensions> | |
<bootstrap class="App\Tests\PhpUnit\Extension"/> <!-- use correct path to the extension --> | |
</extensions> | |
</phpunit> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment