4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\DependencyInjection\Tests\Compiler;
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\DependencyInjection\Compiler\FactoryReturnTypePass;
16 use Symfony\Component\DependencyInjection\ContainerBuilder;
17 use Symfony\Component\DependencyInjection\Reference;
18 use Symfony\Component\DependencyInjection\Tests\Fixtures\FactoryDummy;
19 use Symfony\Component\DependencyInjection\Tests\Fixtures\factoryFunction;
20 use Symfony\Component\DependencyInjection\Tests\Fixtures\FactoryParent;
23 * @author Guilhem N. <egetick@gmail.com>
27 class FactoryReturnTypePassTest extends TestCase
29 public function testProcess()
31 $container = new ContainerBuilder();
33 $factory = $container->register('factory');
34 $factory->setFactory(array(FactoryDummy::class, 'createFactory'));
36 $container->setAlias('alias_factory', 'factory');
38 $foo = $container->register('foo');
39 $foo->setFactory(array(new Reference('alias_factory'), 'create'));
41 $bar = $container->register('bar', __CLASS__);
42 $bar->setFactory(array(new Reference('factory'), 'create'));
44 $pass = new FactoryReturnTypePass();
45 $pass->process($container);
47 if (method_exists(\ReflectionMethod::class, 'getReturnType')) {
48 $this->assertEquals(FactoryDummy::class, $factory->getClass());
49 $this->assertEquals(\stdClass::class, $foo->getClass());
51 $this->assertNull($factory->getClass());
52 $this->assertNull($foo->getClass());
54 $this->assertEquals(__CLASS__, $bar->getClass());
58 * @dataProvider returnTypesProvider
60 public function testReturnTypes($factory, $returnType, $hhvmSupport = true)
62 if (!$hhvmSupport && \defined('HHVM_VERSION')) {
63 $this->markTestSkipped('Scalar typehints not supported by hhvm.');
66 $container = new ContainerBuilder();
68 $service = $container->register('service');
69 $service->setFactory($factory);
71 $pass = new FactoryReturnTypePass();
72 $pass->process($container);
74 if (method_exists(\ReflectionMethod::class, 'getReturnType')) {
75 $this->assertEquals($returnType, $service->getClass());
77 $this->assertNull($service->getClass());
81 public function returnTypesProvider()
84 // must be loaded before the function as they are in the same file
85 array(array(FactoryDummy::class, 'createBuiltin'), null, false),
86 array(array(FactoryDummy::class, 'createParent'), FactoryParent::class),
87 array(array(FactoryDummy::class, 'createSelf'), FactoryDummy::class),
88 array(factoryFunction::class, FactoryDummy::class),
92 public function testCircularReference()
94 $container = new ContainerBuilder();
96 $factory = $container->register('factory');
97 $factory->setFactory(array(new Reference('factory2'), 'createSelf'));
99 $factory2 = $container->register('factory2');
100 $factory2->setFactory(array(new Reference('factory'), 'create'));
102 $pass = new FactoryReturnTypePass();
103 $pass->process($container);
105 $this->assertNull($factory->getClass());
106 $this->assertNull($factory2->getClass());
110 * @requires function ReflectionMethod::getReturnType
111 * @expectedDeprecation Relying on its factory's return-type to define the class of service "factory" is deprecated since Symfony 3.3 and won't work in 4.0. Set the "class" attribute to "Symfony\Component\DependencyInjection\Tests\Fixtures\FactoryDummy" on the service definition instead.
113 public function testCompile()
115 $container = new ContainerBuilder();
117 $factory = $container->register('factory');
118 $factory->setFactory(array(FactoryDummy::class, 'createFactory'));
119 $container->compile();
121 $this->assertEquals(FactoryDummy::class, $container->getDefinition('factory')->getClass());