merged branch fabpot/resource-tracking (PR #6501)

This PR was merged into the master branch.

Commits
-------

6cd1fd4 [DependencyInjection] removed hard dependency on the Config component

Discussion
----------

[DependencyInjection] removed hard dependency on the Config component

The Config component is a hard dependency for the loaders (but loaders
themselves are optional); all other classes should not have a hard dep
on Config. The introduction of a new flag allows to remove this
dependency.

This commit also fixes skipped test dependencies.

---------------------------------------------------------------------------

by fabpot at 2012-12-28T09:47:13Z

As there is only one location where we are directly using a class from the Config component (`ContainerBuilder::addObjectResource()`), we can also just test this case and do nothing if the class does not exist instead of adding a flag, but that looks dirty.

```php
public function addObjectResource($object)
{
    if (!class_exists('Symfony\Component\Config\Resource\FileResource')) {
        return $this;
    }

    $parent = new \ReflectionObject($object);
    do {
        $this->addResource(new FileResource($parent->getFileName()));
    } while ($parent = $parent->getParentClass());

    return $this;
}
```

What do you think?
This commit is contained in:
Fabien Potencier 2012-12-28 23:54:18 +01:00
commit 16702fcd24
10 changed files with 83 additions and 77 deletions

View File

@ -43,6 +43,7 @@ class MergeExtensionConfigurationPass implements CompilerPassInterface
$config = $container->getParameterBag()->resolveValue($config); $config = $container->getParameterBag()->resolveValue($config);
$tmpContainer = new ContainerBuilder($container->getParameterBag()); $tmpContainer = new ContainerBuilder($container->getParameterBag());
$tmpContainer->setResourceTracking($container->isTrackingResources());
$tmpContainer->addObjectResource($extension); $tmpContainer->addObjectResource($extension);
$extension->load($config, $tmpContainer); $extension->load($config, $tmpContainer);

View File

@ -63,6 +63,31 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
*/ */
private $compiler; private $compiler;
private $trackResources = true;
/**
* Sets the track resources flag.
*
* If you are not using the loaders and therefore don't want
* to depend on the Config component, set this flag to false.
*
* @param Boolean $track true if you want to track resources, false otherwise
*/
public function setResourceTracking($track)
{
$this->trackResources = (Boolean) $track;
}
/**
* Checks if resources are tracked.
*
* @return Boolean true if resources are tracked, false otherwise
*/
public function isTrackingResources()
{
return $this->trackResources;
}
/** /**
* Registers an extension. * Registers an extension.
* *
@ -152,6 +177,10 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
*/ */
public function addResource(ResourceInterface $resource) public function addResource(ResourceInterface $resource)
{ {
if (!$this->trackResources) {
return $this;
}
$this->resources[] = $resource; $this->resources[] = $resource;
return $this; return $this;
@ -168,6 +197,10 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
*/ */
public function setResources(array $resources) public function setResources(array $resources)
{ {
if (!$this->trackResources) {
return $this;
}
$this->resources = $resources; $this->resources = $resources;
return $this; return $this;
@ -184,6 +217,10 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
*/ */
public function addObjectResource($object) public function addObjectResource($object)
{ {
if (!$this->trackResources) {
return $this;
}
$parent = new \ReflectionObject($object); $parent = new \ReflectionObject($object);
do { do {
$this->addResource(new FileResource($parent->getFileName())); $this->addResource(new FileResource($parent->getFileName()));
@ -437,8 +474,10 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
$this->addAliases($container->getAliases()); $this->addAliases($container->getAliases());
$this->getParameterBag()->add($container->getParameterBag()->all()); $this->getParameterBag()->add($container->getParameterBag()->all());
foreach ($container->getResources() as $resource) { if ($this->trackResources) {
$this->addResource($resource); foreach ($container->getResources() as $resource) {
$this->addResource($resource);
}
} }
foreach ($this->extensions as $name => $extension) { foreach ($this->extensions as $name => $extension) {
@ -505,8 +544,10 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
$this->compiler = new Compiler(); $this->compiler = new Compiler();
} }
foreach ($this->compiler->getPassConfig()->getPasses() as $pass) { if ($this->trackResources) {
$this->addObjectResource($pass); foreach ($this->compiler->getPassConfig()->getPasses() as $pass) {
$this->addObjectResource($pass);
}
} }
$this->compiler->compile($this); $this->compiler->compile($this);

View File

@ -20,13 +20,6 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
*/ */
class IntegrationTest extends \PHPUnit_Framework_TestCase class IntegrationTest extends \PHPUnit_Framework_TestCase
{ {
protected function setUp()
{
if (!class_exists('Symfony\Component\Config\Resource\FileResource')) {
$this->markTestSkipped('The "Config" component is not available');
}
}
/** /**
* This tests that the following dependencies are correctly processed: * This tests that the following dependencies are correctly processed:
* *
@ -37,6 +30,7 @@ class IntegrationTest extends \PHPUnit_Framework_TestCase
public function testProcessRemovesAndInlinesRecursively() public function testProcessRemovesAndInlinesRecursively()
{ {
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$container->setResourceTracking(false);
$a = $container $a = $container
->register('a', '\stdClass') ->register('a', '\stdClass')
@ -66,6 +60,7 @@ class IntegrationTest extends \PHPUnit_Framework_TestCase
public function testProcessInlinesReferencesToAliases() public function testProcessInlinesReferencesToAliases()
{ {
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$container->setResourceTracking(false);
$a = $container $a = $container
->register('a', '\stdClass') ->register('a', '\stdClass')
@ -91,6 +86,7 @@ class IntegrationTest extends \PHPUnit_Framework_TestCase
public function testProcessInlinesWhenThereAreMultipleReferencesButFromTheSameDefinition() public function testProcessInlinesWhenThereAreMultipleReferencesButFromTheSameDefinition()
{ {
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$container->setResourceTracking(false);
$container $container
->register('a', '\stdClass') ->register('a', '\stdClass')

View File

@ -210,11 +210,8 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
*/ */
public function testAddGetCompilerPass() public function testAddGetCompilerPass()
{ {
if (!class_exists('Symfony\Component\Config\Resource\FileResource')) {
$this->markTestSkipped('The "Config" component is not available');
}
$builder = new ContainerBuilder(); $builder = new ContainerBuilder();
$builder->setResourceTracking(false);
$builderCompilerPasses = $builder->getCompiler()->getPassConfig()->getPasses(); $builderCompilerPasses = $builder->getCompiler()->getPassConfig()->getPasses();
$builder->addCompilerPass($this->getMock('Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface')); $builder->addCompilerPass($this->getMock('Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface'));
$this->assertEquals(sizeof($builderCompilerPasses) + 1, sizeof($builder->getCompiler()->getPassConfig()->getPasses())); $this->assertEquals(sizeof($builderCompilerPasses) + 1, sizeof($builder->getCompiler()->getPassConfig()->getPasses()));
@ -335,16 +332,14 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
*/ */
public function testMerge() public function testMerge()
{ {
if (!class_exists('Symfony\Component\Config\Resource\FileResource')) {
$this->markTestSkipped('The "Config" component is not available');
}
$container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo'))); $container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo')));
$container->setResourceTracking(false);
$config = new ContainerBuilder(new ParameterBag(array('foo' => 'bar'))); $config = new ContainerBuilder(new ParameterBag(array('foo' => 'bar')));
$container->merge($config); $container->merge($config);
$this->assertEquals(array('bar' => 'foo', 'foo' => 'bar'), $container->getParameterBag()->all(), '->merge() merges current parameters with the loaded ones'); $this->assertEquals(array('bar' => 'foo', 'foo' => 'bar'), $container->getParameterBag()->all(), '->merge() merges current parameters with the loaded ones');
$container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo'))); $container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo')));
$container->setResourceTracking(false);
$config = new ContainerBuilder(new ParameterBag(array('foo' => '%bar%'))); $config = new ContainerBuilder(new ParameterBag(array('foo' => '%bar%')));
$container->merge($config); $container->merge($config);
////// FIXME ////// FIXME
@ -352,6 +347,7 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array('bar' => 'foo', 'foo' => 'foo'), $container->getParameterBag()->all(), '->merge() evaluates the values of the parameters towards already defined ones'); $this->assertEquals(array('bar' => 'foo', 'foo' => 'foo'), $container->getParameterBag()->all(), '->merge() evaluates the values of the parameters towards already defined ones');
$container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo'))); $container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo')));
$container->setResourceTracking(false);
$config = new ContainerBuilder(new ParameterBag(array('foo' => '%bar%', 'baz' => '%foo%'))); $config = new ContainerBuilder(new ParameterBag(array('foo' => '%bar%', 'baz' => '%foo%')));
$container->merge($config); $container->merge($config);
////// FIXME ////// FIXME
@ -359,6 +355,7 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array('bar' => 'foo', 'foo' => 'foo', 'baz' => 'foo'), $container->getParameterBag()->all(), '->merge() evaluates the values of the parameters towards already defined ones'); $this->assertEquals(array('bar' => 'foo', 'foo' => 'foo', 'baz' => 'foo'), $container->getParameterBag()->all(), '->merge() evaluates the values of the parameters towards already defined ones');
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->register('foo', 'FooClass'); $container->register('foo', 'FooClass');
$container->register('bar', 'BarClass'); $container->register('bar', 'BarClass');
$config = new ContainerBuilder(); $config = new ContainerBuilder();
@ -372,6 +369,7 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('foo', (string) $aliases['alias_for_foo']); $this->assertEquals('foo', (string) $aliases['alias_for_foo']);
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->register('foo', 'FooClass'); $container->register('foo', 'FooClass');
$config->setDefinition('foo', new Definition('BazClass')); $config->setDefinition('foo', new Definition('BazClass'));
$container->merge($config); $container->merge($config);
@ -384,11 +382,8 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
*/ */
public function testMergeLogicException() public function testMergeLogicException()
{ {
if (!class_exists('Symfony\Component\Config\Resource\FileResource')) {
$this->markTestSkipped('The "Config" component is not available');
}
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->compile(); $container->compile();
$container->merge(new ContainerBuilder()); $container->merge(new ContainerBuilder());
} }
@ -456,11 +451,8 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
*/ */
public function testExtension() public function testExtension()
{ {
if (!class_exists('Symfony\Component\Config\Resource\FileResource')) {
$this->markTestSkipped('The "Config" component is not available');
}
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->registerExtension($extension = new \ProjectExtension()); $container->registerExtension($extension = new \ProjectExtension());
$this->assertTrue($container->getExtension('project') === $extension, '->registerExtension() registers an extension'); $this->assertTrue($container->getExtension('project') === $extension, '->registerExtension() registers an extension');
@ -471,30 +463,24 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
public function testRegisteredButNotLoadedExtension() public function testRegisteredButNotLoadedExtension()
{ {
if (!class_exists('Symfony\Component\Config\Resource\FileResource')) {
$this->markTestSkipped('The "Config" component is not available');
}
$extension = $this->getMock('Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface'); $extension = $this->getMock('Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface');
$extension->expects($this->once())->method('getAlias')->will($this->returnValue('project')); $extension->expects($this->once())->method('getAlias')->will($this->returnValue('project'));
$extension->expects($this->never())->method('load'); $extension->expects($this->never())->method('load');
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->registerExtension($extension); $container->registerExtension($extension);
$container->compile(); $container->compile();
} }
public function testRegisteredAndLoadedExtension() public function testRegisteredAndLoadedExtension()
{ {
if (!class_exists('Symfony\Component\Config\Resource\FileResource')) {
$this->markTestSkipped('The "Config" component is not available');
}
$extension = $this->getMock('Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface'); $extension = $this->getMock('Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface');
$extension->expects($this->exactly(2))->method('getAlias')->will($this->returnValue('project')); $extension->expects($this->exactly(2))->method('getAlias')->will($this->returnValue('project'));
$extension->expects($this->once())->method('load')->with(array(array('foo' => 'bar'))); $extension->expects($this->once())->method('load')->with(array(array('foo' => 'bar')));
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->registerExtension($extension); $container->registerExtension($extension);
$container->loadFromExtension('project', array('foo' => 'bar')); $container->loadFromExtension('project', array('foo' => 'bar'));
$container->compile(); $container->compile();
@ -502,13 +488,10 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
public function testPrivateServiceUser() public function testPrivateServiceUser()
{ {
if (!class_exists('Symfony\Component\Config\Resource\FileResource')) {
$this->markTestSkipped('The "Config" component is not available');
}
$fooDefinition = new Definition('BarClass'); $fooDefinition = new Definition('BarClass');
$fooUserDefinition = new Definition('BarUserClass', array(new Reference('bar'))); $fooUserDefinition = new Definition('BarUserClass', array(new Reference('bar')));
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$container->setResourceTracking(false);
$fooDefinition->setPublic(false); $fooDefinition->setPublic(false);
@ -526,11 +509,8 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
*/ */
public function testThrowsExceptionWhenSetServiceOnAFrozenContainer() public function testThrowsExceptionWhenSetServiceOnAFrozenContainer()
{ {
if (!class_exists('Symfony\Component\Config\Resource\FileResource')) {
$this->markTestSkipped('The "Config" component is not available');
}
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->setDefinition('a', new Definition('stdClass')); $container->setDefinition('a', new Definition('stdClass'));
$container->compile(); $container->compile();
$container->set('a', new \stdClass()); $container->set('a', new \stdClass());
@ -570,11 +550,8 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
*/ */
public function testThrowsExceptionWhenSetDefinitionOnAFrozenContainer() public function testThrowsExceptionWhenSetDefinitionOnAFrozenContainer()
{ {
if (!class_exists('Symfony\Component\Config\Resource\FileResource')) {
$this->markTestSkipped('The "Config" component is not available');
}
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->compile(); $container->compile();
$container->setDefinition('a', new Definition()); $container->setDefinition('a', new Definition());
} }

View File

@ -80,18 +80,24 @@ class CrossCheckTest extends \PHPUnit_Framework_TestCase
public function crossCheckLoadersDumpers() public function crossCheckLoadersDumpers()
{ {
return array( $tests = array(
array('services1.xml', 'xml'), array('services1.xml', 'xml'),
array('services2.xml', 'xml'), array('services2.xml', 'xml'),
array('services6.xml', 'xml'), array('services6.xml', 'xml'),
array('services8.xml', 'xml'), array('services8.xml', 'xml'),
array('services9.xml', 'xml'), array('services9.xml', 'xml'),
array('services1.yml', 'yaml'),
array('services2.yml', 'yaml'),
array('services6.yml', 'yaml'),
array('services8.yml', 'yaml'),
array('services9.yml', 'yaml'),
); );
if (class_exists('Symfony\Component\Yaml\Yaml')) {
$tests = array_merge($tests, array(
array('services1.yml', 'yaml'),
array('services2.yml', 'yaml'),
array('services6.yml', 'yaml'),
array('services8.yml', 'yaml'),
array('services9.yml', 'yaml'),
));
}
return $tests;
} }
} }

View File

@ -18,13 +18,6 @@ class GraphvizDumperTest extends \PHPUnit_Framework_TestCase
{ {
protected static $fixturesPath; protected static $fixturesPath;
protected function setUp()
{
if (!class_exists('Symfony\Component\Config\Loader\Loader')) {
$this->markTestSkipped('The "Config" component is not available');
}
}
public static function setUpBeforeClass() public static function setUpBeforeClass()
{ {
self::$fixturesPath = __DIR__.'/../Fixtures/'; self::$fixturesPath = __DIR__.'/../Fixtures/';

View File

@ -21,13 +21,6 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
{ {
protected static $fixturesPath; protected static $fixturesPath;
protected function setUp()
{
if (!class_exists('Symfony\Component\Config\Loader\Loader')) {
$this->markTestSkipped('The "Config" component is not available');
}
}
public static function setUpBeforeClass() public static function setUpBeforeClass()
{ {
self::$fixturesPath = realpath(__DIR__.'/../Fixtures/'); self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
@ -47,6 +40,7 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
public function testDumpFrozenContainerWithNoParameter() public function testDumpFrozenContainerWithNoParameter()
{ {
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->register('foo', 'stdClass'); $container->register('foo', 'stdClass');
$container->compile(); $container->compile();
@ -76,6 +70,7 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
)); ));
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->setDefinition('test', $definition); $container->setDefinition('test', $definition);
$container->setParameter('empty_value', ''); $container->setParameter('empty_value', '');
$container->setParameter('some_string', '-'); $container->setParameter('some_string', '-');

View File

@ -18,13 +18,6 @@ class XmlDumperTest extends \PHPUnit_Framework_TestCase
{ {
protected static $fixturesPath; protected static $fixturesPath;
protected function setUp()
{
if (!class_exists('Symfony\Component\Config\Loader\Loader')) {
$this->markTestSkipped('The "Config" component is not available');
}
}
public static function setUpBeforeClass() public static function setUpBeforeClass()
{ {
self::$fixturesPath = realpath(__DIR__.'/../Fixtures/'); self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');

View File

@ -20,8 +20,8 @@ class YamlDumperTest extends \PHPUnit_Framework_TestCase
protected function setUp() protected function setUp()
{ {
if (!class_exists('Symfony\Component\Config\Loader\Loader')) { if (!class_exists('Symfony\Component\Yaml\Yaml')) {
$this->markTestSkipped('The "Config" component is not available'); $this->markTestSkipped('The "Yaml" component is not available');
} }
} }

View File

@ -98,6 +98,10 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
public function testLoadImports() public function testLoadImports()
{ {
if (!class_exists('Symfony\Component\Yaml\Yaml')) {
$this->markTestSkipped('The "Yaml" component is not available');
}
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$resolver = new LoaderResolver(array( $resolver = new LoaderResolver(array(
new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')), new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')),