Issue #3031577 by alexpott, Lendude, larowlan: \Drupal\Tests\Listeners\DeprecationListenerTrait::getSkippedDeprecations() does not work in unit tests
parent
0df3be0e23
commit
51cc6680c8
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\Tests\Listeners;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\Test;
|
||||||
|
use PHPUnit\Framework\TestListener;
|
||||||
|
use PHPUnit\Framework\TestListenerDefaultImplementation;
|
||||||
|
|
||||||
|
if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) {
|
||||||
|
class_alias('Drupal\Tests\Listeners\Legacy\AfterSymfonyListener', 'Drupal\Tests\Listeners\AfterSymfonyListener');
|
||||||
|
// Using an early return instead of an else does not work when using the
|
||||||
|
// PHPUnit phar due to some weird PHP behavior (the class gets defined without
|
||||||
|
// executing the code before it and so the definition is not properly
|
||||||
|
// conditional).
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/**
|
||||||
|
* Listens to PHPUnit test runs.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
class AfterSymfonyListener implements TestListener {
|
||||||
|
use TestListenerDefaultImplementation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function endTest(Test $test, $time) {
|
||||||
|
restore_error_handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,10 +13,21 @@ use PHPUnit\Framework\TestCase;
|
||||||
* fixed.
|
* fixed.
|
||||||
*/
|
*/
|
||||||
trait DeprecationListenerTrait {
|
trait DeprecationListenerTrait {
|
||||||
|
|
||||||
use ExpectDeprecationTrait;
|
use ExpectDeprecationTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The previous error handler.
|
||||||
|
*
|
||||||
|
* @var callable
|
||||||
|
*/
|
||||||
|
private $previousHandler;
|
||||||
|
|
||||||
protected function deprecationStartTest($test) {
|
protected function deprecationStartTest($test) {
|
||||||
if ($test instanceof \PHPUnit_Framework_TestCase || $test instanceof TestCase) {
|
if ($test instanceof \PHPUnit_Framework_TestCase || $test instanceof TestCase) {
|
||||||
|
if ('disabled' !== getenv('SYMFONY_DEPRECATIONS_HELPER')) {
|
||||||
|
$this->registerErrorHandler($test);
|
||||||
|
}
|
||||||
if ($this->willBeIsolated($test)) {
|
if ($this->willBeIsolated($test)) {
|
||||||
putenv('DRUPAL_EXPECTED_DEPRECATIONS_SERIALIZE=' . tempnam(sys_get_temp_dir(), 'exdep'));
|
putenv('DRUPAL_EXPECTED_DEPRECATIONS_SERIALIZE=' . tempnam(sys_get_temp_dir(), 'exdep'));
|
||||||
}
|
}
|
||||||
|
@ -126,6 +137,8 @@ trait DeprecationListenerTrait {
|
||||||
// is a Windows only deprecation. Remove when core no longer uses
|
// is a Windows only deprecation. Remove when core no longer uses
|
||||||
// WinCacheClassLoader in \Drupal\Core\DrupalKernel::initializeSettings().
|
// WinCacheClassLoader in \Drupal\Core\DrupalKernel::initializeSettings().
|
||||||
'The Symfony\Component\ClassLoader\WinCacheClassLoader class is deprecated since Symfony 3.3 and will be removed in 4.0. Use `composer install --apcu-autoloader` instead.',
|
'The Symfony\Component\ClassLoader\WinCacheClassLoader class is deprecated since Symfony 3.3 and will be removed in 4.0. Use `composer install --apcu-autoloader` instead.',
|
||||||
|
// The following deprecation message is skipped for testing purposes.
|
||||||
|
'\Drupal\Tests\SkippedDeprecationTest deprecation',
|
||||||
// These deprecations are triggered by symfony/psr-http-message-factory
|
// These deprecations are triggered by symfony/psr-http-message-factory
|
||||||
// 1.2, which can be installed if you update dependencies on php 7 or
|
// 1.2, which can be installed if you update dependencies on php 7 or
|
||||||
// higher
|
// higher
|
||||||
|
@ -134,4 +147,40 @@ trait DeprecationListenerTrait {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers an error handler that wraps Symfony's DeprecationErrorHandler.
|
||||||
|
*
|
||||||
|
* @see \Symfony\Bridge\PhpUnit\DeprecationErrorHandler
|
||||||
|
* @see \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait
|
||||||
|
*/
|
||||||
|
protected function registerErrorHandler($test) {
|
||||||
|
$deprecation_handler = function ($type, $msg, $file, $line, $context = []) {
|
||||||
|
// Skip listed deprecations.
|
||||||
|
if ($type === E_USER_DEPRECATED && in_array($msg, self::getSkippedDeprecations(), TRUE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return call_user_func($this->previousHandler, $type, $msg, $file, $line, $context);
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($this->previousHandler) {
|
||||||
|
set_error_handler($deprecation_handler);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$this->previousHandler = set_error_handler($deprecation_handler);
|
||||||
|
|
||||||
|
// Register another listener so that we can remove the error handler before
|
||||||
|
// Symfony's DeprecationErrorHandler checks that it is the currently
|
||||||
|
// registered handler. Note this is done like this to ensure the error
|
||||||
|
// handler is removed after SymfonyTestsListenerTrait::endTest() is called.
|
||||||
|
// SymfonyTestsListenerTrait has its own error handler that needs to be
|
||||||
|
// removed before this one.
|
||||||
|
$test_result_object = $test->getTestResultObject();
|
||||||
|
$reflection_class = new \ReflectionClass($test_result_object);
|
||||||
|
$reflection_property = $reflection_class->getProperty('listeners');
|
||||||
|
$reflection_property->setAccessible(TRUE);
|
||||||
|
$listeners = $reflection_property->getValue($test_result_object);
|
||||||
|
$listeners[] = new AfterSymfonyListener();
|
||||||
|
$reflection_property->setValue($test_result_object, $listeners);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\Tests\Listeners\Legacy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens to PHPUnit test runs.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
class AfterSymfonyListener extends \PHPUnit_Framework_BaseTestListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function endTest(\PHPUnit_Framework_Test $test, $time) {
|
||||||
|
restore_error_handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\Tests;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group Test
|
||||||
|
*/
|
||||||
|
class SkippedDeprecationTest extends UnitTestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests skipping deprecations in unit tests.
|
||||||
|
*
|
||||||
|
* @see \Drupal\Tests\Listeners\DeprecationListenerTrait::getSkippedDeprecations()
|
||||||
|
*/
|
||||||
|
public function testSkippingDeprecations() {
|
||||||
|
@trigger_error('\Drupal\Tests\SkippedDeprecationTest deprecation', E_USER_DEPRECATED);
|
||||||
|
$this->addToAssertionCount(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests skipping deprecations in unit tests multiple times.
|
||||||
|
*
|
||||||
|
* @see \Drupal\Tests\Listeners\DeprecationListenerTrait::getSkippedDeprecations()
|
||||||
|
*/
|
||||||
|
public function testSkippingDeprecationsAgain() {
|
||||||
|
@trigger_error('\Drupal\Tests\SkippedDeprecationTest deprecation', E_USER_DEPRECATED);
|
||||||
|
$this->addToAssertionCount(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue