Merge branch '3.4'

* 3.4:
  Made some SecurityBundle tests case-insensitive to prepare for future Symfony versions
  [Console] Added a case-insensitive fallback for console command names
  fix merge
  [DI] Fix dumping abstract with YamlDumper
  restrict reflection doc block
  [DI] Fix YamlDumper not dumping abstract and autoconfigure
This commit is contained in:
Nicolas Grekas 2017-08-15 10:24:11 +02:00
commit 501c1b5d0e
14 changed files with 173 additions and 32 deletions

View File

@ -98,7 +98,7 @@
"phpdocumentor/reflection-docblock": "^3.0" "phpdocumentor/reflection-docblock": "^3.0"
}, },
"conflict": { "conflict": {
"phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.1", "phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.2",
"phpdocumentor/type-resolver": "<0.2.0", "phpdocumentor/type-resolver": "<0.2.0",
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0"
}, },

View File

@ -81,6 +81,11 @@ abstract class CompleteConfigurationTest extends TestCase
$configs[] = array_values($configDef->getArguments()); $configs[] = array_values($configDef->getArguments());
} }
// the IDs of the services are case sensitive or insensitive depending on
// the Symfony version. Transform them to lowercase to simplify tests.
$configs[0][2] = strtolower($configs[0][2]);
$configs[2][2] = strtolower($configs[2][2]);
$this->assertEquals(array( $this->assertEquals(array(
array( array(
'simple', 'simple',

View File

@ -570,7 +570,12 @@ class Application
$expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name); $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name);
$commands = preg_grep('{^'.$expr.'}', $allCommands); $commands = preg_grep('{^'.$expr.'}', $allCommands);
if (empty($commands) || count(preg_grep('{^'.$expr.'$}', $commands)) < 1) { if (empty($commands)) {
$commands = preg_grep('{^'.$expr.'}i', $allCommands);
}
// if no commands matched or we just matched namespaces
if (empty($commands) || count(preg_grep('{^'.$expr.'$}i', $commands)) < 1) {
if (false !== $pos = strrpos($name, ':')) { if (false !== $pos = strrpos($name, ':')) {
// check if a namespace exists and contains commands // check if a namespace exists and contains commands
$this->findNamespace(substr($name, 0, $pos)); $this->findNamespace(substr($name, 0, $pos));

View File

@ -16,6 +16,7 @@ CHANGELOG
* added `CommandLoaderInterface`, `FactoryCommandLoader` and PSR-11 * added `CommandLoaderInterface`, `FactoryCommandLoader` and PSR-11
`ContainerCommandLoader` for commands lazy-loading `ContainerCommandLoader` for commands lazy-loading
* added a case-insensitive command name matching fallback
3.3.0 3.3.0
----- -----

View File

@ -50,6 +50,8 @@ class ApplicationTest extends TestCase
require_once self::$fixturesPath.'/Foo3Command.php'; require_once self::$fixturesPath.'/Foo3Command.php';
require_once self::$fixturesPath.'/Foo4Command.php'; require_once self::$fixturesPath.'/Foo4Command.php';
require_once self::$fixturesPath.'/Foo5Command.php'; require_once self::$fixturesPath.'/Foo5Command.php';
require_once self::$fixturesPath.'/FooSameCaseUppercaseCommand.php';
require_once self::$fixturesPath.'/FooSameCaseLowercaseCommand.php';
require_once self::$fixturesPath.'/FoobarCommand.php'; require_once self::$fixturesPath.'/FoobarCommand.php';
require_once self::$fixturesPath.'/BarBucCommand.php'; require_once self::$fixturesPath.'/BarBucCommand.php';
require_once self::$fixturesPath.'/FooSubnamespaced1Command.php'; require_once self::$fixturesPath.'/FooSubnamespaced1Command.php';
@ -316,6 +318,41 @@ class ApplicationTest extends TestCase
$this->assertInstanceOf('FooCommand', $application->find('a'), '->find() returns a command if the abbreviation exists for an alias'); $this->assertInstanceOf('FooCommand', $application->find('a'), '->find() returns a command if the abbreviation exists for an alias');
} }
public function testFindCaseSensitiveFirst()
{
$application = new Application();
$application->add(new \FooSameCaseUppercaseCommand());
$application->add(new \FooSameCaseLowercaseCommand());
$this->assertInstanceOf('FooSameCaseUppercaseCommand', $application->find('f:B'), '->find() returns a command if the abbreviation is the correct case');
$this->assertInstanceOf('FooSameCaseUppercaseCommand', $application->find('f:BAR'), '->find() returns a command if the abbreviation is the correct case');
$this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('f:b'), '->find() returns a command if the abbreviation is the correct case');
$this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('f:bar'), '->find() returns a command if the abbreviation is the correct case');
}
public function testFindCaseInsensitiveAsFallback()
{
$application = new Application();
$application->add(new \FooSameCaseLowercaseCommand());
$this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('f:b'), '->find() returns a command if the abbreviation is the correct case');
$this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('f:B'), '->find() will fallback to case insensitivity');
$this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('FoO:BaR'), '->find() will fallback to case insensitivity');
}
/**
* @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException
* @expectedExceptionMessage Command "FoO:BaR" is ambiguous
*/
public function testFindCaseInsensitiveSuggestions()
{
$application = new Application();
$application->add(new \FooSameCaseLowercaseCommand());
$application->add(new \FooSameCaseUppercaseCommand());
$this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('FoO:BaR'), '->find() will find two suggestions with case insensitivity');
}
public function testFindWithCommandLoader() public function testFindWithCommandLoader()
{ {
$application = new Application(); $application = new Application();
@ -413,8 +450,8 @@ class ApplicationTest extends TestCase
public function provideInvalidCommandNamesSingle() public function provideInvalidCommandNamesSingle()
{ {
return array( return array(
array('foo3:baR'), array('foo3:barr'),
array('foO3:bar'), array('fooo3:bar'),
); );
} }

View File

@ -0,0 +1,11 @@
<?php
use Symfony\Component\Console\Command\Command;
class FooSameCaseLowercaseCommand extends Command
{
protected function configure()
{
$this->setName('foo:bar')->setDescription('foo:bar command');
}
}

View File

@ -0,0 +1,11 @@
<?php
use Symfony\Component\Console\Command\Command;
class FooSameCaseUppercaseCommand extends Command
{
protected function configure()
{
$this->setName('foo:BAR')->setDescription('foo:BAR command');
}
}

View File

@ -110,6 +110,14 @@ class YamlDumper extends Dumper
$code .= " autowire: true\n"; $code .= " autowire: true\n";
} }
if ($definition->isAutoconfigured()) {
$code .= " autoconfigure: true\n";
}
if ($definition->isAbstract()) {
$code .= " abstract: true\n";
}
if ($definition->isLazy()) { if ($definition->isLazy()) {
$code .= " lazy: true\n"; $code .= " lazy: true\n";
} }

View File

@ -12,9 +12,11 @@
namespace Symfony\Component\DependencyInjection\Tests\Dumper; namespace Symfony\Component\DependencyInjection\Tests\Dumper;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Dumper\YamlDumper; use Symfony\Component\DependencyInjection\Dumper\YamlDumper;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Yaml\Parser; use Symfony\Component\Yaml\Parser;
@ -65,6 +67,16 @@ class YamlDumperTest extends TestCase
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services24.yml', $dumper->dump()); $this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services24.yml', $dumper->dump());
} }
public function testDumpLoad()
{
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('services_dump_load.yml');
$dumper = new YamlDumper($container);
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_dump_load.yml', $dumper->dump());
}
public function testInlineServices() public function testInlineServices()
{ {
$container = new ContainerBuilder(); $container = new ContainerBuilder();

View File

@ -0,0 +1,14 @@
services:
service_container:
class: Symfony\Component\DependencyInjection\ContainerInterface
synthetic: true
foo:
autoconfigure: true
abstract: true
Psr\Container\ContainerInterface:
alias: service_container
public: false
Symfony\Component\DependencyInjection\ContainerInterface:
alias: service_container
public: false

View File

@ -92,6 +92,7 @@ class PhpDocExtractorTest extends TestCase
array('donotexist', null, null, null), array('donotexist', null, null, null),
array('staticGetter', null, null, null), array('staticGetter', null, null, null),
array('staticSetter', null, null, null), array('staticSetter', null, null, null),
array('emptyVar', null, null, null),
); );
} }

View File

@ -41,6 +41,7 @@ class ReflectionExtractorTest extends TestCase
'B', 'B',
'Guid', 'Guid',
'g', 'g',
'emptyVar',
'foo', 'foo',
'foo2', 'foo2',
'foo3', 'foo3',
@ -72,6 +73,7 @@ class ReflectionExtractorTest extends TestCase
'B', 'B',
'Guid', 'Guid',
'g', 'g',
'emptyVar',
'foo', 'foo',
'foo2', 'foo2',
'foo3', 'foo3',
@ -99,6 +101,7 @@ class ReflectionExtractorTest extends TestCase
'B', 'B',
'Guid', 'Guid',
'g', 'g',
'emptyVar',
'foo', 'foo',
'foo2', 'foo2',
'foo3', 'foo3',
@ -170,37 +173,63 @@ class ReflectionExtractorTest extends TestCase
); );
} }
public function testIsReadable() /**
* @dataProvider getReadableProperties
*/
public function testIsReadable($property, $expected)
{ {
$this->assertFalse($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'bar', array())); $this->assertSame(
$this->assertFalse($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'baz', array())); $expected,
$this->assertTrue($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'parent', array())); $this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', $property, array())
$this->assertTrue($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'a', array())); );
$this->assertFalse($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'b', array()));
$this->assertTrue($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'c', array()));
$this->assertTrue($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'd', array()));
$this->assertFalse($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'e', array()));
$this->assertFalse($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'f', array()));
$this->assertTrue($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'Id', array()));
$this->assertTrue($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'id', array()));
$this->assertTrue($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'Guid', array()));
$this->assertFalse($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'guid', array()));
} }
public function testIsWritable() public function getReadableProperties()
{ {
$this->assertFalse($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'bar', array())); return array(
$this->assertFalse($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'baz', array())); array('bar', false),
$this->assertTrue($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'parent', array())); array('baz', false),
$this->assertFalse($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'a', array())); array('parent', true),
$this->assertTrue($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'b', array())); array('a', true),
$this->assertFalse($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'c', array())); array('b', false),
$this->assertFalse($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'd', array())); array('c', true),
$this->assertTrue($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'e', array())); array('d', true),
$this->assertTrue($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'f', array())); array('e', false),
$this->assertFalse($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'Id', array())); array('f', false),
$this->assertTrue($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'Guid', array())); array('Id', true),
$this->assertFalse($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'guid', array())); array('id', true),
array('Guid', true),
array('guid', false),
);
}
/**
* @dataProvider getWritableProperties
*/
public function testIsWritable($property, $expected)
{
$this->assertSame(
$expected,
$this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', $property, array())
);
}
public function getWritableProperties()
{
return array(
array('bar', false),
array('baz', false),
array('parent', true),
array('a', false),
array('b', true),
array('c', false),
array('d', false),
array('e', true),
array('f', true),
array('Id', false),
array('Guid', true),
array('guid', false),
);
} }
public function testSingularize() public function testSingularize()

View File

@ -68,6 +68,13 @@ class Dummy extends ParentDummy
*/ */
public $g; public $g;
/**
* This should not be removed.
*
* @var
*/
public $emptyVar;
public static function getStatic() public static function getStatic()
{ {
} }

View File

@ -34,7 +34,7 @@
"doctrine/annotations": "~1.0" "doctrine/annotations": "~1.0"
}, },
"conflict": { "conflict": {
"phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.1", "phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.2",
"phpdocumentor/type-resolver": "<0.2.0", "phpdocumentor/type-resolver": "<0.2.0",
"symfony/dependency-injection": "<3.4" "symfony/dependency-injection": "<3.4"
}, },