Merge branch '2.8' into 3.3
* 2.8: [VarDumper] Enhance docblock to tell about AbstractDumper::dumpLine(-1) [Debug] Remove false-positive check in DebugClassLoader [Validator] Fix use of GroupSequenceProvider in child classes Change number PHPDoc type to int|float [VarDumper] Strengthen dumped JS [travis] Add timing info [Validator] Fix Greek translation [Console] Initialize lazily to render exceptions properly [Validator] Add a property tag for File::$maxSize
This commit is contained in:
commit
726c567d14
33
.travis.yml
33
.travis.yml
|
@ -56,15 +56,38 @@ before_install:
|
|||
export PHPUNIT_X="$PHPUNIT --exclude-group tty,benchmark,intl-data"
|
||||
export COMPOSER_UP='composer update --no-progress --no-suggest --ansi'
|
||||
|
||||
nanoseconds() {
|
||||
local cmd="date"
|
||||
local format="+%s%N"
|
||||
local os=$(uname)
|
||||
if hash gdate > /dev/null 2>&1; then
|
||||
cmd="gdate"
|
||||
elif [[ "$os" = Darwin ]]; then
|
||||
format="+%s000000000"
|
||||
fi
|
||||
$cmd -u $format
|
||||
}
|
||||
export -f nanoseconds
|
||||
|
||||
# tfold is a helper to create folded reports
|
||||
tfold () {
|
||||
title=$1
|
||||
fold=$(echo $title | sed -r 's/[^-_A-Za-z\d]+/./g')
|
||||
local title=$1
|
||||
local fold=$(echo $title | sed -r 's/[^-_A-Za-z0-9]+/./g')
|
||||
shift
|
||||
echo -e "travis_fold:start:$fold\\n\\e[1;34m$title\\e[0m"
|
||||
bash -xc "$*" 2>&1 &&
|
||||
local id=$(printf %08x $(( RANDOM * RANDOM )))
|
||||
local start=$(nanoseconds)
|
||||
echo -e "travis_fold:start:$fold"
|
||||
echo -e "travis_time:start:$id"
|
||||
echo -e "\\e[1;34m$title\\e[0m"
|
||||
|
||||
bash -xc "$*" 2>&1
|
||||
local ok=$?
|
||||
local end=$(nanoseconds)
|
||||
echo -e "\\ntravis_time:end:$id:start=$start,finish=$end,duration=$(($end-$start))"
|
||||
(exit $ok) &&
|
||||
echo -e "\\e[32mOK\\e[0m $title\\n\\ntravis_fold:end:$fold" ||
|
||||
( echo -e "\\e[41mKO\\e[0m $title\\n" && exit 1 )
|
||||
echo -e "\\e[41mKO\\e[0m $title\\n"
|
||||
(exit $ok)
|
||||
}
|
||||
export -f tfold
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ class Application
|
|||
private $terminal;
|
||||
private $defaultCommand;
|
||||
private $singleCommand;
|
||||
private $initialized;
|
||||
|
||||
/**
|
||||
* @param string $name The name of the application
|
||||
|
@ -83,12 +84,6 @@ class Application
|
|||
$this->version = $version;
|
||||
$this->terminal = new Terminal();
|
||||
$this->defaultCommand = 'list';
|
||||
$this->helperSet = $this->getDefaultHelperSet();
|
||||
$this->definition = $this->getDefaultInputDefinition();
|
||||
|
||||
foreach ($this->getDefaultCommands() as $command) {
|
||||
$this->add($command);
|
||||
}
|
||||
}
|
||||
|
||||
public function setDispatcher(EventDispatcherInterface $dispatcher)
|
||||
|
@ -195,10 +190,11 @@ class Application
|
|||
|
||||
if (!$name) {
|
||||
$name = $this->defaultCommand;
|
||||
$this->definition->setArguments(array_merge(
|
||||
$this->definition->getArguments(),
|
||||
$definition = $this->getDefinition();
|
||||
$definition->setArguments(array_merge(
|
||||
$definition->getArguments(),
|
||||
array(
|
||||
'command' => new InputArgument('command', InputArgument::OPTIONAL, $this->definition->getArgument('command')->getDescription(), $name),
|
||||
'command' => new InputArgument('command', InputArgument::OPTIONAL, $definition->getArgument('command')->getDescription(), $name),
|
||||
)
|
||||
));
|
||||
}
|
||||
|
@ -248,6 +244,10 @@ class Application
|
|||
*/
|
||||
public function getHelperSet()
|
||||
{
|
||||
if (!$this->helperSet) {
|
||||
$this->helperSet = $this->getDefaultHelperSet();
|
||||
}
|
||||
|
||||
return $this->helperSet;
|
||||
}
|
||||
|
||||
|
@ -268,6 +268,10 @@ class Application
|
|||
*/
|
||||
public function getDefinition()
|
||||
{
|
||||
if (!$this->definition) {
|
||||
$this->definition = $this->getDefaultInputDefinition();
|
||||
}
|
||||
|
||||
if ($this->singleCommand) {
|
||||
$inputDefinition = $this->definition;
|
||||
$inputDefinition->setArguments();
|
||||
|
@ -424,6 +428,8 @@ class Application
|
|||
*/
|
||||
public function add(Command $command)
|
||||
{
|
||||
$this->init();
|
||||
|
||||
$command->setApplication($this);
|
||||
|
||||
if (!$command->isEnabled()) {
|
||||
|
@ -456,6 +462,8 @@ class Application
|
|||
*/
|
||||
public function get($name)
|
||||
{
|
||||
$this->init();
|
||||
|
||||
if (!isset($this->commands[$name])) {
|
||||
throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $name));
|
||||
}
|
||||
|
@ -483,6 +491,8 @@ class Application
|
|||
*/
|
||||
public function has($name)
|
||||
{
|
||||
$this->init();
|
||||
|
||||
return isset($this->commands[$name]);
|
||||
}
|
||||
|
||||
|
@ -560,6 +570,8 @@ class Application
|
|||
*/
|
||||
public function find($name)
|
||||
{
|
||||
$this->init();
|
||||
|
||||
$allCommands = array_keys($this->commands);
|
||||
$expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name);
|
||||
$commands = preg_grep('{^'.$expr.'}', $allCommands);
|
||||
|
@ -626,6 +638,8 @@ class Application
|
|||
*/
|
||||
public function all($namespace = null)
|
||||
{
|
||||
$this->init();
|
||||
|
||||
if (null === $namespace) {
|
||||
return $this->commands;
|
||||
}
|
||||
|
@ -1139,4 +1153,16 @@ class Application
|
|||
|
||||
return $namespaces;
|
||||
}
|
||||
|
||||
private function init()
|
||||
{
|
||||
if ($this->initialized) {
|
||||
return;
|
||||
}
|
||||
$this->initialized = true;
|
||||
|
||||
foreach ($this->getDefaultCommands() as $command) {
|
||||
$this->add($command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ class DebugClassLoader
|
|||
{
|
||||
private $classLoader;
|
||||
private $isFinder;
|
||||
private $loaded = array();
|
||||
private static $caseCheck;
|
||||
private static $final = array();
|
||||
private static $finalMethods = array();
|
||||
|
@ -139,9 +140,10 @@ class DebugClassLoader
|
|||
ErrorHandler::stackErrors();
|
||||
|
||||
try {
|
||||
if ($this->isFinder) {
|
||||
if ($this->isFinder && !isset($this->loaded[$class])) {
|
||||
$this->loaded[$class] = true;
|
||||
if ($file = $this->classLoader[0]->findFile($class)) {
|
||||
require_once $file;
|
||||
require $file;
|
||||
}
|
||||
} else {
|
||||
call_user_func($this->classLoader, $class);
|
||||
|
|
|
@ -59,6 +59,23 @@ class DebugClassLoaderTest extends TestCase
|
|||
$this->fail('DebugClassLoader did not register');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Exception
|
||||
* @expectedExceptionMessage boo
|
||||
*/
|
||||
public function testThrowingClass()
|
||||
{
|
||||
try {
|
||||
class_exists(__NAMESPACE__.'\Fixtures\Throwing');
|
||||
$this->fail('Exception expected');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertSame('boo', $e->getMessage());
|
||||
}
|
||||
|
||||
// the second call also should throw
|
||||
class_exists(__NAMESPACE__.'\Fixtures\Throwing');
|
||||
}
|
||||
|
||||
public function testUnsilencing()
|
||||
{
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
|
@ -124,6 +141,7 @@ class DebugClassLoaderTest extends TestCase
|
|||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
* @expectedExceptionMessage Case mismatch between loaded and declared class names
|
||||
*/
|
||||
public function testNameCaseMismatch()
|
||||
{
|
||||
|
@ -145,6 +163,7 @@ class DebugClassLoaderTest extends TestCase
|
|||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
* @expectedExceptionMessage Case mismatch between loaded and declared class names
|
||||
*/
|
||||
public function testPsr4CaseMismatch()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
throw new \Exception('boo');
|
|
@ -357,9 +357,9 @@ class NumberFormatter
|
|||
/**
|
||||
* Format a number.
|
||||
*
|
||||
* @param number $value The value to format
|
||||
* @param int $type Type of the formatting, one of the format type constants
|
||||
* Only type NumberFormatter::TYPE_DEFAULT is currently supported.
|
||||
* @param int|float $value The value to format
|
||||
* @param int $type Type of the formatting, one of the format type constants
|
||||
* Only type NumberFormatter::TYPE_DEFAULT is currently supported.
|
||||
*
|
||||
* @return bool|string The formatted value or false on error
|
||||
*
|
||||
|
|
|
@ -18,6 +18,8 @@ use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
|||
* @Annotation
|
||||
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
|
||||
*
|
||||
* @property int $maxSize
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class File extends Constraint
|
||||
|
|
|
@ -339,6 +339,10 @@ class ClassMetadata extends GenericMetadata implements ClassMetadataInterface
|
|||
*/
|
||||
public function mergeConstraints(ClassMetadata $source)
|
||||
{
|
||||
if ($source->isGroupSequenceProvider()) {
|
||||
$this->setGroupSequenceProvider(true);
|
||||
}
|
||||
|
||||
foreach ($source->getConstraints() as $constraint) {
|
||||
$this->addConstraint(clone $constraint);
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@
|
|||
</trans-unit>
|
||||
<trans-unit id="25">
|
||||
<source>This value is not valid.</source>
|
||||
<target>Αυτή η τιμή δεν είναι έκγυρη.</target>
|
||||
<target>Αυτή η τιμή δεν είναι έγκυρη.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="26">
|
||||
<source>This value is not a valid time.</source>
|
||||
|
@ -136,11 +136,11 @@
|
|||
</trans-unit>
|
||||
<trans-unit id="37">
|
||||
<source>This is not a valid IP address.</source>
|
||||
<target>Αυτό δεν είναι μια έκγυρη διεύθυνση IP.</target>
|
||||
<target>Αυτό δεν είναι μια έγκυρη διεύθυνση IP.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="38">
|
||||
<source>This value is not a valid language.</source>
|
||||
<target>Αυτή η τιμή δεν αντιστοιχεί σε μια έκγυρη γλώσσα.</target>
|
||||
<target>Αυτή η τιμή δεν αντιστοιχεί σε μια έγκυρη γλώσσα.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="39">
|
||||
<source>This value is not a valid locale.</source>
|
||||
|
@ -148,7 +148,7 @@
|
|||
</trans-unit>
|
||||
<trans-unit id="40">
|
||||
<source>This value is not a valid country.</source>
|
||||
<target>Αυτή η τιμή δεν αντιστοιχεί σε μια έκγυρη χώρα.</target>
|
||||
<target>Αυτή η τιμή δεν αντιστοιχεί σε μια έγκυρη χώρα.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="41">
|
||||
<source>This value is already used.</source>
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Validator\Tests\Fixtures;
|
||||
|
||||
class GroupSequenceProviderChildEntity extends GroupSequenceProviderEntity
|
||||
{
|
||||
}
|
|
@ -24,6 +24,7 @@ class ClassMetadataTest extends TestCase
|
|||
const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity';
|
||||
const PARENTCLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParent';
|
||||
const PROVIDERCLASS = 'Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity';
|
||||
const PROVIDERCHILDCLASS = 'Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderChildEntity';
|
||||
|
||||
protected $metadata;
|
||||
|
||||
|
@ -301,6 +302,17 @@ class ClassMetadataTest extends TestCase
|
|||
$this->assertTrue($metadata->isGroupSequenceProvider());
|
||||
}
|
||||
|
||||
public function testMergeConstraintsMergesGroupSequenceProvider()
|
||||
{
|
||||
$parent = new ClassMetadata(self::PROVIDERCLASS);
|
||||
$parent->setGroupSequenceProvider(true);
|
||||
|
||||
$metadata = new ClassMetadata(self::PROVIDERCHILDCLASS);
|
||||
$metadata->mergeConstraints($parent);
|
||||
|
||||
$this->assertTrue($metadata->isGroupSequenceProvider());
|
||||
}
|
||||
|
||||
/**
|
||||
* https://github.com/symfony/symfony/issues/11604.
|
||||
*/
|
||||
|
@ -309,13 +321,3 @@ class ClassMetadataTest extends TestCase
|
|||
$this->assertCount(0, $this->metadata->getPropertyMetadata('foo'), '->getPropertyMetadata() returns an empty collection if no metadata is configured for the given property');
|
||||
}
|
||||
}
|
||||
|
||||
class ParentClass
|
||||
{
|
||||
public $example = 0;
|
||||
}
|
||||
|
||||
class ChildClass extends ParentClass
|
||||
{
|
||||
public $example = 1; // overrides parent property of same name
|
||||
}
|
||||
|
|
|
@ -159,7 +159,8 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
|
|||
/**
|
||||
* Dumps the current line.
|
||||
*
|
||||
* @param int $depth The recursive depth in the dumped structure for the line being dumped
|
||||
* @param int $depth The recursive depth in the dumped structure for the line being dumped,
|
||||
* or -1 to signal the end-of-dump to the line dumper callable
|
||||
*/
|
||||
protected function dumpLine($depth)
|
||||
{
|
||||
|
|
|
@ -155,10 +155,10 @@ if (!doc.addEventListener) {
|
|||
function toggle(a, recursive) {
|
||||
var s = a.nextSibling || {}, oldClass = s.className, arrow, newClass;
|
||||
|
||||
if ('sf-dump-compact' == oldClass) {
|
||||
if (/\bsf-dump-compact\b/.test(oldClass)) {
|
||||
arrow = '▼';
|
||||
newClass = 'sf-dump-expanded';
|
||||
} else if ('sf-dump-expanded' == oldClass) {
|
||||
} else if (/\bsf-dump-expanded\b/.test(oldClass)) {
|
||||
arrow = '▶';
|
||||
newClass = 'sf-dump-compact';
|
||||
} else {
|
||||
|
@ -166,13 +166,13 @@ function toggle(a, recursive) {
|
|||
}
|
||||
|
||||
a.lastChild.innerHTML = arrow;
|
||||
s.className = newClass;
|
||||
s.className = s.className.replace(/\bsf-dump-(compact|expanded)\b/, newClass);
|
||||
|
||||
if (recursive) {
|
||||
try {
|
||||
a = s.querySelectorAll('.'+oldClass);
|
||||
for (s = 0; s < a.length; ++s) {
|
||||
if (a[s].className !== newClass) {
|
||||
if (-1 == a[s].className.indexOf(newClass)) {
|
||||
a[s].className = newClass;
|
||||
a[s].previousSibling.lastChild.innerHTML = arrow;
|
||||
}
|
||||
|
@ -334,7 +334,7 @@ return function (root, x) {
|
|||
if (f && t && f[0] !== t[0]) {
|
||||
r.innerHTML = r.innerHTML.replace(new RegExp('^'+f[0].replace(rxEsc, '\\$1'), 'mg'), t[0]);
|
||||
}
|
||||
if ('sf-dump-compact' == r.className) {
|
||||
if (/\bsf-dump-compact\b/.test(r.className)) {
|
||||
toggle(s, isCtrlKey(e));
|
||||
}
|
||||
}
|
||||
|
@ -378,6 +378,7 @@ return function (root, x) {
|
|||
a.title = (a.title ? a.title+'\n[' : '[')+keyHint+'+click] Expand all children';
|
||||
a.innerHTML += '<span>▼</span>';
|
||||
a.className += ' sf-dump-toggle';
|
||||
|
||||
x = 1;
|
||||
if ('sf-dump' != elt.parentNode.className) {
|
||||
x += elt.parentNode.getAttribute('data-depth')/1;
|
||||
|
@ -386,7 +387,7 @@ return function (root, x) {
|
|||
if (x > options.maxDepth) {
|
||||
toggle(a);
|
||||
}
|
||||
} else if ('sf-dump-ref' == elt.className && (a = elt.getAttribute('href'))) {
|
||||
} else if (/\bsf-dump-ref\b/.test(elt.className) && (a = elt.getAttribute('href'))) {
|
||||
a = a.substr(1);
|
||||
elt.className += ' '+a;
|
||||
|
||||
|
|
Reference in New Issue