Skip to content
Snippets Groups Projects
Commit d77a68d5 authored by catch's avatar catch
Browse files

Issue #3272779 by mondrake, longwave, alexpott: [Symfony 6.1] Replace...

Issue #3272779 by mondrake, longwave, alexpott: [Symfony 6.1] Replace deprecationListenerTrait with PHPUnitBridge ignoreFile
parent e47f94ca
No related branches found
Tags 5.5.12
37 merge requests!7471uncessary 5 files are moved from media-library folder to misc folder,!7452Issue #1797438. HTML5 validation is preventing form submit and not fully...,!54479.5.x SF update,!5014Issue #3071143: Table Render Array Example Is Incorrect,!4868Issue #1428520: Improve menu parent link selection,!4289Issue #1344552 by marcingy, Niklas Fiekas, Ravi.J, aleevas, Eduardo Morales...,!4114Issue #2707291: Disable body-level scrolling when a dialog is open as a modal,!3630Issue #2815301 by Chi, DanielVeza, kostyashupenko, smustgrave: Allow to create...,!3291Issue #3336463: Rewrite rules for gzipped CSS and JavaScript aggregates never match,!3143Issue #3313342: [PHP 8.1] Deprecated function: strpos(): Passing null to parameter #1 LayoutBuilderUiCacheContext.php on line 28,!3102Issue #3164428 by DonAtt, longwave, sahil.goyal, Anchal_gupta, alexpott: Use...,!2853#3274419 Makes BaseFieldOverride inherit the internal property from the base field.,!2719Issue #3110137: Remove Classy from core.,!2437Issue #3238257 by hooroomoo, Wim Leers: Fragment link pointing to <textarea>...,!2378Issue #2875033: Optimize joins and table selection in SQL entity query implementation,!2074Issue #2707689: NodeForm::actions() checks for delete access on new entities,!2062Issue #3246454: Add weekly granularity to views date sort,!1591Issue #3199697: Add JSON:API Translation experimental module,!1484Exposed filters get values from URL when Ajax is on,!1255Issue #3238922: Refactor (if feasible) uses of the jQuery serialize function to use vanillaJS,!1254Issue #3238915: Refactor (if feasible) uses of the jQuery ready function to use VanillaJS,!1162Issue #3100350: Unable to save '/' root path alias,!1073issue #3191727: Focus states on mobile second level navigation items fixed,!10223132456: Fix issue where views instances are emptied before an ajax request is complete,!957Added throwing of InvalidPluginDefinitionException from getDefinition().,!925Issue #2339235: Remove taxonomy hard dependency on node module,!877Issue #2708101: Default value for link text is not saved,!873Issue #2875228: Site install not using batch API service,!872Draft: Issue #3221319: Race condition when creating menu links and editing content deletes menu links,!844Resolve #3036010 "Updaters",!712Issue #2909128: Autocomplete intermittent on Chrome Android,!617Issue #3043725: Provide a Entity Handler for user cancelation,!579Issue #2230909: Simple decimals fail to pass validation,!560Move callback classRemove outside of the loop,!555Issue #3202493,!485Sets the autocomplete attribute for username/password input field on login form.,!30Issue #3182188: Updates composer usage to point at ./vendor/bin/composer
This commit is part of merge request !1581. Comments created here will be created in the context of that merge request.
# This file contains patterns to be ignored while testing for use of
# deprecated code.
# See https://www.drupal.org/node/3285162 for more details.
%The "Symfony\\Component\\Validator\\Context\\ExecutionContextInterface::.*\(\)" method is considered internal Used by the validator engine\. (Should not be called by user\W+code\. )?It may change without further notice\. You should not extend it from "[^"]+"\.%
%The "PHPUnit\\Framework\\TestCase::addWarning\(\)" method is considered internal%
# The following deprecations were not added as part of the original issues and
# thus were not addressed in time for the 9.0.0 release.
%The entity link url update for the "\w+" view is deprecated in drupal:9\.0\.0 and is removed from drupal:10\.0\.0\. Module-provided Views configuration should be updated to accommodate the changes described at https:\/\/www.drupal.org\/node\/2857891\.%
%The operator defaults update for the "\w+" view is deprecated in drupal:9\.0\.0 and is removed from drupal:10\.0\.0\. Module-provided Views configuration should be updated to accommodate the changes described at https:\/\/www.drupal.org\/node\/2869168\.%
# Skip EasyRdf deprecations for PHP 8.1 - fixed by
# https://github.com/easyrdf/easyrdf/pull/384.
%Return type of EasyRdf\\.* should either be compatible with .*, or the #\[\\ReturnTypeWillChange\] attribute should be used to temporarily suppress the notice%
# Skip non-Symfony DebugClassLoader forward compatibility warnings.
%Method "(?!Symfony\\)[^"]+" might add "[^"]+" as a native return type declaration in the future. Do the same in (child class|implementation) "[^"]+" now to avoid errors or add an explicit @return annotation to suppress this message%
# Skip DebugClassLoader false positives.
%Method "[^"]+" might add "[^"]+" as a native return type declaration in the future. Do the same in (child class|implementation) "(?!Drupal\\)[^"]+" now to avoid errors or add an explicit @return annotation to suppress this message%
%The "Drupal\\[^"]+" method will require a new "[^"]+" argument in the next major version of its interface "Drupal\\[^"]+", not defining it is deprecated%
# The following deprecation is listed for Twig 2 compatibility when unit
# testing using \Symfony\Component\ErrorHandler\DebugClassLoader.
%The "Twig\\Environment::getTemplateClass\(\)" method is considered internal\. It may change without further notice\. You should not extend it from "Drupal\\Core\\Template\\TwigEnvironment"\.%
# PHPUnit 9.
%"PHPUnit\\Framework\\TestListener".*is deprecated%
%"PHPUnit\\Framework\\TestListenerDefaultImplementation".*is deprecated%
%"PHPUnit\\Framework\\TestSuite".*is considered internal%
%"PHPUnit\\TextUI\\DefaultResultPrinter".*is considered internal%
# Symfony 6.1 deprecations.
%Since symfony\/routing 6\.1: Construction of .*MissingMandatoryParametersException.* with an exception message is deprecated, provide the route name and an array of missing parameters instead%
%Since symfony\/routing 6\.1: The .*UrlMatcher::handleRouteRequirements\(\).* method will have a new .*routeParameters.* argument in version 7\.0, not defining it is deprecated%
......@@ -31,8 +31,26 @@
external DDev URL so you can follow the links directly.
-->
<env name="BROWSERTEST_OUTPUT_BASE_URL" value=""/>
<!-- Deprecation testing is managed through Symfony's PHPUnit Bridge.
The environment variable SYMFONY_DEPRECATIONS_HELPER is used to configure
the behaviour of the deprecation tests.
See https://symfony.com/doc/current/components/phpunit_bridge.html#configuration
Drupal core's testing framework is setting this variable to its defaults.
Projects with their own requirements need to manage this variable
explicitly.
-->
<!-- To disable deprecation testing completely uncomment the next line. -->
<!-- <env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled"/> -->
<!-- Deprecation errors can be selectively ignored by specifying a file of
regular expression patterns for exclusion.
See https://symfony.com/doc/current/components/phpunit_bridge.html#ignoring-deprecations
Uncomment the line below to specify a custom deprecations ignore file.
NOTE: it may be required to specify the full path to the file to run tests
correctly.
-->
<!-- <env name="SYMFONY_DEPRECATIONS_HELPER" value="ignoreFile=.deprecation-ignore.txt"/> -->
<!-- Example for changing the driver class for mink tests MINK_DRIVER_CLASS value: 'Drupal\FunctionalJavascriptTests\DrupalSelenium2Driver' -->
<env name="MINK_DRIVER_CLASS" value=''/>
<!-- Example for changing the driver args to mink tests MINK_DRIVER_ARGS value: '["http://127.0.0.1:8510"]' -->
......
<?php
namespace Drupal\Tests\Listeners;
use PHPUnit\Util\Test;
/**
* Removes deprecations that we are yet to fix.
*
* @internal
* This class will be removed once all the deprecation notices have been
* fixed.
*/
trait DeprecationListenerTrait {
/**
* The previous error handler.
*
* @var callable
*/
private $previousHandler;
/**
* Reacts to the end of a test.
*
* @param \PHPUnit\Framework\Test $test
* The test object that has ended its test run.
* @param float $time
* The time the test took.
*/
protected function deprecationEndTest($test, $time) {
/** @var \PHPUnit\Framework\Test $test */
if ($file = getenv('SYMFONY_DEPRECATIONS_SERIALIZE')) {
$method = $test->getName(FALSE);
if (strpos($method, 'testLegacy') === 0
|| strpos($method, 'provideLegacy') === 0
|| strpos($method, 'getLegacy') === 0
|| strpos(get_class($test), '\Legacy')
|| in_array('legacy', Test::getGroups(get_class($test), $method), TRUE)) {
// This is a legacy test don't skip deprecations.
return;
}
// Need to edit the file of deprecations to remove any skipped
// deprecations.
$deprecations = file_get_contents($file);
$deprecations = $deprecations ? unserialize($deprecations) : [];
$resave = FALSE;
foreach ($deprecations as $key => $deprecation) {
if (static::isDeprecationSkipped($deprecation[1])) {
unset($deprecations[$key]);
$resave = TRUE;
}
}
if ($resave) {
file_put_contents($file, serialize($deprecations));
}
}
}
/**
* Determines if a deprecation error should be skipped.
*
* @return bool
* TRUE if the deprecation error should be skipped, FALSE if not.
*/
public static function isDeprecationSkipped($message) {
if (in_array($message, static::getSkippedDeprecations(), TRUE)) {
return TRUE;
}
$dynamic_skipped_deprecations = [
'%The "Symfony\\\\Component\\\\Validator\\\\Context\\\\ExecutionContextInterface::.*\(\)" method is considered internal Used by the validator engine\. (Should not be called by user\W+code\. )?It may change without further notice\. You should not extend it from "[^"]+".%',
'%The "PHPUnit\\\\Framework\\\\TestCase::addWarning\(\)" method is considered internal%',
// Skip EasyRdf deprecations for PHP 8.1 - fixed by
// https://github.com/easyrdf/easyrdf/pull/384.
'%Return type of EasyRdf\\\\.* should either be compatible with .*, or the #\[\\\\ReturnTypeWillChange\] attribute should be used to temporarily suppress the notice%',
// Skip non-Symfony DebugClassLoader forward compatibility warnings.
'%Method "(?!Symfony\\\\)[^"]+" might add "[^"]+" as a native return type declaration in the future. Do the same in (child class|implementation) "[^"]+" now to avoid errors or add an explicit @return annotation to suppress this message%',
// Skip DebugClassLoader false positives.
'%Method "[^"]+" might add "[^"]+" as a native return type declaration in the future. Do the same in (child class|implementation) "(?!Drupal\\\\)[^"]+" now to avoid errors or add an explicit @return annotation to suppress this message%',
'%The "Drupal\\\\[^"]+" method will require a new "[^"]+" argument in the next major version of its interface "Drupal\\\\[^"]+", not defining it is deprecated%',
];
return (bool) preg_filter($dynamic_skipped_deprecations, '$0', $message);
}
/**
* A list of deprecations to ignore whilst fixes are put in place.
*
* Do not add any new deprecations to this list. All deprecation errors will
* eventually be removed from this list.
*
* @return string[]
* A list of deprecations to ignore.
*
* @internal
*
* @todo Fix all these deprecations and remove them from this list.
* https://www.drupal.org/project/drupal/issues/2959269
*
* @see https://www.drupal.org/node/2811561
*/
public static function getSkippedDeprecations() {
return [
// The following deprecation messages are skipped for testing purposes.
'\Drupal\Tests\SkippedDeprecationTest deprecation',
'Return type of PhpDeprecation::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice',
// The following deprecation is listed for Twig 2 compatibility when unit
// testing using \Symfony\Component\ErrorHandler\DebugClassLoader.
'The "Twig\Environment::getTemplateClass()" method is considered internal. It may change without further notice. You should not extend it from "Drupal\Core\Template\TwigEnvironment".',
'"Symfony\Component\DomCrawler\Crawler::text()" will normalize whitespaces by default in Symfony 5.0, set the second "$normalizeWhitespace" argument to false to retrieve the non-normalized version of the text.',
// PHPUnit 9.
"The \"Drupal\Tests\Listeners\DrupalListener\" class implements \"PHPUnit\Framework\TestListener\" that is deprecated Use the `TestHook` interfaces instead.",
"The \"Drupal\Tests\Listeners\DrupalListener\" class uses \"PHPUnit\Framework\TestListenerDefaultImplementation\" that is deprecated The `TestListener` interface is deprecated.",
"The \"PHPUnit\Framework\TestSuite\" class is considered internal This class is not covered by the backward compatibility promise for PHPUnit. It may change without further notice. You should not use it from \"Drupal\Tests\TestSuites\TestSuiteBase\".",
"The \"PHPUnit\TextUI\DefaultResultPrinter\" class is considered internal This class is not covered by the backward compatibility promise for PHPUnit. It may change without further notice. You should not use it from \"Drupal\Tests\Listeners\HtmlOutputPrinter\".",
"The \"Drupal\Tests\Listeners\DrupalListener\" class implements \"PHPUnit\Framework\TestListener\" that is deprecated.",
// Symfony 6.1.
"Since symfony/routing 6.1: Construction of \"Symfony\Component\Routing\Exception\MissingMandatoryParametersException\" with an exception message is deprecated, provide the route name and an array of missing parameters instead.",
"Since symfony/routing 6.1: The \"Symfony\Component\Routing\Matcher\UrlMatcher::handleRouteRequirements()\" method will have a new \"array \$routeParameters\" argument in version 7.0, not defining it is deprecated.",
];
}
/**
* Registers an error handler that wraps Symfony's DeprecationErrorHandler.
*
* @see \Symfony\Bridge\PhpUnit\DeprecationErrorHandler
* @see \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait
*/
protected function registerErrorHandler() {
if ($this->previousHandler || 'disabled' === getenv('SYMFONY_DEPRECATIONS_HELPER')) {
return;
}
$deprecation_handler = function ($type, $msg, $file, $line, $context = []) {
// Skip listed deprecations.
if (($type === E_USER_DEPRECATED || $type === E_DEPRECATED) && static::isDeprecationSkipped($msg)) {
return;
}
return call_user_func($this->previousHandler, $type, $msg, $file, $line, $context);
};
$this->previousHandler = set_error_handler($deprecation_handler);
}
/**
* Removes the error handler if registered.
*
* @see \Drupal\Tests\Listeners\DeprecationListenerTrait::registerErrorHandler()
*/
protected function removeErrorHandler(): void {
if ($this->previousHandler) {
$this->previousHandler = NULL;
restore_error_handler();
}
}
}
......@@ -6,25 +6,16 @@
use PHPUnit\Framework\TestListenerDefaultImplementation;
use PHPUnit\Framework\Test;
use PHPUnit\Framework\TestSuite;
use PHPUnit\Util\Test as UtilTest;
use Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait;
use Symfony\Bridge\PhpUnit\SymfonyTestsListener;
/**
* Listens to PHPUnit test runs.
*
* This listener orchestrates error handlers to ensure deprecations are skipped
* when \Drupal\Tests\Listeners\DeprecationListenerTrait::isDeprecationSkipped()
* returns TRUE. It removes test listeners to ensure that when
* \Symfony\Bridge\PhpUnit\DeprecationErrorHandler::shutdown() is run the error
* handler is in the expected state.
*
* @internal
*/
class DrupalListener implements TestListener {
use TestListenerDefaultImplementation;
use DeprecationListenerTrait;
use DrupalComponentTestListenerTrait;
use DrupalStandardsListenerTrait;
......@@ -47,7 +38,6 @@ public function __construct() {
*/
public function startTestSuite(TestSuite $suite): void {
$this->symfonyListener->startTestSuite($suite);
$this->registerErrorHandler();
}
/**
......@@ -61,11 +51,6 @@ public function addSkippedTest(Test $test, \Throwable $t, float $time): void {
* {@inheritdoc}
*/
public function startTest(Test $test): void {
// The Drupal error handler has to be registered prior to the Symfony error
// handler that is registered in
// \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::startTest()
// that handles expected deprecations.
$this->registerErrorHandler();
$this->symfonyListener->startTest($test);
// Check for incorrect visibility of the $modules property.
$class = new \ReflectionClass($test);
......@@ -78,30 +63,9 @@ public function startTest(Test $test): void {
* {@inheritdoc}
*/
public function endTest(Test $test, float $time): void {
if (!SymfonyTestsListenerTrait::$previousErrorHandler) {
$className = get_class($test);
$groups = UtilTest::getGroups($className, $test->getName(FALSE));
if (in_array('legacy', $groups, TRUE)) {
// If the Symfony listener is not registered for legacy tests then
// deprecations triggered by the DebugClassloader in
// \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest()
// are not correctly identified as occurring in legacy tests.
$symfony_error_handler = set_error_handler([SymfonyTestsListenerTrait::class, 'handleError']);
}
}
$this->deprecationEndTest($test, $time);
$this->symfonyListener->endTest($test, $time);
$this->componentEndTest($test, $time);
$this->standardsEndTest($test, $time);
if (isset($symfony_error_handler)) {
// If this test listener has added the Symfony error handler then it needs
// to be removed.
restore_error_handler();
}
// The Drupal error handler has to be removed after the Symfony error
// handler is potentially removed in
// \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest().
$this->removeErrorHandler();
}
}
<?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);
}
/**
* Tests skipping E_DEPRECATED deprecations in unit tests.
*
* @see \Drupal\Tests\Listeners\DeprecationListenerTrait::getSkippedDeprecations()
*/
public function testSkippingPhpDeprecations() {
include_once __DIR__ . '/../../fixtures/deprecated_code.php';
$this->addToAssertionCount(1);
}
}
......@@ -179,3 +179,10 @@ class_alias('\Drupal\Tests\DocumentElement', '\Behat\Mink\Element\DocumentElemen
// thrown if an assert fails, but this call does not turn runtime assertions on
// if they weren't on already.
Handle::register();
// Ensure ignored deprecation patterns listed in .deprecation-ignore.txt are
// considered in testing.
if (getenv('SYMFONY_DEPRECATIONS_HELPER') === FALSE) {
$deprecation_ignore_filename = realpath(__DIR__ . "/../.deprecation-ignore.txt");
putenv("SYMFONY_DEPRECATIONS_HELPER=ignoreFile=$deprecation_ignore_filename");
}
<?php
// @phpcs:ignoreFile
/**
* This class triggers an E_DEPRECATED notice.
*
* @see
*/
class PhpDeprecation implements \IteratorAggregate {
/**
* {@inheritdoc}
*/
public function getIterator() {
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment