2015-08-24 02:36:41 +01:00
|
|
|
<?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\DependencyInjection\Tests\Compiler;
|
|
|
|
|
|
|
|
use Symfony\Component\DependencyInjection\Compiler\AutowirePass;
|
|
|
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|
|
|
use Symfony\Component\DependencyInjection\Reference;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
|
|
|
*/
|
|
|
|
class AutowirePassTest extends \PHPUnit_Framework_TestCase
|
|
|
|
{
|
|
|
|
public function testProcess()
|
|
|
|
{
|
|
|
|
$container = new ContainerBuilder();
|
|
|
|
|
|
|
|
$container->register('foo', __NAMESPACE__.'\Foo');
|
|
|
|
$barDefinition = $container->register('bar', __NAMESPACE__.'\Bar');
|
|
|
|
$barDefinition->setAutowired(true);
|
|
|
|
|
|
|
|
$pass = new AutowirePass();
|
|
|
|
$pass->process($container);
|
|
|
|
|
|
|
|
$this->assertCount(1, $container->getDefinition('bar')->getArguments());
|
|
|
|
$this->assertEquals('foo', (string) $container->getDefinition('bar')->getArgument(0));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testProcessAutowireParent()
|
|
|
|
{
|
|
|
|
$container = new ContainerBuilder();
|
|
|
|
|
|
|
|
$container->register('b', __NAMESPACE__.'\B');
|
|
|
|
$cDefinition = $container->register('c', __NAMESPACE__.'\C');
|
|
|
|
$cDefinition->setAutowired(true);
|
|
|
|
|
|
|
|
$pass = new AutowirePass();
|
|
|
|
$pass->process($container);
|
|
|
|
|
|
|
|
$this->assertCount(1, $container->getDefinition('c')->getArguments());
|
|
|
|
$this->assertEquals('b', (string) $container->getDefinition('c')->getArgument(0));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testProcessAutowireInterface()
|
|
|
|
{
|
|
|
|
$container = new ContainerBuilder();
|
|
|
|
|
|
|
|
$container->register('f', __NAMESPACE__.'\F');
|
|
|
|
$gDefinition = $container->register('g', __NAMESPACE__.'\G');
|
|
|
|
$gDefinition->setAutowired(true);
|
|
|
|
|
|
|
|
$pass = new AutowirePass();
|
|
|
|
$pass->process($container);
|
|
|
|
|
|
|
|
$this->assertCount(2, $container->getDefinition('g')->getArguments());
|
|
|
|
$this->assertEquals('f', (string) $container->getDefinition('g')->getArgument(0));
|
|
|
|
$this->assertEquals('f', (string) $container->getDefinition('g')->getArgument(1));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testCompleteExistingDefinition()
|
|
|
|
{
|
|
|
|
$container = new ContainerBuilder();
|
|
|
|
|
|
|
|
$container->register('b', __NAMESPACE__.'\B');
|
|
|
|
$container->register('f', __NAMESPACE__.'\F');
|
|
|
|
$hDefinition = $container->register('h', __NAMESPACE__.'\H')->addArgument(new Reference('b'));
|
|
|
|
$hDefinition->setAutowired(true);
|
|
|
|
|
|
|
|
$pass = new AutowirePass();
|
|
|
|
$pass->process($container);
|
|
|
|
|
|
|
|
$this->assertCount(2, $container->getDefinition('h')->getArguments());
|
|
|
|
$this->assertEquals('b', (string) $container->getDefinition('h')->getArgument(0));
|
|
|
|
$this->assertEquals('f', (string) $container->getDefinition('h')->getArgument(1));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testCompleteExistingDefinitionWithNotDefinedArguments()
|
|
|
|
{
|
|
|
|
$container = new ContainerBuilder();
|
|
|
|
|
|
|
|
$container->register('b', __NAMESPACE__.'\B');
|
|
|
|
$container->register('f', __NAMESPACE__.'\F');
|
|
|
|
$hDefinition = $container->register('h', __NAMESPACE__.'\H')->addArgument('')->addArgument('');
|
|
|
|
$hDefinition->setAutowired(true);
|
|
|
|
|
|
|
|
$pass = new AutowirePass();
|
|
|
|
$pass->process($container);
|
|
|
|
|
|
|
|
$this->assertCount(2, $container->getDefinition('h')->getArguments());
|
|
|
|
$this->assertEquals('b', (string) $container->getDefinition('h')->getArgument(0));
|
|
|
|
$this->assertEquals('f', (string) $container->getDefinition('h')->getArgument(1));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
|
|
|
* @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" for the service "a".
|
|
|
|
*/
|
|
|
|
public function testTypeCollision()
|
|
|
|
{
|
|
|
|
$container = new ContainerBuilder();
|
|
|
|
|
|
|
|
$container->register('c1', __NAMESPACE__.'\CollisionA');
|
|
|
|
$container->register('c2', __NAMESPACE__.'\CollisionB');
|
|
|
|
$aDefinition = $container->register('a', __NAMESPACE__.'\CannotBeAutowired');
|
|
|
|
$aDefinition->setAutowired(true);
|
|
|
|
|
|
|
|
$pass = new AutowirePass();
|
|
|
|
$pass->process($container);
|
|
|
|
}
|
|
|
|
|
2015-11-23 22:18:49 +00:00
|
|
|
/**
|
|
|
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
|
|
|
* @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" for the service "a".
|
|
|
|
*/
|
|
|
|
public function testTypeNotGuessable()
|
|
|
|
{
|
|
|
|
$container = new ContainerBuilder();
|
|
|
|
|
|
|
|
$container->register('a1', __NAMESPACE__.'\Foo');
|
|
|
|
$container->register('a2', __NAMESPACE__.'\Foo');
|
|
|
|
$aDefinition = $container->register('a', __NAMESPACE__.'\NotGuessableArgument');
|
|
|
|
$aDefinition->setAutowired(true);
|
|
|
|
|
|
|
|
$pass = new AutowirePass();
|
|
|
|
$pass->process($container);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
|
|
|
* @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\A" for the service "a".
|
|
|
|
*/
|
|
|
|
public function testTypeNotGuessableWithSubclass()
|
|
|
|
{
|
|
|
|
$container = new ContainerBuilder();
|
|
|
|
|
|
|
|
$container->register('a1', __NAMESPACE__.'\B');
|
|
|
|
$container->register('a2', __NAMESPACE__.'\B');
|
|
|
|
$aDefinition = $container->register('a', __NAMESPACE__.'\NotGuessableArgumentForSubclass');
|
|
|
|
$aDefinition->setAutowired(true);
|
|
|
|
|
|
|
|
$pass = new AutowirePass();
|
|
|
|
$pass->process($container);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testTypeNotGuessableWithTypeSet()
|
|
|
|
{
|
|
|
|
$container = new ContainerBuilder();
|
|
|
|
|
|
|
|
$container->register('a1', __NAMESPACE__.'\Foo');
|
|
|
|
$container->register('a2', __NAMESPACE__.'\Foo')->addAutowiringType(__NAMESPACE__.'\Foo');
|
|
|
|
$aDefinition = $container->register('a', __NAMESPACE__.'\NotGuessableArgument');
|
|
|
|
$aDefinition->setAutowired(true);
|
|
|
|
|
|
|
|
$pass = new AutowirePass();
|
|
|
|
$pass->process($container);
|
|
|
|
|
|
|
|
$this->assertCount(1, $container->getDefinition('a')->getArguments());
|
|
|
|
$this->assertEquals('a2', (string) $container->getDefinition('a')->getArgument(0));
|
|
|
|
}
|
|
|
|
|
2015-08-24 02:36:41 +01:00
|
|
|
public function testWithTypeSet()
|
|
|
|
{
|
|
|
|
$container = new ContainerBuilder();
|
|
|
|
|
|
|
|
$container->register('c1', __NAMESPACE__.'\CollisionA');
|
|
|
|
$container->register('c2', __NAMESPACE__.'\CollisionB')->addAutowiringType(__NAMESPACE__.'\CollisionInterface');
|
|
|
|
$aDefinition = $container->register('a', __NAMESPACE__.'\CannotBeAutowired');
|
|
|
|
$aDefinition->setAutowired(true);
|
|
|
|
|
|
|
|
$pass = new AutowirePass();
|
|
|
|
$pass->process($container);
|
|
|
|
|
|
|
|
$this->assertCount(1, $container->getDefinition('a')->getArguments());
|
|
|
|
$this->assertEquals('c2', (string) $container->getDefinition('a')->getArgument(0));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testCreateDefinition()
|
|
|
|
{
|
|
|
|
$container = new ContainerBuilder();
|
|
|
|
|
|
|
|
$coopTilleulsDefinition = $container->register('coop_tilleuls', __NAMESPACE__.'\LesTilleuls');
|
|
|
|
$coopTilleulsDefinition->setAutowired(true);
|
|
|
|
|
|
|
|
$pass = new AutowirePass();
|
|
|
|
$pass->process($container);
|
|
|
|
|
|
|
|
$this->assertCount(1, $container->getDefinition('coop_tilleuls')->getArguments());
|
|
|
|
$this->assertEquals('autowired.symfony\component\dependencyinjection\tests\compiler\dunglas', $container->getDefinition('coop_tilleuls')->getArgument(0));
|
|
|
|
|
|
|
|
$dunglasDefinition = $container->getDefinition('autowired.symfony\component\dependencyinjection\tests\compiler\dunglas');
|
|
|
|
$this->assertEquals(__NAMESPACE__.'\Dunglas', $dunglasDefinition->getClass());
|
|
|
|
$this->assertFalse($dunglasDefinition->isPublic());
|
|
|
|
$this->assertCount(1, $dunglasDefinition->getArguments());
|
|
|
|
$this->assertEquals('autowired.symfony\component\dependencyinjection\tests\compiler\lille', $dunglasDefinition->getArgument(0));
|
|
|
|
|
|
|
|
$lilleDefinition = $container->getDefinition('autowired.symfony\component\dependencyinjection\tests\compiler\lille');
|
|
|
|
$this->assertEquals(__NAMESPACE__.'\Lille', $lilleDefinition->getClass());
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testResolveParameter()
|
|
|
|
{
|
|
|
|
$container = new ContainerBuilder();
|
|
|
|
|
|
|
|
$container->setParameter('class_name', __NAMESPACE__.'\Foo');
|
|
|
|
$container->register('foo', '%class_name%');
|
|
|
|
$barDefinition = $container->register('bar', __NAMESPACE__.'\Bar');
|
|
|
|
$barDefinition->setAutowired(true);
|
|
|
|
|
|
|
|
$pass = new AutowirePass();
|
|
|
|
$pass->process($container);
|
|
|
|
|
|
|
|
$this->assertEquals('foo', $container->getDefinition('bar')->getArgument(0));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testOptionalParameter()
|
|
|
|
{
|
|
|
|
$container = new ContainerBuilder();
|
|
|
|
|
|
|
|
$container->register('a', __NAMESPACE__.'\A');
|
|
|
|
$container->register('foo', __NAMESPACE__.'\Foo');
|
|
|
|
$optDefinition = $container->register('opt', __NAMESPACE__.'\OptionalParameter');
|
|
|
|
$optDefinition->setAutowired(true);
|
|
|
|
|
|
|
|
$pass = new AutowirePass();
|
|
|
|
$pass->process($container);
|
|
|
|
|
|
|
|
$definition = $container->getDefinition('opt');
|
|
|
|
$this->assertNull($definition->getArgument(0));
|
|
|
|
$this->assertEquals('a', $definition->getArgument(1));
|
|
|
|
$this->assertEquals('foo', $definition->getArgument(2));
|
|
|
|
}
|
|
|
|
|
2015-11-03 19:42:49 +00:00
|
|
|
public function testDontTriggerAutowiring()
|
2015-08-24 02:36:41 +01:00
|
|
|
{
|
|
|
|
$container = new ContainerBuilder();
|
|
|
|
|
|
|
|
$container->register('foo', __NAMESPACE__.'\Foo');
|
|
|
|
$container->register('bar', __NAMESPACE__.'\Bar');
|
|
|
|
|
|
|
|
$pass = new AutowirePass();
|
|
|
|
$pass->process($container);
|
|
|
|
|
|
|
|
$this->assertCount(0, $container->getDefinition('bar')->getArguments());
|
|
|
|
}
|
2015-11-04 18:04:11 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
|
|
|
* @expectedExceptionMessage Cannot autowire argument 2 for Symfony\Component\DependencyInjection\Tests\Compiler\BadTypeHintedArgument because the type-hinted class does not exist (Class Symfony\Component\DependencyInjection\Tests\Compiler\NotARealClass does not exist).
|
|
|
|
*/
|
|
|
|
public function testClassNotFoundThrowsException()
|
|
|
|
{
|
|
|
|
$container = new ContainerBuilder();
|
|
|
|
|
|
|
|
$aDefinition = $container->register('a', __NAMESPACE__.'\BadTypeHintedArgument');
|
|
|
|
$aDefinition->setAutowired(true);
|
|
|
|
|
|
|
|
$pass = new AutowirePass();
|
|
|
|
$pass->process($container);
|
|
|
|
}
|
2015-11-04 00:40:26 +00:00
|
|
|
|
|
|
|
public function testDontUseAbstractServices()
|
|
|
|
{
|
|
|
|
$container = new ContainerBuilder();
|
|
|
|
|
|
|
|
$container->register('abstract_foo', __NAMESPACE__.'\Foo')->setAbstract(true);
|
|
|
|
$container->register('foo', __NAMESPACE__.'\Foo');
|
|
|
|
$container->register('bar', __NAMESPACE__.'\Bar')->setAutowired(true);
|
|
|
|
|
|
|
|
$pass = new AutowirePass();
|
|
|
|
$pass->process($container);
|
|
|
|
|
|
|
|
$arguments = $container->getDefinition('bar')->getArguments();
|
|
|
|
$this->assertSame('foo', (string) $arguments[0]);
|
|
|
|
}
|
2015-08-24 02:36:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
class Foo
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
class Bar
|
|
|
|
{
|
|
|
|
public function __construct(Foo $foo)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class A
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
class B extends A
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
class C
|
|
|
|
{
|
|
|
|
public function __construct(A $a)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
interface DInterface
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
interface EInterface extends DInterface
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
class F implements EInterface
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
class G
|
|
|
|
{
|
|
|
|
public function __construct(DInterface $d, EInterface $e)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class H
|
|
|
|
{
|
|
|
|
public function __construct(B $b, DInterface $d)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
interface CollisionInterface
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
class CollisionA implements CollisionInterface
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
class CollisionB implements CollisionInterface
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
class CannotBeAutowired
|
|
|
|
{
|
|
|
|
public function __construct(CollisionInterface $collision)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class Lille
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
class Dunglas
|
|
|
|
{
|
|
|
|
public function __construct(Lille $l)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class LesTilleuls
|
|
|
|
{
|
|
|
|
public function __construct(Dunglas $k)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class OptionalParameter
|
|
|
|
{
|
|
|
|
public function __construct(CollisionInterface $c = null, A $a, Foo $f = null)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
2015-11-04 18:04:11 +00:00
|
|
|
|
|
|
|
class BadTypeHintedArgument
|
|
|
|
{
|
|
|
|
public function __construct(Dunglas $k, NotARealClass $r)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
2015-11-23 22:18:49 +00:00
|
|
|
class NotGuessableArgument
|
|
|
|
{
|
|
|
|
public function __construct(Foo $k)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
class NotGuessableArgumentForSubclass
|
|
|
|
{
|
|
|
|
public function __construct(A $k)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|