Added the Search API Synonym module to deal specifically with licence and license...
[yaffs-website] / vendor / symfony / dependency-injection / Tests / Compiler / ResolveInstanceofConditionalsPassTest.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\DependencyInjection\Tests\Compiler;
13
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\DependencyInjection\Argument\BoundArgument;
16 use Symfony\Component\DependencyInjection\ChildDefinition;
17 use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
18 use Symfony\Component\DependencyInjection\Compiler\ResolveInstanceofConditionalsPass;
19 use Symfony\Component\DependencyInjection\ContainerBuilder;
20
21 class ResolveInstanceofConditionalsPassTest extends TestCase
22 {
23     public function testProcess()
24     {
25         $container = new ContainerBuilder();
26         $def = $container->register('foo', self::class)->addTag('tag')->setAutowired(true)->setChanges(array());
27         $def->setInstanceofConditionals(array(
28             parent::class => (new ChildDefinition(''))->setProperty('foo', 'bar')->addTag('baz', array('attr' => 123)),
29         ));
30
31         (new ResolveInstanceofConditionalsPass())->process($container);
32
33         $parent = 'instanceof.'.parent::class.'.0.foo';
34         $def = $container->getDefinition('foo');
35         $this->assertEmpty($def->getInstanceofConditionals());
36         $this->assertInstanceOf(ChildDefinition::class, $def);
37         $this->assertTrue($def->isAutowired());
38         $this->assertSame($parent, $def->getParent());
39         $this->assertSame(array('tag' => array(array()), 'baz' => array(array('attr' => 123))), $def->getTags());
40
41         $parent = $container->getDefinition($parent);
42         $this->assertSame(array('foo' => 'bar'), $parent->getProperties());
43         $this->assertSame(array(), $parent->getTags());
44     }
45
46     public function testProcessInheritance()
47     {
48         $container = new ContainerBuilder();
49
50         $def = $container
51             ->register('parent', parent::class)
52             ->addMethodCall('foo', array('foo'));
53         $def->setInstanceofConditionals(array(
54             parent::class => (new ChildDefinition(''))->addMethodCall('foo', array('bar')),
55         ));
56
57         $def = (new ChildDefinition('parent'))->setClass(self::class);
58         $container->setDefinition('child', $def);
59
60         (new ResolveInstanceofConditionalsPass())->process($container);
61         (new ResolveChildDefinitionsPass())->process($container);
62
63         $expected = array(
64             array('foo', array('bar')),
65             array('foo', array('foo')),
66         );
67
68         $this->assertSame($expected, $container->getDefinition('parent')->getMethodCalls());
69         $this->assertSame($expected, $container->getDefinition('child')->getMethodCalls());
70     }
71
72     public function testProcessDoesReplaceShared()
73     {
74         $container = new ContainerBuilder();
75
76         $def = $container->register('foo', 'stdClass');
77         $def->setInstanceofConditionals(array(
78             'stdClass' => (new ChildDefinition(''))->setShared(false),
79         ));
80
81         (new ResolveInstanceofConditionalsPass())->process($container);
82
83         $def = $container->getDefinition('foo');
84         $this->assertFalse($def->isShared());
85     }
86
87     public function testProcessHandlesMultipleInheritance()
88     {
89         $container = new ContainerBuilder();
90
91         $def = $container->register('foo', self::class)->setShared(true);
92
93         $def->setInstanceofConditionals(array(
94             parent::class => (new ChildDefinition(''))->setLazy(true)->setShared(false),
95             self::class => (new ChildDefinition(''))->setAutowired(true),
96         ));
97
98         (new ResolveInstanceofConditionalsPass())->process($container);
99         (new ResolveChildDefinitionsPass())->process($container);
100
101         $def = $container->getDefinition('foo');
102         $this->assertTrue($def->isAutowired());
103         $this->assertTrue($def->isLazy());
104         $this->assertTrue($def->isShared());
105     }
106
107     public function testProcessUsesAutoconfiguredInstanceof()
108     {
109         $container = new ContainerBuilder();
110         $def = $container->register('normal_service', self::class);
111         $def->setInstanceofConditionals(array(
112             parent::class => (new ChildDefinition(''))
113                 ->addTag('local_instanceof_tag')
114                 ->setFactory('locally_set_factory'),
115         ));
116         $def->setAutoconfigured(true);
117         $container->registerForAutoconfiguration(parent::class)
118             ->addTag('autoconfigured_tag')
119             ->setAutowired(true)
120             ->setFactory('autoconfigured_factory');
121
122         (new ResolveInstanceofConditionalsPass())->process($container);
123         (new ResolveChildDefinitionsPass())->process($container);
124
125         $def = $container->getDefinition('normal_service');
126         // autowired thanks to the autoconfigured instanceof
127         $this->assertTrue($def->isAutowired());
128         // factory from the specific instanceof overrides global one
129         $this->assertEquals('locally_set_factory', $def->getFactory());
130         // tags are merged, the locally set one is first
131         $this->assertSame(array('local_instanceof_tag' => array(array()), 'autoconfigured_tag' => array(array())), $def->getTags());
132     }
133
134     public function testAutoconfigureInstanceofDoesNotDuplicateTags()
135     {
136         $container = new ContainerBuilder();
137         $def = $container->register('normal_service', self::class);
138         $def
139             ->addTag('duplicated_tag')
140             ->addTag('duplicated_tag', array('and_attributes' => 1))
141         ;
142         $def->setInstanceofConditionals(array(
143             parent::class => (new ChildDefinition(''))->addTag('duplicated_tag'),
144         ));
145         $def->setAutoconfigured(true);
146         $container->registerForAutoconfiguration(parent::class)
147             ->addTag('duplicated_tag', array('and_attributes' => 1))
148         ;
149
150         (new ResolveInstanceofConditionalsPass())->process($container);
151         (new ResolveChildDefinitionsPass())->process($container);
152
153         $def = $container->getDefinition('normal_service');
154         $this->assertSame(array('duplicated_tag' => array(array(), array('and_attributes' => 1))), $def->getTags());
155     }
156
157     public function testProcessDoesNotUseAutoconfiguredInstanceofIfNotEnabled()
158     {
159         $container = new ContainerBuilder();
160         $def = $container->register('normal_service', self::class);
161         $def->setInstanceofConditionals(array(
162             parent::class => (new ChildDefinition(''))
163                 ->addTag('foo_tag'),
164         ));
165         $container->registerForAutoconfiguration(parent::class)
166             ->setAutowired(true);
167
168         (new ResolveInstanceofConditionalsPass())->process($container);
169         (new ResolveChildDefinitionsPass())->process($container);
170
171         $def = $container->getDefinition('normal_service');
172         $this->assertFalse($def->isAutowired());
173     }
174
175     /**
176      * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
177      * @expectedExceptionMessage "App\FakeInterface" is set as an "instanceof" conditional, but it does not exist.
178      */
179     public function testBadInterfaceThrowsException()
180     {
181         $container = new ContainerBuilder();
182         $def = $container->register('normal_service', self::class);
183         $def->setInstanceofConditionals(array(
184             'App\\FakeInterface' => (new ChildDefinition(''))
185                 ->addTag('foo_tag'),
186         ));
187
188         (new ResolveInstanceofConditionalsPass())->process($container);
189     }
190
191     public function testBadInterfaceForAutomaticInstanceofIsOk()
192     {
193         $container = new ContainerBuilder();
194         $container->register('normal_service', self::class)
195             ->setAutoconfigured(true);
196         $container->registerForAutoconfiguration('App\\FakeInterface')
197             ->setAutowired(true);
198
199         (new ResolveInstanceofConditionalsPass())->process($container);
200         $this->assertTrue($container->hasDefinition('normal_service'));
201     }
202
203     /**
204      * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
205      * @expectedExceptionMessage Autoconfigured instanceof for type "PHPUnit\Framework\TestCase" defines method calls but these are not supported and should be removed.
206      */
207     public function testProcessThrowsExceptionForAutoconfiguredCalls()
208     {
209         $container = new ContainerBuilder();
210         $container->registerForAutoconfiguration(parent::class)
211             ->addMethodCall('setFoo');
212
213         (new ResolveInstanceofConditionalsPass())->process($container);
214     }
215
216     /**
217      * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
218      * @expectedExceptionMessage Autoconfigured instanceof for type "PHPUnit\Framework\TestCase" defines arguments but these are not supported and should be removed.
219      */
220     public function testProcessThrowsExceptionForArguments()
221     {
222         $container = new ContainerBuilder();
223         $container->registerForAutoconfiguration(parent::class)
224             ->addArgument('bar');
225
226         (new ResolveInstanceofConditionalsPass())->process($container);
227     }
228
229     public function testMergeReset()
230     {
231         $container = new ContainerBuilder();
232
233         $container
234             ->register('bar', self::class)
235             ->addArgument('a')
236             ->addMethodCall('setB')
237             ->setDecoratedService('foo')
238             ->addTag('t')
239             ->setInstanceofConditionals(array(
240                 parent::class => (new ChildDefinition(''))->addTag('bar'),
241             ))
242         ;
243
244         (new ResolveInstanceofConditionalsPass())->process($container);
245
246         $abstract = $container->getDefinition('abstract.instanceof.bar');
247
248         $this->assertEmpty($abstract->getArguments());
249         $this->assertEmpty($abstract->getMethodCalls());
250         $this->assertNull($abstract->getDecoratedService());
251         $this->assertEmpty($abstract->getTags());
252         $this->assertTrue($abstract->isAbstract());
253     }
254
255     public function testBindings()
256     {
257         $container = new ContainerBuilder();
258         $def = $container->register('foo', self::class)->setBindings(array('$toto' => 123));
259         $def->setInstanceofConditionals(array(parent::class => new ChildDefinition('')));
260
261         (new ResolveInstanceofConditionalsPass())->process($container);
262
263         $bindings = $container->getDefinition('foo')->getBindings();
264         $this->assertSame(array('$toto'), array_keys($bindings));
265         $this->assertInstanceOf(BoundArgument::class, $bindings['$toto']);
266         $this->assertSame(123, $bindings['$toto']->getValues()[0]);
267     }
268 }