minor #33491 [Debug] disable new DebugClassLoader when testing the legacy one (nicolas-grekas)
This PR was merged into the 4.4 branch.
Discussion
----------
[Debug] disable new DebugClassLoader when testing the legacy one
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
Commits
-------
25a683bbeb
[Debug] disable new DebugClassLoader when testing the legacy one
This commit is contained in:
commit
7a1545cc8f
@ -179,7 +179,7 @@ class DeprecationErrorHandler
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method_exists(DebugClassLoader::class, 'checkClasses')) {
|
if (class_exists(DebugClassLoader::class, false)) {
|
||||||
DebugClassLoader::checkClasses();
|
DebugClassLoader::checkClasses();
|
||||||
}
|
}
|
||||||
$currErrorHandler = set_error_handler('var_dump');
|
$currErrorHandler = set_error_handler('var_dump');
|
||||||
|
@ -245,6 +245,10 @@ class SymfonyTestsListenerTrait
|
|||||||
|
|
||||||
public function endTest($test, $time)
|
public function endTest($test, $time)
|
||||||
{
|
{
|
||||||
|
if (class_exists(DebugClassLoader::class, false)) {
|
||||||
|
DebugClassLoader::checkClasses();
|
||||||
|
}
|
||||||
|
|
||||||
$className = \get_class($test);
|
$className = \get_class($test);
|
||||||
$groups = Test::getGroups($className, $test->getName(false));
|
$groups = Test::getGroups($className, $test->getName(false));
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Please update when phpunit needs to be reinstalled with fresh deps:
|
// Please update when phpunit needs to be reinstalled with fresh deps:
|
||||||
// Cache-Id: 2019-09-02 16:00 UTC
|
// Cache-Id: 2019-09-06 15:00 UTC
|
||||||
|
|
||||||
error_reporting(-1);
|
error_reporting(-1);
|
||||||
|
|
||||||
|
@ -274,13 +274,14 @@ class WebTestCaseTest extends TestCase
|
|||||||
|
|
||||||
private function getTester(KernelBrowser $client): WebTestCase
|
private function getTester(KernelBrowser $client): WebTestCase
|
||||||
{
|
{
|
||||||
return new class($client) extends WebTestCase {
|
$tester = new class() extends WebTestCase {
|
||||||
use WebTestAssertionsTrait;
|
use WebTestAssertionsTrait {
|
||||||
|
getClient as public;
|
||||||
public function __construct(KernelBrowser $client)
|
|
||||||
{
|
|
||||||
self::getClient($client);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$tester::getClient($client);
|
||||||
|
|
||||||
|
return $tester;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,21 +29,23 @@ class DebugClassLoaderTest extends TestCase
|
|||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
$this->errorReporting = error_reporting(E_ALL);
|
$this->errorReporting = error_reporting(E_ALL);
|
||||||
$this->loader = new ClassLoader();
|
$this->loader = [new DebugClassLoader([new ClassLoader(), 'loadClass']), 'loadClass'];
|
||||||
spl_autoload_register([$this->loader, 'loadClass'], true, true);
|
spl_autoload_register($this->loader, true, true);
|
||||||
DebugClassLoader::enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function tearDown(): void
|
protected function tearDown(): void
|
||||||
{
|
{
|
||||||
DebugClassLoader::disable();
|
spl_autoload_unregister($this->loader);
|
||||||
spl_autoload_unregister([$this->loader, 'loadClass']);
|
|
||||||
error_reporting($this->errorReporting);
|
error_reporting($this->errorReporting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @runInSeparateProcess
|
||||||
|
*/
|
||||||
public function testIdempotence()
|
public function testIdempotence()
|
||||||
{
|
{
|
||||||
DebugClassLoader::enable();
|
DebugClassLoader::enable();
|
||||||
|
DebugClassLoader::enable();
|
||||||
|
|
||||||
$functions = spl_autoload_functions();
|
$functions = spl_autoload_functions();
|
||||||
foreach ($functions as $function) {
|
foreach ($functions as $function) {
|
||||||
@ -441,7 +443,5 @@ class ClassLoader
|
|||||||
eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsVirtualMagicCall extends \\'.__NAMESPACE__.'\Fixtures\VirtualClassMagicCall implements \\'.__NAMESPACE__.'\Fixtures\VirtualInterface {
|
eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsVirtualMagicCall extends \\'.__NAMESPACE__.'\Fixtures\VirtualClassMagicCall implements \\'.__NAMESPACE__.'\Fixtures\VirtualInterface {
|
||||||
}');
|
}');
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -374,13 +374,22 @@ class DebugClassLoader
|
|||||||
|
|
||||||
public function checkAnnotations(\ReflectionClass $refl, string $class): array
|
public function checkAnnotations(\ReflectionClass $refl, string $class): array
|
||||||
{
|
{
|
||||||
if ('Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerForV7' === $class || 'Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerForV6' === $class) {
|
if (
|
||||||
|
'Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerForV7' === $class
|
||||||
|
|| 'Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerForV6' === $class
|
||||||
|
|| 'Test\Symfony\Component\Debug\Tests' === $refl->getNamespaceName()
|
||||||
|
) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
$deprecations = [];
|
$deprecations = [];
|
||||||
|
|
||||||
|
$className = isset($class[15]) && "\0" === $class[15] && 0 === strpos($class, "class@anonymous\x00") ? get_parent_class($class).'@anonymous' : $class;
|
||||||
|
|
||||||
// Don't trigger deprecations for classes in the same vendor
|
// Don't trigger deprecations for classes in the same vendor
|
||||||
if (2 > $vendorLen = 1 + (strpos($class, '\\') ?: strpos($class, '_'))) {
|
if ($class !== $className) {
|
||||||
|
$vendor = preg_match('/^namespace ([^;\\\\\s]++)[;\\\\]/m', @file_get_contents($refl->getFileName()), $vendor) ? $vendor[1].'\\' : '';
|
||||||
|
$vendorLen = \strlen($vendor);
|
||||||
|
} elseif (2 > $vendorLen = 1 + (strpos($class, '\\') ?: strpos($class, '_'))) {
|
||||||
$vendorLen = 0;
|
$vendorLen = 0;
|
||||||
$vendor = '';
|
$vendor = '';
|
||||||
} else {
|
} else {
|
||||||
@ -424,7 +433,7 @@ class DebugClassLoader
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset(self::$final[$parent])) {
|
if (isset(self::$final[$parent])) {
|
||||||
$deprecations[] = sprintf('The "%s" class is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $parent, self::$final[$parent], $class);
|
$deprecations[] = sprintf('The "%s" class is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $parent, self::$final[$parent], $className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,10 +446,10 @@ class DebugClassLoader
|
|||||||
$type = class_exists($class, false) ? 'class' : (interface_exists($class, false) ? 'interface' : 'trait');
|
$type = class_exists($class, false) ? 'class' : (interface_exists($class, false) ? 'interface' : 'trait');
|
||||||
$verb = class_exists($use, false) || interface_exists($class, false) ? 'extends' : (interface_exists($use, false) ? 'implements' : 'uses');
|
$verb = class_exists($use, false) || interface_exists($class, false) ? 'extends' : (interface_exists($use, false) ? 'implements' : 'uses');
|
||||||
|
|
||||||
$deprecations[] = sprintf('The "%s" %s %s "%s" that is deprecated%s.', $class, $type, $verb, $use, self::$deprecated[$use]);
|
$deprecations[] = sprintf('The "%s" %s %s "%s" that is deprecated%s.', $className, $type, $verb, $use, self::$deprecated[$use]);
|
||||||
}
|
}
|
||||||
if (isset(self::$internal[$use]) && strncmp($vendor, str_replace('_', '\\', $use), $vendorLen)) {
|
if (isset(self::$internal[$use]) && strncmp($vendor, str_replace('_', '\\', $use), $vendorLen)) {
|
||||||
$deprecations[] = sprintf('The "%s" %s is considered internal%s. It may change without further notice. You should not use it from "%s".', $use, class_exists($use, false) ? 'class' : (interface_exists($use, false) ? 'interface' : 'trait'), self::$internal[$use], $class);
|
$deprecations[] = sprintf('The "%s" %s is considered internal%s. It may change without further notice. You should not use it from "%s".', $use, class_exists($use, false) ? 'class' : (interface_exists($use, false) ? 'interface' : 'trait'), self::$internal[$use], $className);
|
||||||
}
|
}
|
||||||
if (isset(self::$method[$use])) {
|
if (isset(self::$method[$use])) {
|
||||||
if ($refl->isAbstract()) {
|
if ($refl->isAbstract()) {
|
||||||
@ -459,7 +468,7 @@ class DebugClassLoader
|
|||||||
}
|
}
|
||||||
$realName = substr($name, 0, strpos($name, '('));
|
$realName = substr($name, 0, strpos($name, '('));
|
||||||
if (!$refl->hasMethod($realName) || !($methodRefl = $refl->getMethod($realName))->isPublic() || ($static && !$methodRefl->isStatic()) || (!$static && $methodRefl->isStatic())) {
|
if (!$refl->hasMethod($realName) || !($methodRefl = $refl->getMethod($realName))->isPublic() || ($static && !$methodRefl->isStatic()) || (!$static && $methodRefl->isStatic())) {
|
||||||
$deprecations[] = sprintf('Class "%s" should implement method "%s::%s"%s', $class, ($static ? 'static ' : '').$interface, $name, null == $description ? '.' : ': '.$description);
|
$deprecations[] = sprintf('Class "%s" should implement method "%s::%s"%s', $className, ($static ? 'static ' : '').$interface, $name, null == $description ? '.' : ': '.$description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -516,13 +525,13 @@ class DebugClassLoader
|
|||||||
|
|
||||||
if ($parent && isset(self::$finalMethods[$parent][$method->name])) {
|
if ($parent && isset(self::$finalMethods[$parent][$method->name])) {
|
||||||
list($declaringClass, $message) = self::$finalMethods[$parent][$method->name];
|
list($declaringClass, $message) = self::$finalMethods[$parent][$method->name];
|
||||||
$deprecations[] = sprintf('The "%s::%s()" method is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $declaringClass, $method->name, $message, $class);
|
$deprecations[] = sprintf('The "%s::%s()" method is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $declaringClass, $method->name, $message, $className);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset(self::$internalMethods[$class][$method->name])) {
|
if (isset(self::$internalMethods[$class][$method->name])) {
|
||||||
list($declaringClass, $message) = self::$internalMethods[$class][$method->name];
|
list($declaringClass, $message) = self::$internalMethods[$class][$method->name];
|
||||||
if (strncmp($ns, $declaringClass, $len)) {
|
if (strncmp($ns, $declaringClass, $len)) {
|
||||||
$deprecations[] = sprintf('The "%s::%s()" method is considered internal%s. It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $class);
|
$deprecations[] = sprintf('The "%s::%s()" method is considered internal%s. It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,7 +546,7 @@ class DebugClassLoader
|
|||||||
|
|
||||||
foreach (self::$annotatedParameters[$class][$method->name] as $parameterName => $deprecation) {
|
foreach (self::$annotatedParameters[$class][$method->name] as $parameterName => $deprecation) {
|
||||||
if (!isset($definedParameters[$parameterName]) && !($doc && preg_match("/\\n\\s+\\* @param +((?(?!callable *\().*?|callable *\(.*\).*?))(?<= )\\\${$parameterName}\\b/", $doc))) {
|
if (!isset($definedParameters[$parameterName]) && !($doc && preg_match("/\\n\\s+\\* @param +((?(?!callable *\().*?|callable *\(.*\).*?))(?<= )\\\${$parameterName}\\b/", $doc))) {
|
||||||
$deprecations[] = sprintf($deprecation, $class);
|
$deprecations[] = sprintf($deprecation, $className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -575,7 +584,7 @@ class DebugClassLoader
|
|||||||
if ($canAddReturnType && 'docblock' === ($this->patchTypes['force'] ?? false) && false === strpos($method->getFileName(), \DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR)) {
|
if ($canAddReturnType && 'docblock' === ($this->patchTypes['force'] ?? false) && false === strpos($method->getFileName(), \DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR)) {
|
||||||
$this->patchMethod($method, $returnType, $declaringFile, $normalizedType);
|
$this->patchMethod($method, $returnType, $declaringFile, $normalizedType);
|
||||||
} elseif ('' !== $declaringClass) {
|
} elseif ('' !== $declaringClass) {
|
||||||
$deprecations[] = sprintf('Method "%s::%s()" will return "%s" as of its next major version. Doing the same in child class "%s" will be required when upgrading.', $declaringClass, $method->name, $normalizedType, $class);
|
$deprecations[] = sprintf('Method "%s::%s()" will return "%s" as of its next major version. Doing the same in child class "%s" will be required when upgrading.', $declaringClass, $method->name, $normalizedType, $className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -632,7 +641,7 @@ class DebugClassLoader
|
|||||||
foreach ($matches as list(, $parameterType, $parameterName)) {
|
foreach ($matches as list(, $parameterType, $parameterName)) {
|
||||||
if (!isset($definedParameters[$parameterName])) {
|
if (!isset($definedParameters[$parameterName])) {
|
||||||
$parameterType = trim($parameterType);
|
$parameterType = trim($parameterType);
|
||||||
self::$annotatedParameters[$class][$method->name][$parameterName] = sprintf('The "%%s::%s()" method will require a new "%s$%s" argument in the next major version of its parent class "%s", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, $class);
|
self::$annotatedParameters[$class][$method->name][$parameterName] = sprintf('The "%%s::%s()" method will require a new "%s$%s" argument in the next major version of its parent class "%s", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, $className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,21 +26,23 @@ class DebugClassLoaderTest extends TestCase
|
|||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
$this->errorReporting = error_reporting(E_ALL);
|
$this->errorReporting = error_reporting(E_ALL);
|
||||||
$this->loader = new ClassLoader();
|
$this->loader = [new DebugClassLoader([new ClassLoader(), 'loadClass']), 'loadClass'];
|
||||||
spl_autoload_register([$this->loader, 'loadClass'], true, true);
|
spl_autoload_register($this->loader, true, true);
|
||||||
DebugClassLoader::enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function tearDown(): void
|
protected function tearDown(): void
|
||||||
{
|
{
|
||||||
DebugClassLoader::disable();
|
spl_autoload_unregister($this->loader);
|
||||||
spl_autoload_unregister([$this->loader, 'loadClass']);
|
|
||||||
error_reporting($this->errorReporting);
|
error_reporting($this->errorReporting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @runInSeparateProcess
|
||||||
|
*/
|
||||||
public function testIdempotence()
|
public function testIdempotence()
|
||||||
{
|
{
|
||||||
DebugClassLoader::enable();
|
DebugClassLoader::enable();
|
||||||
|
DebugClassLoader::enable();
|
||||||
|
|
||||||
$functions = spl_autoload_functions();
|
$functions = spl_autoload_functions();
|
||||||
foreach ($functions as $function) {
|
foreach ($functions as $function) {
|
||||||
@ -76,6 +78,7 @@ class DebugClassLoaderTest extends TestCase
|
|||||||
public function testNameCaseMismatch()
|
public function testNameCaseMismatch()
|
||||||
{
|
{
|
||||||
$this->expectException('RuntimeException');
|
$this->expectException('RuntimeException');
|
||||||
|
$this->expectExceptionMessage('Case mismatch between loaded and declared class names');
|
||||||
class_exists(__NAMESPACE__.'\TestingCaseMismatch', true);
|
class_exists(__NAMESPACE__.'\TestingCaseMismatch', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +96,7 @@ class DebugClassLoaderTest extends TestCase
|
|||||||
public function testPsr4CaseMismatch()
|
public function testPsr4CaseMismatch()
|
||||||
{
|
{
|
||||||
$this->expectException('RuntimeException');
|
$this->expectException('RuntimeException');
|
||||||
|
$this->expectExceptionMessage('Case mismatch between loaded and declared class names');
|
||||||
class_exists(__NAMESPACE__.'\Fixtures\Psr4CaseMismatch', true);
|
class_exists(__NAMESPACE__.'\Fixtures\Psr4CaseMismatch', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user