Compare commits

...

38 Commits

Author SHA1 Message Date
Fabien Potencier
aeb73aca16 Fix typo 2020-08-10 09:47:39 +02:00
Fabien Potencier
600aa0e19e Merge branch '3.4' into 4.4
* 3.4:
  Add Tagalog translations for validator messages 94, 95, 96 and 99
  PHPUnit's assertContains() performs strict comparisons now.
  [ClassLoader][Routing] Fix namespace parsing on php 8.
  Fix deprecated libxml_disable_entity_loader
  Made reference to PHPUnit\Util\XML::loadfile php5-compatible.
  [Validator] Add missing translations for german and vietnamese
  Modernized deprecated PHPUnit assertion calls
  [Console] The message of "class not found" errors has changed in php 8.
  The PHPUnit\Util\XML class has been removed in PHPUnit 9.3.
  [Console] Make sure we pass a numeric array of arguments to call_user_func_array().
  [Serializer] Fix that it will never reach DOMNode
  [Validator] sync translations
  [VarDumper] Improve previous fix on light array coloration
  [Cache] Fix #37667
2020-08-10 09:27:51 +02:00
Alexander M. Turek
0893a0b07c Modernized deprecated PHPUnit assertion calls 2020-08-09 10:13:48 +02:00
Nicolas Grekas
47aa9064d7 Merge branch '3.4' into 4.4
* 3.4:
  [Cache] fix catching auth errors
  Fix CS
  [FrameworkBundle] set default session.handler alias if handler_id is not provided
  Fix CS
  Readability update
  Fix checks for phpunit releases on Composer 2 (resolves #37601)
  [SCA] Minor fixes on tests
2020-07-23 10:31:43 +02:00
Thomas Calvet
7ce874f443 [SCA] Minor fixes on tests 2020-07-16 11:41:49 +02:00
Nicolas Grekas
bd613a9662 Merge branch '3.4' into 4.4
* 3.4:
  [ErrorHandler] fix throwing from __toString()
  Removed comments and requirements relative to php <5.5 (not supported anymore)
  fix validating lazy properties that evaluate to null
2020-06-30 19:40:09 +02:00
Nicolas Grekas
f34d2bf035 [ErrorHandler] fix throwing from __toString() 2020-06-30 19:28:29 +02:00
Alexander M. Turek
28f92d08bb Parse and render anonymous classes correctly on php 8 2020-05-24 10:33:35 +02:00
Nicolas Grekas
8f904cac22 Merge branch '3.4' into 4.4
* 3.4:
  Skip Doctrine DBAL on php 8 until we have a compatible version.
  [DomCrawler] Catch expected ValueError.
  [Validator] Catch expected ValueError.
  [VarDumper] ReflectionFunction::isDisabled() is deprecated.
  [PropertyAccess] Parse php 8 TypeErrors correctly.
  [Intl] Fix call to ReflectionProperty::getValue() for static properties.
  [HttpKernel] Prevent calling method_exists() with non-string values.
  [Debug] php 8 does not pass $context to error handlers.
  [Config] Removed implicit cast of ReflectionProperty to string.
  [Debug] Undefined variables raise a warning in php 8.
  [Debug] Skip test that would trigger a fatal error on php 8.
  Address deprecation of ReflectionType::getClass().
  Properties $originalName and $mimeType are never null in UploadedFile
2020-05-23 11:11:46 +02:00
Nicolas Grekas
518c6a00d0 minor #36898 [Debug] php 8 does not pass $context to error handlers (derrabus)
This PR was merged into the 3.4 branch.

Discussion
----------

[Debug] php 8 does not pass $context to error handlers

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | #36872
| License       | MIT
| Doc PR        | N/A

php 8 will call error handlers without the optional `$context` parameter. Thus, error handlers that make that parameter mandatory will break.

Commits
-------

593897c9e1 [Debug] php 8 does not pass $context to error handlers.
2020-05-22 20:25:20 +02:00
Alexander M. Turek
2560754c36 [Debug] php 8 does not pass $context to error handlers. 2020-05-22 13:12:29 +02:00
Alexander M. Turek
44897cd605 [Debug] Undefined variables raise a warning in php 8. 2020-05-22 12:23:23 +02:00
Alexander M. Turek
7e9cd457b4 [Debug] Skip test that would trigger a fatal error on php 8. 2020-05-21 16:02:48 +02:00
Nicolas Grekas
6aa62a36bc Use ">=" for the "php" requirement 2020-05-20 10:37:50 +02:00
Nicolas Grekas
4431584a89 [Debug][ErrorHandler] cleanup phpunit.xml.dist files 2020-05-01 18:55:10 +02:00
Tobias Schultze
346636d2ca add missing gitattributes for phpunit-bridge 2020-03-27 17:54:36 +01:00
Nicolas Grekas
f0ae2b4150 Merge branch '3.4' into 4.4
* 3.4:
  [Http Foundation] Fix clear cookie samesite
  [Security] Check if firewall is stateless before checking for session/previous session
  [Form] Support customized intl php.ini settings
  [Security] Remember me: allow to set the samesite cookie flag
  [Debug] fix for PHP 7.3.16+/7.4.4+
  [Validator] Backport translations
  Prevent warning in proc_open()
2020-03-23 13:37:11 +01:00
Nicolas Grekas
ce9f3b5e8e [Debug] fix for PHP 7.3.16+/7.4.4+ 2020-03-23 11:22:40 +01:00
Fabien Potencier
f9385709e7 Merge branch '3.4' into 4.4
* 3.4:
  Add missing dots at the end of exception messages
2020-03-15 11:05:03 +01:00
Fabien Potencier
ed3231ef38 Add missing dots at the end of exception messages 2020-03-15 10:38:08 +01:00
Jules Pietri
a980d87a65 [Debug][ErrorHandler] improved deprecation notices for methods new args and return type 2020-02-23 15:41:43 +01:00
Fabien Potencier
ef8d82f96d Merge branch '3.4' into 4.4
* 3.4:
  [Translation] Add missing use statement
  [Translation][Debug] Add installation and minimal example to README
  [Validator] try to call __get method if property is uninitialized
  Fix handling of empty_data's \Closure value in Date/Time form types
2020-02-04 08:40:16 +01:00
Wouter de Jong
a99278d50a [Translation][Debug] Add installation and minimal example to README 2020-02-03 16:10:40 +01:00
Nicolas Grekas
2023647105 Merge branch '4.3' into 4.4
* 4.3:
  Fix displaying anonymous classes on PHP >= 7.4.2
2020-01-25 13:44:29 +01:00
Nicolas Grekas
8e36299635 Fix displaying anonymous classes on PHP >= 7.4.2 2020-01-25 13:32:28 +01:00
Nicolas Grekas
89c3fd5c29 Merge branch '4.3' into 4.4
* 4.3:
  [Debug] fix ClassNotFoundFatalErrorHandler
  [Routing] Fix using a custom matcher & generator dumper class
  [Dotenv] Fixed infinite loop with missing quote followed by quoted value
  [HttpClient] Added missing sprintf
  [TwigBridge] button_widget now has its title attr translated even if its label = null or false
  [PhpUnitBridge] When using phpenv + phpenv-composer plugin, composer executable is wrapped into a bash script
  [Messenger] Added check if json_encode succeeded
  [Security] Prevent canceled remember-me cookie from being accepted
  [FrameworkBundle][TranslationUpdateCommand] Do not output positive feedback on stderr
  [Security\Guard] Fix missing typehints
2020-01-08 18:29:02 +01:00
Nicolas Grekas
1eff904a95 Merge branch '3.4' into 4.3
* 3.4:
  [Debug] fix ClassNotFoundFatalErrorHandler
  [Dotenv] Fixed infinite loop with missing quote followed by quoted value
  [TwigBridge] button_widget now has its title attr translated even if its label = null or false
  [PhpUnitBridge] When using phpenv + phpenv-composer plugin, composer executable is wrapped into a bash script
  [Security] Prevent canceled remember-me cookie from being accepted
  [FrameworkBundle][TranslationUpdateCommand] Do not output positive feedback on stderr
2020-01-08 18:19:22 +01:00
Nicolas Grekas
70dd18e93b [Debug] fix ClassNotFoundFatalErrorHandler 2020-01-08 17:36:15 +01:00
Nicolas Grekas
bb2ab8bc2d Merge branch '4.3' into 4.4
* 4.3:
  [Mailer] Remove line breaks in email attachment content
  Update links to documentation
  [Validator] Add the missing translations for the Arabic (ar) locale
  ensure to expect no validation for the right reasons
  [PhpUnitBridge] Add test case for @expectedDeprecation annotation
  [PhpUnitBridge][SymfonyTestsListenerTrait] Remove $testsWithWarnings stack
  [Mailer][MailchimpBridge] Fix missing attachments when sending via Mandrill API
  [Mailer][MailchimpBridge] Fix incorrect sender address when sender has name
  [HttpClient] fix capturing SSL certificates with NativeHttpClient
  [TwigBridge][Form] Added missing help messages in form themes
  Update year in license files
  Update year in license files
  [HttpClient] fix typo
  [Console][FormatterHelper] Use helper strlen statically and remove duplicated code
  [Routing] Fix i18n routing when the url contains the locale
  Fix BC issue in phpDoc Reflection library
  [Translator] Performance improvement in MessageCatalogue and catalogue operations.
2020-01-04 14:00:46 +01:00
Nicolas Grekas
e45fa0c74a Merge branch '3.4' into 4.3
* 3.4:
  Update links to documentation
  [Validator] Add the missing translations for the Arabic (ar) locale
  ensure to expect no validation for the right reasons
  [PhpUnitBridge] Add test case for @expectedDeprecation annotation
  Update year in license files
  [Console][FormatterHelper] Use helper strlen statically and remove duplicated code
  Fix BC issue in phpDoc Reflection library
  [Translator] Performance improvement in MessageCatalogue and catalogue operations.
2020-01-04 13:24:57 +01:00
Shaharia Azam
9a81b6360b Update links to documentation 2020-01-04 13:05:51 +01:00
Jan Rosier
cbe127b719 Update year in license files 2020-01-01 12:03:25 +01:00
Nicolas Grekas
5c4c1db977 Merge branch '4.3' into 4.4
* 4.3:
  Fix displaying anonymous classes on PHP 7.4
2019-12-16 15:46:54 +01:00
Nicolas Grekas
c533fe8d14 Fix displaying anonymous classes on PHP 7.4 2019-12-16 15:20:08 +01:00
Nicolas Grekas
b9b11cec64 Merge branch '4.3' into 4.4
* 4.3:
  Use `::class` constants instead of `__NAMESPACE__` when possible
2019-12-16 12:07:37 +01:00
Nicolas Grekas
ba2ce2f0ee Merge branch '3.4' into 4.3
* 3.4:
  Use `::class` constants instead of `__NAMESPACE__` when possible
2019-12-16 12:02:49 +01:00
Artem Henvald
9d32af2d83 Use ::class constants instead of __NAMESPACE__ when possible 2019-12-16 11:25:54 +01:00
Javier Eguiluz
46447ad343 [Debug] Updated the README to deprecate the component 2019-12-10 11:48:09 +01:00
15 changed files with 152 additions and 87 deletions

1
.gitattributes vendored
View File

@@ -1,3 +1,4 @@
/Tests export-ignore
/phpunit.xml.dist export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore

View File

@@ -391,7 +391,7 @@ class DebugClassLoader
foreach ($matches as list(, $parameterType, $parameterName)) {
if (!isset($definedParameters[$parameterName])) {
$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, $method->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 %s "%s", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, interface_exists($class) ? 'interface' : 'parent class', $method->class);
}
}
}

View File

@@ -226,14 +226,14 @@ class ErrorHandler
if (!\is_array($log)) {
$log = [$log];
} elseif (!\array_key_exists(0, $log)) {
throw new \InvalidArgumentException('No logger provided');
throw new \InvalidArgumentException('No logger provided.');
}
if (null === $log[0]) {
$this->loggedErrors &= ~$type;
} elseif ($log[0] instanceof LoggerInterface) {
$this->loggedErrors |= $type;
} else {
throw new \InvalidArgumentException('Invalid logger provided');
throw new \InvalidArgumentException('Invalid logger provided.');
}
$this->loggers[$type] = $log + $prev[$type];
@@ -403,19 +403,7 @@ class ErrorHandler
}
$scope = $this->scopedErrors & $type;
if (4 < $numArgs = \func_num_args()) {
$context = $scope ? (func_get_arg(4) ?: []) : [];
} else {
$context = [];
}
if (isset($context['GLOBALS']) && $scope) {
$e = $context; // Whatever the signature of the method,
unset($e['GLOBALS'], $context); // $context is always a reference in 5.3
$context = $e;
}
if (false !== strpos($message, "class@anonymous\0")) {
if (false !== strpos($message, "@anonymous\0")) {
$logMessage = $this->levels[$type].': '.(new FlattenException())->setMessage($message)->getMessage();
} else {
$logMessage = $this->levels[$type].': '.$message;
@@ -476,6 +464,8 @@ class ErrorHandler
// `return trigger_error($e, E_USER_ERROR);` allows this error handler
// to make $e get through the __toString() barrier.
$context = 4 < \func_num_args() ? (func_get_arg(4) ?: []) : [];
foreach ($context as $e) {
if ($e instanceof \Throwable && $e->__toString() === $message) {
self::$toStringException = $e;
@@ -499,7 +489,7 @@ class ErrorHandler
if ($this->isRecursive) {
$log = 0;
} else {
if (!\defined('HHVM_VERSION')) {
if (\PHP_VERSION_ID < (\PHP_VERSION_ID < 70400 ? 70316 : 70404) && !\defined('HHVM_VERSION')) {
$currentErrorHandler = set_error_handler('var_dump');
restore_error_handler();
}
@@ -511,7 +501,7 @@ class ErrorHandler
} finally {
$this->isRecursive = false;
if (!\defined('HHVM_VERSION')) {
if (\PHP_VERSION_ID < (\PHP_VERSION_ID < 70400 ? 70316 : 70404) && !\defined('HHVM_VERSION')) {
set_error_handler($currentErrorHandler);
}
}
@@ -540,7 +530,7 @@ class ErrorHandler
$handlerException = null;
if (($this->loggedErrors & $type) || $exception instanceof FatalThrowableError) {
if (false !== strpos($message = $exception->getMessage(), "class@anonymous\0")) {
if (false !== strpos($message = $exception->getMessage(), "@anonymous\0")) {
$message = (new FlattenException())->setMessage($message)->getMessage();
}
if ($exception instanceof FatalErrorException) {

View File

@@ -26,7 +26,7 @@ class FatalThrowableError extends FatalErrorException
public function __construct(\Throwable $e)
{
$this->originalClassName = \get_class($e);
$this->originalClassName = get_debug_type($e);
if ($e instanceof \ParseError) {
$severity = E_PARSE;

View File

@@ -67,7 +67,7 @@ class FlattenException
$e->setStatusCode($statusCode);
$e->setHeaders($headers);
$e->setTraceFromThrowable($exception);
$e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : \get_class($exception));
$e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : get_debug_type($exception));
$e->setFile($exception->getFile());
$e->setLine($exception->getLine());
@@ -134,7 +134,7 @@ class FlattenException
*/
public function setClass($class)
{
$this->class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class;
$this->class = false !== strpos($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class;
return $this;
}
@@ -179,9 +179,9 @@ class FlattenException
*/
public function setMessage($message)
{
if (false !== strpos($message, "class@anonymous\0")) {
$message = preg_replace_callback('/class@anonymous\x00.*?\.php0x?[0-9a-fA-F]++/', function ($m) {
return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0];
if (false !== strpos($message, "@anonymous\0")) {
$message = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) {
return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0];
}, $message);
}

View File

@@ -256,7 +256,11 @@ EOF
foreach ($e['trace'] as $trace) {
$content .= '<tr><td>';
if ($trace['function']) {
$content .= sprintf('at <span class="trace-class">%s</span><span class="trace-type">%s</span><span class="trace-method">%s</span>(<span class="trace-arguments">%s</span>)', $this->formatClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args']));
$content .= sprintf('at <span class="trace-class">%s</span><span class="trace-type">%s</span><span class="trace-method">%s</span>', $this->formatClass($trace['class']), $trace['type'], $trace['function']);
if (isset($trace['args'])) {
$content .= sprintf('(<span class="trace-arguments">%s</span>)', $this->formatArgs($trace['args']));
}
}
if (isset($trace['file']) && isset($trace['line'])) {
$content .= $this->formatPath($trace['file'], $trace['line']);

View File

@@ -1,4 +1,4 @@
Copyright (c) 2004-2019 Fabien Potencier
Copyright (c) 2004-2020 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,12 +1,29 @@
Debug Component
===============
**CAUTION**: this component is deprecated since Symfony 4.4. Instead, use the
[ErrorHandler component](https://github.com/symfony/symfony/tree/master/src/Symfony/Component/ErrorHandler).
-----
The Debug component provides tools to ease debugging PHP code.
Getting Started
---------------
```
$ composer install symfony/debug
```
```php
use Symfony\Component\Debug\Debug;
Debug::enable();
```
Resources
---------
* [Documentation](https://symfony.com/doc/current/components/debug/index.html)
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
* [Report issues](https://github.com/symfony/symfony/issues) and
[send Pull Requests](https://github.com/symfony/symfony/pulls)

View File

@@ -68,21 +68,21 @@ class DebugClassLoaderTest extends TestCase
$this->expectException('Exception');
$this->expectExceptionMessage('boo');
try {
class_exists(__NAMESPACE__.'\Fixtures\Throwing');
class_exists(Fixtures\Throwing::class);
$this->fail('Exception expected');
} catch (\Exception $e) {
$this->assertSame('boo', $e->getMessage());
}
// the second call also should throw
class_exists(__NAMESPACE__.'\Fixtures\Throwing');
class_exists(Fixtures\Throwing::class);
}
public function testNameCaseMismatch()
{
$this->expectException('RuntimeException');
$this->expectExceptionMessage('Case mismatch between loaded and declared class names');
class_exists(__NAMESPACE__.'\TestingCaseMismatch', true);
class_exists(TestingCaseMismatch::class, true);
}
public function testFileCaseMismatch()
@@ -93,7 +93,7 @@ class DebugClassLoaderTest extends TestCase
$this->markTestSkipped('Can only be run on case insensitive filesystems');
}
class_exists(__NAMESPACE__.'\Fixtures\CaseMismatch', true);
class_exists(Fixtures\CaseMismatch::class, true);
}
public function testPsr4CaseMismatch()
@@ -115,7 +115,7 @@ class DebugClassLoaderTest extends TestCase
public function testClassAlias()
{
$this->assertTrue(class_exists(__NAMESPACE__.'\Fixtures\ClassAlias', true));
$this->assertTrue(class_exists(Fixtures\ClassAlias::class, true));
}
/**
@@ -157,7 +157,7 @@ class DebugClassLoaderTest extends TestCase
$e = error_reporting(0);
trigger_error('', E_USER_NOTICE);
class_exists('Test\\'.__NAMESPACE__.'\\NonDeprecatedInterfaceClass', true);
class_exists('Test\\'.NonDeprecatedInterfaceClass::class, true);
error_reporting($e);
restore_error_handler();
@@ -204,7 +204,7 @@ class DebugClassLoaderTest extends TestCase
require __DIR__.'/Fixtures/FinalClasses.php';
$i = 1;
while (class_exists($finalClass = __NAMESPACE__.'\\Fixtures\\FinalClass'.$i++, false)) {
while (class_exists($finalClass = Fixtures\FinalClass::class.$i++, false)) {
spl_autoload_call($finalClass);
class_exists('Test\\'.__NAMESPACE__.'\\Extends'.substr($finalClass, strrpos($finalClass, '\\') + 1), true);
}
@@ -230,7 +230,7 @@ class DebugClassLoaderTest extends TestCase
set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
$e = error_reporting(E_USER_DEPRECATED);
class_exists(__NAMESPACE__.'\\Fixtures\\ExtendedFinalMethod', true);
class_exists(Fixtures\ExtendedFinalMethod::class, true);
error_reporting($e);
restore_error_handler();
@@ -249,7 +249,7 @@ class DebugClassLoaderTest extends TestCase
$e = error_reporting(0);
trigger_error('', E_USER_NOTICE);
class_exists('Test\\'.__NAMESPACE__.'\\ExtendsAnnotatedClass', true);
class_exists('Test\\'.ExtendsAnnotatedClass::class, true);
error_reporting($e);
restore_error_handler();
@@ -266,7 +266,7 @@ class DebugClassLoaderTest extends TestCase
set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
$e = error_reporting(E_USER_DEPRECATED);
class_exists('Test\\'.__NAMESPACE__.'\\ExtendsInternals', true);
class_exists('Test\\'.ExtendsInternals::class, true);
error_reporting($e);
restore_error_handler();
@@ -285,19 +285,19 @@ class DebugClassLoaderTest extends TestCase
set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
$e = error_reporting(E_USER_DEPRECATED);
class_exists(__NAMESPACE__.'\\Fixtures\SubClassWithAnnotatedParameters', true);
class_exists(Fixtures\SubClassWithAnnotatedParameters::class, true);
error_reporting($e);
restore_error_handler();
$this->assertSame([
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::quzMethod()" method will require a new "Quz $quz" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\ClassWithAnnotatedParameters", not defining it is deprecated.',
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::whereAmI()" method will require a new "bool $matrix" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::iAmHere()" method will require a new "$noType" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::iAmHere()" method will require a new "callable(\Throwable|null $reason, mixed $value) $callback" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::iAmHere()" method will require a new "string $param" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::iAmHere()" method will require a new "callable ($a, $b) $anotherOne" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::iAmHere()" method will require a new "Type$WithDollarIsStillAType $ccc" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::whereAmI()" method will require a new "bool $matrix" argument in the next major version of its interface "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::iAmHere()" method will require a new "$noType" argument in the next major version of its interface "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::iAmHere()" method will require a new "callable(\Throwable|null $reason, mixed $value) $callback" argument in the next major version of its interface "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::iAmHere()" method will require a new "string $param" argument in the next major version of its interface "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::iAmHere()" method will require a new "callable ($a, $b) $anotherOne" argument in the next major version of its interface "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::iAmHere()" method will require a new "Type$WithDollarIsStillAType $ccc" argument in the next major version of its interface "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::isSymfony()" method will require a new "true $yes" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\ClassWithAnnotatedParameters", not defining it is deprecated.',
], $deprecations);
}
@@ -308,7 +308,7 @@ class DebugClassLoaderTest extends TestCase
set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
$e = error_reporting(E_USER_DEPRECATED);
class_exists('Test\\'.__NAMESPACE__.'\\UseTraitWithInternalMethod', true);
class_exists('Test\\'.UseTraitWithInternalMethod::class, true);
error_reporting($e);
restore_error_handler();
@@ -322,7 +322,7 @@ class DebugClassLoaderTest extends TestCase
set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
$e = error_reporting(E_USER_DEPRECATED);
class_exists('Test\\'.__NAMESPACE__.'\\ExtendsVirtual', true);
class_exists('Test\\'.ExtendsVirtual::class, true);
error_reporting($e);
restore_error_handler();
@@ -348,7 +348,7 @@ class DebugClassLoaderTest extends TestCase
set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
$e = error_reporting(E_USER_DEPRECATED);
class_exists('Test\\'.__NAMESPACE__.'\\ExtendsVirtualMagicCall', true);
class_exists('Test\\'.ExtendsVirtualMagicCall::class, true);
error_reporting($e);
restore_error_handler();
@@ -358,7 +358,7 @@ class DebugClassLoaderTest extends TestCase
public function testEvaluatedCode()
{
$this->assertTrue(class_exists(__NAMESPACE__.'\Fixtures\DefinitionInEvaluatedCode', true));
$this->assertTrue(class_exists(Fixtures\DefinitionInEvaluatedCode::class, true));
}
}
@@ -377,11 +377,11 @@ class ClassLoader
{
$fixtureDir = __DIR__.\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR;
if (__NAMESPACE__.'\TestingUnsilencing' === $class) {
if (TestingUnsilencing::class === $class) {
eval('-- parse error --');
} elseif (__NAMESPACE__.'\TestingStacking' === $class) {
} elseif (TestingStacking::class === $class) {
eval('namespace '.__NAMESPACE__.'; class TestingStacking { function foo() {} }');
} elseif (__NAMESPACE__.'\TestingCaseMismatch' === $class) {
} elseif (TestingCaseMismatch::class === $class) {
eval('namespace '.__NAMESPACE__.'; class TestingCaseMisMatch {}');
} elseif (__NAMESPACE__.'\Fixtures\Psr4CaseMismatch' === $class) {
return $fixtureDir.'psr4'.\DIRECTORY_SEPARATOR.'Psr4CaseMismatch.php';
@@ -391,55 +391,55 @@ class ClassLoader
return $fixtureDir.'notPsr0Bis.php';
} elseif ('Symfony\Bridge\Debug\Tests\Fixtures\ExtendsDeprecatedParent' === $class) {
eval('namespace Symfony\Bridge\Debug\Tests\Fixtures; class ExtendsDeprecatedParent extends \\'.__NAMESPACE__.'\Fixtures\DeprecatedClass {}');
} elseif ('Test\\'.__NAMESPACE__.'\DeprecatedParentClass' === $class) {
} elseif ('Test\\'.DeprecatedParentClass::class === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class DeprecatedParentClass extends \\'.__NAMESPACE__.'\Fixtures\DeprecatedClass {}');
} elseif ('Test\\'.__NAMESPACE__.'\DeprecatedInterfaceClass' === $class) {
} elseif ('Test\\'.DeprecatedInterfaceClass::class === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class DeprecatedInterfaceClass implements \\'.__NAMESPACE__.'\Fixtures\DeprecatedInterface {}');
} elseif ('Test\\'.__NAMESPACE__.'\NonDeprecatedInterfaceClass' === $class) {
} elseif ('Test\\'.NonDeprecatedInterfaceClass::class === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class NonDeprecatedInterfaceClass implements \\'.__NAMESPACE__.'\Fixtures\NonDeprecatedInterface {}');
} elseif ('Test\\'.__NAMESPACE__.'\Float' === $class) {
} elseif ('Test\\'.Float::class === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class Float {}');
} elseif (0 === strpos($class, 'Test\\'.__NAMESPACE__.'\ExtendsFinalClass')) {
} elseif (0 === strpos($class, 'Test\\'.ExtendsFinalClass::class)) {
$classShortName = substr($class, strrpos($class, '\\') + 1);
eval('namespace Test\\'.__NAMESPACE__.'; class '.$classShortName.' extends \\'.__NAMESPACE__.'\Fixtures\\'.substr($classShortName, 7).' {}');
} elseif ('Test\\'.__NAMESPACE__.'\ExtendsAnnotatedClass' === $class) {
} elseif ('Test\\'.ExtendsAnnotatedClass::class === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsAnnotatedClass extends \\'.__NAMESPACE__.'\Fixtures\AnnotatedClass {
public function deprecatedMethod() { }
}');
} elseif ('Test\\'.__NAMESPACE__.'\ExtendsInternals' === $class) {
} elseif ('Test\\'.ExtendsInternals::class === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsInternals extends ExtendsInternalsParent {
use \\'.__NAMESPACE__.'\Fixtures\InternalTrait;
public function internalMethod() { }
}');
} elseif ('Test\\'.__NAMESPACE__.'\ExtendsInternalsParent' === $class) {
} elseif ('Test\\'.ExtendsInternalsParent::class === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsInternalsParent extends \\'.__NAMESPACE__.'\Fixtures\InternalClass implements \\'.__NAMESPACE__.'\Fixtures\InternalInterface { }');
} elseif ('Test\\'.__NAMESPACE__.'\UseTraitWithInternalMethod' === $class) {
} elseif ('Test\\'.UseTraitWithInternalMethod::class === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class UseTraitWithInternalMethod { use \\'.__NAMESPACE__.'\Fixtures\TraitWithInternalMethod; }');
} elseif ('Test\\'.__NAMESPACE__.'\ExtendsVirtual' === $class) {
} elseif ('Test\\'.ExtendsVirtual::class === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsVirtual extends ExtendsVirtualParent implements \\'.__NAMESPACE__.'\Fixtures\VirtualSubInterface {
public function ownClassMethod() { }
public function classMethod() { }
public function sameLineInterfaceMethodNoBraces() { }
}');
} elseif ('Test\\'.__NAMESPACE__.'\ExtendsVirtualParent' === $class) {
} elseif ('Test\\'.ExtendsVirtualParent::class === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsVirtualParent extends ExtendsVirtualAbstract {
public function ownParentMethod() { }
public function traitMethod() { }
public function sameLineInterfaceMethod() { }
public function staticMethodNoBraces() { } // should be static
}');
} elseif ('Test\\'.__NAMESPACE__.'\ExtendsVirtualAbstract' === $class) {
} elseif ('Test\\'.ExtendsVirtualAbstract::class === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; abstract class ExtendsVirtualAbstract extends ExtendsVirtualAbstractBase {
public static function staticMethod() { }
public function ownAbstractMethod() { }
public function interfaceMethod() { }
}');
} elseif ('Test\\'.__NAMESPACE__.'\ExtendsVirtualAbstractBase' === $class) {
} elseif ('Test\\'.ExtendsVirtualAbstractBase::class === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; abstract class ExtendsVirtualAbstractBase extends \\'.__NAMESPACE__.'\Fixtures\VirtualClass implements \\'.__NAMESPACE__.'\Fixtures\VirtualInterface {
public function ownAbstractBaseMethod() { }
}');
} elseif ('Test\\'.__NAMESPACE__.'\ExtendsVirtualMagicCall' === $class) {
} elseif ('Test\\'.ExtendsVirtualMagicCall::class === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsVirtualMagicCall extends \\'.__NAMESPACE__.'\Fixtures\VirtualClassMagicCall implements \\'.__NAMESPACE__.'\Fixtures\VirtualInterface {
}');
}

View File

@@ -103,9 +103,14 @@ class ErrorHandlerTest extends TestCase
$this->fail('ErrorException expected');
} catch (\ErrorException $exception) {
// if an exception is thrown, the test passed
$this->assertEquals(E_NOTICE, $exception->getSeverity());
if (\PHP_VERSION_ID < 80000) {
$this->assertEquals(E_NOTICE, $exception->getSeverity());
$this->assertMatchesRegularExpression('/^Notice: Undefined variable: (foo|bar)/', $exception->getMessage());
} else {
$this->assertEquals(E_WARNING, $exception->getSeverity());
$this->assertMatchesRegularExpression('/^Warning: Undefined variable \$(foo|bar)/', $exception->getMessage());
}
$this->assertEquals(__FILE__, $exception->getFile());
$this->assertRegExp('/^Notice: Undefined variable: (foo|bar)/', $exception->getMessage());
$trace = $exception->getTrace();
@@ -249,11 +254,17 @@ class ErrorHandlerTest extends TestCase
$line = null;
$logArgCheck = function ($level, $message, $context) use (&$line) {
$this->assertEquals('Notice: Undefined variable: undefVar', $message);
$this->assertArrayHasKey('exception', $context);
$exception = $context['exception'];
if (\PHP_VERSION_ID < 80000) {
$this->assertEquals('Notice: Undefined variable: undefVar', $message);
$this->assertSame(E_NOTICE, $exception->getSeverity());
} else {
$this->assertEquals('Warning: Undefined variable $undefVar', $message);
$this->assertSame(E_WARNING, $exception->getSeverity());
}
$this->assertInstanceOf(SilencedErrorContext::class, $exception);
$this->assertSame(E_NOTICE, $exception->getSeverity());
$this->assertSame(__FILE__, $exception->getFile());
$this->assertSame($line, $exception->getLine());
$this->assertNotEmpty($exception->getTrace());
@@ -267,8 +278,13 @@ class ErrorHandlerTest extends TestCase
;
$handler = ErrorHandler::register();
$handler->setDefaultLogger($logger, E_NOTICE);
$handler->screamAt(E_NOTICE);
if (\PHP_VERSION_ID < 80000) {
$handler->setDefaultLogger($logger, E_NOTICE);
$handler->screamAt(E_NOTICE);
} else {
$handler->setDefaultLogger($logger, E_WARNING);
$handler->screamAt(E_WARNING);
}
unset($undefVar);
$line = __LINE__ + 1;
@$undefVar++;
@@ -309,6 +325,26 @@ class ErrorHandlerTest extends TestCase
}
}
public function testHandleErrorWithAnonymousClass()
{
$handler = ErrorHandler::register();
$handler->throwAt(E_USER_WARNING, true);
try {
$handler->handleError(E_USER_WARNING, 'foo '.\get_class(new class() extends \stdClass {
}).' bar', 'foo.php', 12);
$this->fail('Exception expected.');
} catch (\ErrorException $e) {
} finally {
restore_error_handler();
restore_exception_handler();
}
$this->assertSame('User Warning: foo stdClass@anonymous bar', $e->getMessage());
$this->assertSame(E_USER_WARNING, $e->getSeverity());
$this->assertSame('foo.php', $e->getFile());
$this->assertSame(12, $e->getLine());
}
public function testHandleDeprecation()
{
$logArgCheck = function ($level, $message, $context) {
@@ -329,8 +365,6 @@ class ErrorHandlerTest extends TestCase
$handler = new ErrorHandler();
$handler->setDefaultLogger($logger);
@$handler->handleError(E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, []);
restore_error_handler();
}
public function testHandleException()

View File

@@ -174,9 +174,9 @@ class FlattenExceptionTest extends TestCase
$flattened = FlattenException::create($exception)->getPrevious();
$this->assertEquals($flattened->getMessage(), 'Oh noes!', 'The message is copied from the original exception.');
$this->assertEquals($flattened->getCode(), 42, 'The code is copied from the original exception.');
$this->assertEquals($flattened->getClass(), 'ParseError', 'The class is set to the class of the original exception');
$this->assertEquals('Oh noes!', $flattened->getMessage(), 'The message is copied from the original exception.');
$this->assertEquals(42, $flattened->getCode(), 'The code is copied from the original exception.');
$this->assertEquals('ParseError', $flattened->getClass(), 'The class is set to the class of the original exception');
}
/**
@@ -240,6 +240,10 @@ class FlattenExceptionTest extends TestCase
public function testArguments()
{
if (\PHP_VERSION_ID >= 70400) {
$this->markTestSkipped('PHP 7.4 removes arguments from exception traces.');
}
$dh = opendir(__DIR__);
$fh = tmpfile();
@@ -296,12 +300,16 @@ class FlattenExceptionTest extends TestCase
$this->assertSame(['float', INF], $array[$i++]);
// assertEquals() does not like NAN values.
$this->assertEquals($array[$i][0], 'float');
$this->assertEquals('float', $array[$i][0]);
$this->assertNan($array[$i][1]);
}
public function testRecursionInArguments()
{
if (\PHP_VERSION_ID >= 70400) {
$this->markTestSkipped('PHP 7.4 removes arguments from exception traces.');
}
$a = null;
$a = ['foo', [2, &$a]];
$exception = $this->createException($a);
@@ -313,6 +321,10 @@ class FlattenExceptionTest extends TestCase
public function testTooBigArray()
{
if (\PHP_VERSION_ID >= 70400) {
$this->markTestSkipped('PHP 7.4 removes arguments from exception traces.');
}
$a = [];
for ($i = 0; $i < 20; ++$i) {
for ($j = 0; $j < 50; ++$j) {
@@ -343,6 +355,11 @@ class FlattenExceptionTest extends TestCase
$this->assertSame('RuntimeException@anonymous', $flattened->getClass());
$flattened->setClass(\get_class(new class('Oops') extends NotFoundHttpException {
}));
$this->assertSame('Symfony\Component\HttpKernel\Exception\NotFoundHttpException@anonymous', $flattened->getClass());
$flattened = FlattenException::create(new \Exception(sprintf('Class "%s" blah.', \get_class(new class() extends \RuntimeException {
}))));

View File

@@ -32,6 +32,10 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
// get class loaders wrapped by DebugClassLoader
if ($function[0] instanceof DebugClassLoader) {
$function = $function[0]->getClassLoader();
if (!\is_array($function)) {
continue;
}
}
if ($function[0] instanceof ComposerClassLoader) {
@@ -64,7 +68,7 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
}
$this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $exception);
$this->assertSame($translatedMessage, $exception->getMessage());
$this->assertEquals($translatedMessage, $exception->getMessage());
$this->assertSame($error['type'], $exception->getSeverity());
$this->assertSame($error['file'], $exception->getFile());
$this->assertSame($error['line'], $exception->getLine());

View File

@@ -15,8 +15,8 @@ class ErrorHandlerThatUsesThePreviousOne
return $handler;
}
public function handleError($type, $message, $file, $line, $context)
public function handleError()
{
return \call_user_func(self::$previous, $type, $message, $file, $line, $context);
return \call_user_func_array(self::$previous, \func_get_args());
}
}

View File

@@ -16,8 +16,9 @@
}
],
"require": {
"php": "^7.1.3",
"psr/log": "~1.0"
"php": ">=7.1.3",
"psr/log": "~1.0",
"symfony/polyfill-php80": "^1.15"
},
"conflict": {
"symfony/http-kernel": "<3.4"

View File

@@ -14,10 +14,7 @@
<testsuites>
<testsuite name="Symfony Debug Component Test Suite">
<directory>./Tests/</directory>
</testsuite>
<testsuite name="Symfony Debug Extension Test Suite">
<directory suffix=".phpt">./Resources/ext/tests/</directory>
<directory suffix=".phpt">./Tests/</directory>
</testsuite>
</testsuites>