Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / vendor / symfony / dependency-injection / Tests / Compiler / InlineServiceDefinitionsPassTest.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\Definition;
16 use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
17 use Symfony\Component\DependencyInjection\Compiler\RepeatedPass;
18 use Symfony\Component\DependencyInjection\Compiler\InlineServiceDefinitionsPass;
19 use Symfony\Component\DependencyInjection\Reference;
20 use Symfony\Component\DependencyInjection\ContainerBuilder;
21 use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
22 use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
23
24 class InlineServiceDefinitionsPassTest extends TestCase
25 {
26     public function testProcess()
27     {
28         $container = new ContainerBuilder();
29         $container
30             ->register('inlinable.service')
31             ->setPublic(false)
32         ;
33
34         $container
35             ->register('service')
36             ->setArguments(array(new Reference('inlinable.service')))
37         ;
38
39         $this->process($container);
40
41         $arguments = $container->getDefinition('service')->getArguments();
42         $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $arguments[0]);
43         $this->assertSame($container->getDefinition('inlinable.service'), $arguments[0]);
44     }
45
46     public function testProcessDoesNotInlinesWhenAliasedServiceIsShared()
47     {
48         $container = new ContainerBuilder();
49         $container
50             ->register('foo')
51             ->setPublic(false)
52         ;
53         $container->setAlias('moo', 'foo');
54
55         $container
56             ->register('service')
57             ->setArguments(array($ref = new Reference('foo')))
58         ;
59
60         $this->process($container);
61
62         $arguments = $container->getDefinition('service')->getArguments();
63         $this->assertSame($ref, $arguments[0]);
64     }
65
66     public function testProcessDoesInlineNonSharedService()
67     {
68         $container = new ContainerBuilder();
69         $container
70             ->register('foo')
71             ->setShared(false)
72         ;
73         $container
74             ->register('bar')
75             ->setPublic(false)
76             ->setShared(false)
77         ;
78         $container->setAlias('moo', 'bar');
79
80         $container
81             ->register('service')
82             ->setArguments(array(new Reference('foo'), $ref = new Reference('moo'), new Reference('bar')))
83         ;
84
85         $this->process($container);
86
87         $arguments = $container->getDefinition('service')->getArguments();
88         $this->assertEquals($container->getDefinition('foo'), $arguments[0]);
89         $this->assertNotSame($container->getDefinition('foo'), $arguments[0]);
90         $this->assertSame($ref, $arguments[1]);
91         $this->assertEquals($container->getDefinition('bar'), $arguments[2]);
92         $this->assertNotSame($container->getDefinition('bar'), $arguments[2]);
93     }
94
95     public function testProcessInlinesMixedServicesLoop()
96     {
97         $container = new ContainerBuilder();
98         $container
99             ->register('foo')
100             ->addArgument(new Reference('bar'))
101             ->setShared(false)
102         ;
103         $container
104             ->register('bar')
105             ->setPublic(false)
106             ->addMethodCall('setFoo', array(new Reference('foo')))
107         ;
108
109         $this->process($container);
110
111         $this->assertEquals($container->getDefinition('foo')->getArgument(0), $container->getDefinition('bar'));
112     }
113
114     /**
115      * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
116      * @expectedExceptionMessage Circular reference detected for service "bar", path: "bar -> foo -> bar".
117      */
118     public function testProcessThrowsOnNonSharedLoops()
119     {
120         $container = new ContainerBuilder();
121         $container
122             ->register('foo')
123             ->addArgument(new Reference('bar'))
124             ->setShared(false)
125         ;
126         $container
127             ->register('bar')
128             ->setShared(false)
129             ->addMethodCall('setFoo', array(new Reference('foo')))
130         ;
131
132         $this->process($container);
133     }
134
135     public function testProcessNestedNonSharedServices()
136     {
137         $container = new ContainerBuilder();
138         $container
139             ->register('foo')
140             ->addArgument(new Reference('bar1'))
141             ->addArgument(new Reference('bar2'))
142         ;
143         $container
144             ->register('bar1')
145             ->setShared(false)
146             ->addArgument(new Reference('baz'))
147         ;
148         $container
149             ->register('bar2')
150             ->setShared(false)
151             ->addArgument(new Reference('baz'))
152         ;
153         $container
154             ->register('baz')
155             ->setShared(false)
156         ;
157
158         $this->process($container);
159
160         $baz1 = $container->getDefinition('foo')->getArgument(0)->getArgument(0);
161         $baz2 = $container->getDefinition('foo')->getArgument(1)->getArgument(0);
162
163         $this->assertEquals($container->getDefinition('baz'), $baz1);
164         $this->assertEquals($container->getDefinition('baz'), $baz2);
165         $this->assertNotSame($baz1, $baz2);
166     }
167
168     public function testProcessInlinesIfMultipleReferencesButAllFromTheSameDefinition()
169     {
170         $container = new ContainerBuilder();
171
172         $a = $container->register('a')->setPublic(false);
173         $b = $container
174             ->register('b')
175             ->addArgument(new Reference('a'))
176             ->addArgument(new Definition(null, array(new Reference('a'))))
177         ;
178
179         $this->process($container);
180
181         $arguments = $b->getArguments();
182         $this->assertSame($a, $arguments[0]);
183
184         $inlinedArguments = $arguments[1]->getArguments();
185         $this->assertSame($a, $inlinedArguments[0]);
186     }
187
188     public function testProcessInlinesPrivateFactoryReference()
189     {
190         $container = new ContainerBuilder();
191
192         $container->register('a')->setPublic(false);
193         $b = $container
194             ->register('b')
195             ->setPublic(false)
196             ->setFactory(array(new Reference('a'), 'a'))
197         ;
198
199         $container
200             ->register('foo')
201             ->setArguments(array(
202                 $ref = new Reference('b'),
203             ));
204
205         $this->process($container);
206
207         $inlinedArguments = $container->getDefinition('foo')->getArguments();
208         $this->assertSame($b, $inlinedArguments[0]);
209     }
210
211     public function testProcessDoesNotInlinePrivateFactoryIfReferencedMultipleTimesWithinTheSameDefinition()
212     {
213         $container = new ContainerBuilder();
214         $container
215             ->register('a')
216         ;
217         $container
218             ->register('b')
219             ->setPublic(false)
220             ->setFactory(array(new Reference('a'), 'a'))
221         ;
222
223         $container
224             ->register('foo')
225             ->setArguments(array(
226                     $ref1 = new Reference('b'),
227                     $ref2 = new Reference('b'),
228                 ))
229         ;
230         $this->process($container);
231
232         $args = $container->getDefinition('foo')->getArguments();
233         $this->assertSame($ref1, $args[0]);
234         $this->assertSame($ref2, $args[1]);
235     }
236
237     public function testProcessDoesNotInlineReferenceWhenUsedByInlineFactory()
238     {
239         $container = new ContainerBuilder();
240         $container
241             ->register('a')
242         ;
243         $container
244             ->register('b')
245             ->setPublic(false)
246             ->setFactory(array(new Reference('a'), 'a'))
247         ;
248
249         $inlineFactory = new Definition();
250         $inlineFactory->setPublic(false);
251         $inlineFactory->setFactory(array(new Reference('b'), 'b'));
252
253         $container
254             ->register('foo')
255             ->setArguments(array(
256                     $ref = new Reference('b'),
257                     $inlineFactory,
258                 ))
259         ;
260         $this->process($container);
261
262         $args = $container->getDefinition('foo')->getArguments();
263         $this->assertSame($ref, $args[0]);
264     }
265
266     public function testProcessDoesNotInlineWhenServiceIsPrivateButLazy()
267     {
268         $container = new ContainerBuilder();
269         $container
270             ->register('foo')
271             ->setPublic(false)
272             ->setLazy(true)
273         ;
274
275         $container
276             ->register('service')
277             ->setArguments(array($ref = new Reference('foo')))
278         ;
279
280         $this->process($container);
281
282         $arguments = $container->getDefinition('service')->getArguments();
283         $this->assertSame($ref, $arguments[0]);
284     }
285
286     public function testProcessDoesNotInlineWhenServiceReferencesItself()
287     {
288         $container = new ContainerBuilder();
289         $container
290             ->register('foo')
291             ->setPublic(false)
292             ->addMethodCall('foo', array($ref = new Reference('foo')))
293         ;
294
295         $this->process($container);
296
297         $calls = $container->getDefinition('foo')->getMethodCalls();
298         $this->assertSame($ref, $calls[0][1][0]);
299     }
300
301     public function testProcessDoesNotSetLazyArgumentValuesAfterInlining()
302     {
303         $container = new ContainerBuilder();
304         $container
305             ->register('inline')
306             ->setShared(false)
307         ;
308         $container
309             ->register('service-closure')
310             ->setArguments(array(new ServiceClosureArgument(new Reference('inline'))))
311         ;
312         $container
313             ->register('iterator')
314             ->setArguments(array(new IteratorArgument(array(new Reference('inline')))))
315         ;
316
317         $this->process($container);
318
319         $values = $container->getDefinition('service-closure')->getArgument(0)->getValues();
320         $this->assertInstanceOf(Reference::class, $values[0]);
321         $this->assertSame('inline', (string) $values[0]);
322
323         $values = $container->getDefinition('iterator')->getArgument(0)->getValues();
324         $this->assertInstanceOf(Reference::class, $values[0]);
325         $this->assertSame('inline', (string) $values[0]);
326     }
327
328     /**
329      * @group legacy
330      */
331     public function testGetInlinedServiceIdData()
332     {
333         $container = new ContainerBuilder();
334         $container
335             ->register('inlinable.service')
336             ->setPublic(false)
337         ;
338         $container
339             ->register('non_inlinable.service')
340             ->setPublic(true)
341         ;
342
343         $container
344             ->register('other_service')
345             ->setArguments(array(new Reference('inlinable.service')))
346         ;
347
348         $inlinePass = new InlineServiceDefinitionsPass();
349         $repeatedPass = new RepeatedPass(array(new AnalyzeServiceReferencesPass(), $inlinePass));
350         $repeatedPass->process($container);
351
352         $this->assertEquals(array('inlinable.service' => array('other_service')), $inlinePass->getInlinedServiceIds());
353     }
354
355     protected function process(ContainerBuilder $container)
356     {
357         $repeatedPass = new RepeatedPass(array(new AnalyzeServiceReferencesPass(), new InlineServiceDefinitionsPass()));
358         $repeatedPass->process($container);
359     }
360 }