Merge branch '4.0'

* 4.0:
  Have weak_vendors ignore deprecations from outside
  [HttpFoundation] fixed return type of method HeaderBag::get
  [HttpFoundation] Added "resource" type on Request::create docblock
  [Console] Fix using finally where the catch can also fail
  [Process] Skip environment variables with false value in Process
  Revert "bug #25789  Enableable ArrayNodeDefinition is disabled for empty configuration (kejwmen)"
  Formatting fix in upgrade 3.0 document
  don't split lines on carriage returns when dumping
  trim spaces from unquoted scalar values
  Revert "bug #25851 [Validator] Conflict with egulias/email-validator 2.0 (emodric)"
  [DI] compilation perf tweak
  [Validator] Conflict with egulias/email-validator 2.0
  [Validator] add missing parent isset and add test
This commit is contained in:
Nicolas Grekas 2018-01-21 20:07:38 +01:00
commit 87adf25091
23 changed files with 156 additions and 66 deletions

View File

@ -75,9 +75,12 @@ class DeprecationErrorHandler
}
}
}
$path = realpath($path) ?: $path;
$realPath = realpath($path);
if (false === $realPath && '-' !== $path && 'Standard input code' !== $path) {
return true;
}
foreach ($vendors as $vendor) {
if (0 === strpos($path, $vendor) && false !== strpbrk(substr($path, strlen($vendor), 1), '/'.DIRECTORY_SEPARATOR)) {
if (0 === strpos($realPath, $vendor) && false !== strpbrk(substr($realPath, strlen($vendor), 1), '/'.DIRECTORY_SEPARATOR)) {
return true;
}
}

View File

@ -0,0 +1,3 @@
<?php
@trigger_error('I come from… afar! :D', E_USER_DEPRECATED);

View File

@ -0,0 +1,4 @@
<?php
$phar = new Phar(__DIR__.DIRECTORY_SEPARATOR.'deprecation.phar', 0, 'deprecation.phar');
$phar->buildFromDirectory(__DIR__.DIRECTORY_SEPARATOR.'deprecation');

View File

@ -0,0 +1,23 @@
--TEST--
Test DeprecationErrorHandler in weak vendors mode on eval()'d deprecation
--FILE--
<?php
putenv('SYMFONY_DEPRECATIONS_HELPER=weak_vendors');
putenv('ANSICON');
putenv('ConEmuANSI');
putenv('TERM');
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = dirname($vendor);
}
define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php');
require PHPUNIT_COMPOSER_INSTALL;
require_once __DIR__.'/../../bootstrap.php';
eval("@trigger_error('who knows where I come from?', E_USER_DEPRECATED);")
?>
--EXPECTF--
Other deprecation notices (1)

View File

@ -0,0 +1,25 @@
--TEST--
Test DeprecationErrorHandler in weak vendors mode on eval()'d deprecation
The phar can be regenerated by running php src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/generate_phar.php
--FILE--
<?php
putenv('SYMFONY_DEPRECATIONS_HELPER=weak_vendors');
putenv('ANSICON');
putenv('ConEmuANSI');
putenv('TERM');
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = dirname($vendor);
}
define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php');
require PHPUNIT_COMPOSER_INSTALL;
require_once __DIR__.'/../../bootstrap.php';
\Phar::loadPhar(__DIR__.'/deprecation.phar', 'deprecation.phar');
include 'phar://deprecation.phar/deprecation.php';
?>
--EXPECTF--
Other deprecation notices (1)

View File

@ -283,9 +283,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
->beforeNormalization()
->ifArray()
->then(function ($v) {
if (!isset($v['enabled'])) {
$v['enabled'] = !empty($v);
}
$v['enabled'] = isset($v['enabled']) ? $v['enabled'] : true;
return $v;
})

View File

@ -208,20 +208,6 @@ class ArrayNodeDefinitionTest extends TestCase
$this->assertTrue($this->getField($enabledNode, 'defaultValue'));
}
public function testEnableableNodeIsDisabledForEmptyConfigurationWhenNormalized()
{
$config = array();
$node = new ArrayNodeDefinition('root');
$node->canBeEnabled();
$this->assertEquals(
array('enabled' => false),
$node->getNode()->normalize($config),
'An enableable node is disabled by default'
);
}
public function testIgnoreExtraKeys()
{
$node = new ArrayNodeDefinition('root');
@ -297,7 +283,6 @@ class ArrayNodeDefinitionTest extends TestCase
array(array('enabled' => true, 'foo' => 'baz'), array(array('foo' => 'baz')), 'any configuration enables an enableable node'),
array(array('enabled' => false, 'foo' => 'baz'), array(array('foo' => 'baz', 'enabled' => false)), 'An enableable node can be disabled'),
array(array('enabled' => false, 'foo' => 'bar'), array(false), 'false disables an enableable node'),
array(array('enabled' => false, 'foo' => 'bar'), array(), 'enableable node is disabled by default'),
);
}

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Config\Tests\Definition\Builder;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\Tests\Fixtures\Builder\NodeBuilder as CustomNodeBuilder;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
@ -133,24 +132,6 @@ class TreeBuilderTest extends TestCase
$this->assertEquals('example', $children['child']->getExample());
}
public function testRootNodeThatCanBeEnabledIsDisabledByDefault()
{
$builder = new TreeBuilder();
$builder->root('test')
->canBeEnabled();
$tree = $builder->buildTree();
$children = $tree->getChildren();
$this->assertFalse($children['enabled']->getDefaultValue());
$processor = new Processor();
$result = $processor->process($tree, array());
$this->assertEquals(array('enabled' => false), $result);
}
public function testDefaultPathSeparatorIsDot()
{
$builder = new TreeBuilder();

View File

@ -874,6 +874,7 @@ class Application
}
$event = new ConsoleCommandEvent($command, $input, $output);
$e = null;
try {
$this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);
@ -886,13 +887,18 @@ class Application
} catch (\Throwable $e) {
$event = new ConsoleErrorEvent($input, $output, $e, $command);
$this->dispatcher->dispatch(ConsoleEvents::ERROR, $event);
$e = $event->getError();
if (0 !== $exitCode = $event->getExitCode()) {
throw $event->getError();
if (0 === $exitCode = $event->getExitCode()) {
$e = null;
}
} finally {
$event = new ConsoleTerminateEvent($command, $input, $output, $exitCode);
$this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
}
$event = new ConsoleTerminateEvent($command, $input, $output, $exitCode);
$this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
if (null !== $e) {
throw $e;
}
return $event->getExitCode();

View File

@ -1553,6 +1553,34 @@ class ApplicationTest extends TestCase
}
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage foo
*/
public function testThrowingErrorListener()
{
$dispatcher = $this->getDispatcher();
$dispatcher->addListener('console.error', function (ConsoleErrorEvent $event) {
throw new \RuntimeException('foo');
});
$dispatcher->addListener('console.command', function () {
throw new \RuntimeException('bar');
});
$application = new Application();
$application->setDispatcher($dispatcher);
$application->setAutoExit(false);
$application->setCatchExceptions(false);
$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
$output->write('foo.');
});
$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo'));
}
protected function tearDown()
{
putenv('SHELL_VERBOSITY');

View File

@ -52,7 +52,7 @@ abstract class AbstractRecursivePass implements CompilerPassInterface
*/
protected function processValue($value, $isRoot = false)
{
if (is_array($value)) {
if (\is_array($value)) {
foreach ($value as $k => $v) {
if ($isRoot) {
$this->currentId = $k;

View File

@ -101,11 +101,11 @@ class HeaderBag implements \IteratorAggregate, \Countable
/**
* Returns a header value by name.
*
* @param string $key The header name
* @param mixed $default The default value
* @param bool $first Whether to return the first value or all header values
* @param string $key The header name
* @param string|string[] $default The default value
* @param bool $first Whether to return the first value or all header values
*
* @return string|array The first header value if $first is true, an array of values otherwise
* @return string|string[] The first header value or default value if $first is true, an array of values otherwise
*/
public function get($key, $default = null, $first = true)
{
@ -130,9 +130,9 @@ class HeaderBag implements \IteratorAggregate, \Countable
/**
* Sets a header by name.
*
* @param string $key The key
* @param string|array $values The value or an array of values
* @param bool $replace Whether to replace the actual value or not (true by default)
* @param string $key The key
* @param string|string[] $values The value or an array of values
* @param bool $replace Whether to replace the actual value or not (true by default)
*/
public function set($key, $values, $replace = true)
{

View File

@ -296,13 +296,13 @@ class Request
* The information contained in the URI always take precedence
* over the other information (server and parameters).
*
* @param string $uri The URI
* @param string $method The HTTP method
* @param array $parameters The query (GET) or request (POST) parameters
* @param array $cookies The request cookies ($_COOKIE)
* @param array $files The request files ($_FILES)
* @param array $server The server parameters ($_SERVER)
* @param string $content The raw body data
* @param string $uri The URI
* @param string $method The HTTP method
* @param array $parameters The query (GET) or request (POST) parameters
* @param array $cookies The request cookies ($_COOKIE)
* @param array $files The request files ($_FILES)
* @param array $server The server parameters ($_SERVER)
* @param string|resource $content The raw body data
*
* @return static
*/

View File

@ -291,7 +291,9 @@ class Process implements \IteratorAggregate
$envPairs = array();
foreach ($env as $k => $v) {
$envPairs[] = $k.'='.$v;
if (false !== $v) {
$envPairs[] = $k.'='.$v;
}
}
if (!is_dir($this->cwd)) {

View File

@ -214,6 +214,16 @@ abstract class Constraint
throw new InvalidOptionsException(sprintf('The option "%s" does not exist in constraint %s', $option, get_class($this)), array($option));
}
/**
* @param string $option The option name
*
* @return bool
*/
public function __isset($option)
{
return 'groups' === $option;
}
/**
* Adds the given group if this constraint is in the Default group.
*

View File

@ -26,6 +26,16 @@ class FileTest extends TestCase
$this->assertSame($bytes, $file->maxSize);
$this->assertSame($binaryFormat, $file->binaryFormat);
$this->assertTrue($file->__isset('maxSize'));
}
public function testMagicIsset()
{
$file = new File(array('maxSize' => 1));
$this->assertTrue($file->__isset('maxSize'));
$this->assertTrue($file->__isset('groups'));
$this->assertFalse($file->__isset('toto'));
}
/**

View File

@ -62,7 +62,7 @@ class Dumper
$dumpAsMap = Inline::isHash($input);
foreach ($input as $key => $value) {
if ($inline >= 1 && Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && is_string($value) && false !== strpos($value, "\n")) {
if ($inline >= 1 && Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && is_string($value) && false !== strpos($value, "\n") && false === strpos($value, "\r\n")) {
$output .= sprintf("%s%s%s |\n", $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', '');
foreach (preg_split('/\n|\r\n/', $value) as $row) {

View File

@ -286,6 +286,7 @@ class Inline
} elseif (Parser::preg_match('/^(.*?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) {
$output = $match[1];
$i += strlen($output);
$output = trim($output);
} else {
throw new ParseException(sprintf('Malformed inline YAML string: %s.', $scalar), self::$parsedLineNumber + 1, null, self::$parsedFilename);
}

View File

@ -377,7 +377,8 @@ YAML;
$data = array(
'data' => array(
'single_line' => 'foo bar baz',
'multi_line' => "foo\nline with trailing spaces:\n \nbar\r\ninteger like line:\n123456789\nempty line:\n\nbaz",
'multi_line' => "foo\nline with trailing spaces:\n \nbar\ninteger like line:\n123456789\nempty line:\n\nbaz",
'multi_line_with_carriage_return' => "foo\nbar\r\nbaz",
'nested_inlined_multi_line_string' => array(
'inlined_multi_line' => "foo\nbar\r\nempty line:\n\nbaz",
),
@ -387,6 +388,11 @@ YAML;
$this->assertSame(file_get_contents(__DIR__.'/Fixtures/multiple_lines_as_literal_block.yml'), $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK));
}
public function testCarriageReturnIsMaintainedWhenDumpingAsMultiLineLiteralBlock()
{
$this->assertSame("- \"a\\r\\nb\\nc\"\n", $this->dumper->dump(array("a\r\nb\nc"), 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK));
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage The indentation must be greater than zero

View File

@ -10,4 +10,5 @@ data:
empty line:
baz
multi_line_with_carriage_return: "foo\nbar\r\nbaz"
nested_inlined_multi_line_string: { inlined_multi_line: "foo\nbar\r\nempty line:\n\nbaz" }

View File

@ -252,9 +252,9 @@ class InlineTest extends TestCase
{
if (method_exists($this, 'expectExceptionMessage')) {
$this->expectException(ParseException::class);
$this->expectExceptionMessage(sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo ").', $indicator));
$this->expectExceptionMessage(sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo").', $indicator));
} else {
$this->setExpectedException(ParseException::class, sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo ").', $indicator));
$this->setExpectedException(ParseException::class, sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo").', $indicator));
}
Inline::parse(sprintf('{ foo: %sfoo }', $indicator));
@ -272,9 +272,9 @@ class InlineTest extends TestCase
{
if (method_exists($this, 'expectExceptionMessage')) {
$this->expectException(ParseException::class);
$this->expectExceptionMessage(sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo ").', $indicator));
$this->expectExceptionMessage(sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo").', $indicator));
} else {
$this->setExpectedException(ParseException::class, sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo ").', $indicator));
$this->setExpectedException(ParseException::class, sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo").', $indicator));
}
Inline::parse(sprintf('{ foo: %sfoo }', $indicator));

View File

@ -1602,6 +1602,10 @@ YAML
- !quz {foo: bar, quz: !bar {one: bar}}
YAML
),
'spaces-around-tag-value-in-sequence' => array(
array(new TaggedValue('foo', 'bar')),
'[ !foo bar ]',
),
);
}