Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / vendor / symfony / dependency-injection / Tests / ContainerTest.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;
13
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\DependencyInjection\Alias;
16 use Symfony\Component\DependencyInjection\Container;
17 use Symfony\Component\DependencyInjection\ContainerInterface;
18 use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
19 use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
20
21 class ContainerTest extends TestCase
22 {
23     public function testConstructor()
24     {
25         $sc = new Container();
26         $this->assertSame($sc, $sc->get('service_container'), '__construct() automatically registers itself as a service');
27
28         $sc = new Container(new ParameterBag(array('foo' => 'bar')));
29         $this->assertEquals(array('foo' => 'bar'), $sc->getParameterBag()->all(), '__construct() takes an array of parameters as its first argument');
30     }
31
32     /**
33      * @dataProvider dataForTestCamelize
34      */
35     public function testCamelize($id, $expected)
36     {
37         $this->assertEquals($expected, Container::camelize($id), sprintf('Container::camelize("%s")', $id));
38     }
39
40     public function dataForTestCamelize()
41     {
42         return array(
43             array('foo_bar', 'FooBar'),
44             array('foo.bar', 'Foo_Bar'),
45             array('foo.bar_baz', 'Foo_BarBaz'),
46             array('foo._bar', 'Foo_Bar'),
47             array('foo_.bar', 'Foo_Bar'),
48             array('_foo', 'Foo'),
49             array('.foo', '_Foo'),
50             array('foo_', 'Foo'),
51             array('foo.', 'Foo_'),
52             array('foo\bar', 'Foo_Bar'),
53         );
54     }
55
56     /**
57      * @dataProvider dataForTestUnderscore
58      */
59     public function testUnderscore($id, $expected)
60     {
61         $this->assertEquals($expected, Container::underscore($id), sprintf('Container::underscore("%s")', $id));
62     }
63
64     public function dataForTestUnderscore()
65     {
66         return array(
67             array('FooBar', 'foo_bar'),
68             array('Foo_Bar', 'foo.bar'),
69             array('Foo_BarBaz', 'foo.bar_baz'),
70             array('FooBar_BazQux', 'foo_bar.baz_qux'),
71             array('_Foo', '.foo'),
72             array('Foo_', 'foo.'),
73         );
74     }
75
76     public function testCompile()
77     {
78         $sc = new Container(new ParameterBag(array('foo' => 'bar')));
79         $this->assertFalse($sc->getParameterBag()->isResolved(), '->compile() resolves the parameter bag');
80         $sc->compile();
81         $this->assertTrue($sc->getParameterBag()->isResolved(), '->compile() resolves the parameter bag');
82         $this->assertInstanceOf('Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag', $sc->getParameterBag(), '->compile() changes the parameter bag to a FrozenParameterBag instance');
83         $this->assertEquals(array('foo' => 'bar'), $sc->getParameterBag()->all(), '->compile() copies the current parameters to the new parameter bag');
84     }
85
86     /**
87      * @group legacy
88      * @expectedDeprecation The Symfony\Component\DependencyInjection\Container::isFrozen() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.
89      * @expectedDeprecation The Symfony\Component\DependencyInjection\Container::isFrozen() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.
90      */
91     public function testIsFrozen()
92     {
93         $sc = new Container(new ParameterBag(array('foo' => 'bar')));
94         $this->assertFalse($sc->isFrozen(), '->isFrozen() returns false if the parameters are not frozen');
95         $sc->compile();
96         $this->assertTrue($sc->isFrozen(), '->isFrozen() returns true if the parameters are frozen');
97     }
98
99     public function testIsCompiled()
100     {
101         $sc = new Container(new ParameterBag(array('foo' => 'bar')));
102         $this->assertFalse($sc->isCompiled(), '->isCompiled() returns false if the container is not compiled');
103         $sc->compile();
104         $this->assertTrue($sc->isCompiled(), '->isCompiled() returns true if the container is compiled');
105     }
106
107     public function testIsCompiledWithFrozenParameters()
108     {
109         $sc = new Container(new FrozenParameterBag(array('foo' => 'bar')));
110         $this->assertFalse($sc->isCompiled(), '->isCompiled() returns false if the container is not compiled but the parameter bag is already frozen');
111     }
112
113     public function testGetParameterBag()
114     {
115         $sc = new Container();
116         $this->assertEquals(array(), $sc->getParameterBag()->all(), '->getParameterBag() returns an empty array if no parameter has been defined');
117     }
118
119     public function testGetSetParameter()
120     {
121         $sc = new Container(new ParameterBag(array('foo' => 'bar')));
122         $sc->setParameter('bar', 'foo');
123         $this->assertEquals('foo', $sc->getParameter('bar'), '->setParameter() sets the value of a new parameter');
124
125         $sc->setParameter('foo', 'baz');
126         $this->assertEquals('baz', $sc->getParameter('foo'), '->setParameter() overrides previously set parameter');
127
128         try {
129             $sc->getParameter('baba');
130             $this->fail('->getParameter() thrown an \InvalidArgumentException if the key does not exist');
131         } catch (\Exception $e) {
132             $this->assertInstanceOf('\InvalidArgumentException', $e, '->getParameter() thrown an \InvalidArgumentException if the key does not exist');
133             $this->assertEquals('You have requested a non-existent parameter "baba".', $e->getMessage(), '->getParameter() thrown an \InvalidArgumentException if the key does not exist');
134         }
135     }
136
137     /**
138      * @group legacy
139      * @expectedDeprecation Parameter names will be made case sensitive in Symfony 4.0. Using "Foo" instead of "foo" is deprecated since Symfony 3.4.
140      * @expectedDeprecation Parameter names will be made case sensitive in Symfony 4.0. Using "FOO" instead of "foo" is deprecated since Symfony 3.4.
141      */
142     public function testGetSetParameterWithMixedCase()
143     {
144         $sc = new Container(new ParameterBag(array('foo' => 'bar')));
145
146         $sc->setParameter('Foo', 'baz1');
147         $this->assertEquals('baz1', $sc->getParameter('foo'), '->setParameter() converts the key to lowercase');
148         $this->assertEquals('baz1', $sc->getParameter('FOO'), '->getParameter() converts the key to lowercase');
149     }
150
151     public function testGetServiceIds()
152     {
153         $sc = new Container();
154         $sc->set('foo', $obj = new \stdClass());
155         $sc->set('bar', $obj = new \stdClass());
156         $this->assertEquals(array('service_container', 'foo', 'bar'), $sc->getServiceIds(), '->getServiceIds() returns all defined service ids');
157
158         $sc = new ProjectServiceContainer();
159         $sc->set('foo', $obj = new \stdClass());
160         $this->assertEquals(array('service_container', 'internal', 'bar', 'foo_bar', 'foo.baz', 'circular', 'throw_exception', 'throws_exception_on_service_configuration', 'internal_dependency', 'foo'), $sc->getServiceIds(), '->getServiceIds() returns defined service ids by factory methods in the method map, followed by service ids defined by set()');
161     }
162
163     /**
164      * @group legacy
165      * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.
166      */
167     public function testGetLegacyServiceIds()
168     {
169         $sc = new LegacyProjectServiceContainer();
170         $sc->set('foo', $obj = new \stdClass());
171
172         $this->assertEquals(array('internal', 'bar', 'foo_bar', 'foo.baz', 'circular', 'throw_exception', 'throws_exception_on_service_configuration', 'service_container', 'foo'), $sc->getServiceIds(), '->getServiceIds() returns defined service ids by getXXXService() methods, followed by service ids defined by set()');
173     }
174
175     public function testSet()
176     {
177         $sc = new Container();
178         $sc->set('._. \\o/', $foo = new \stdClass());
179         $this->assertSame($foo, $sc->get('._. \\o/'), '->set() sets a service');
180     }
181
182     public function testSetWithNullResetTheService()
183     {
184         $sc = new Container();
185         $sc->set('foo', null);
186         $this->assertFalse($sc->has('foo'), '->set() with null service resets the service');
187     }
188
189     public function testSetReplacesAlias()
190     {
191         $c = new ProjectServiceContainer();
192
193         $c->set('alias', $foo = new \stdClass());
194         $this->assertSame($foo, $c->get('alias'), '->set() replaces an existing alias');
195     }
196
197     /**
198      * @group legacy
199      * @expectedDeprecation The "bar" service is already initialized, unsetting it is deprecated since Symfony 3.3 and will fail in 4.0.
200      */
201     public function testSetWithNullOnInitializedPredefinedService()
202     {
203         $sc = new Container();
204         $sc->set('foo', new \stdClass());
205         $sc->set('foo', null);
206         $this->assertFalse($sc->has('foo'), '->set() with null service resets the service');
207
208         $sc = new ProjectServiceContainer();
209         $sc->get('bar');
210         $sc->set('bar', null);
211         $this->assertTrue($sc->has('bar'), '->set() with null service resets the pre-defined service');
212     }
213
214     public function testSetWithNullOnUninitializedPredefinedService()
215     {
216         $sc = new Container();
217         $sc->set('foo', new \stdClass());
218         $sc->get('foo', null);
219         $sc->set('foo', null);
220         $this->assertFalse($sc->has('foo'), '->set() with null service resets the service');
221
222         $sc = new ProjectServiceContainer();
223         $sc->set('bar', null);
224         $this->assertTrue($sc->has('bar'), '->set() with null service resets the pre-defined service');
225     }
226
227     public function testGet()
228     {
229         $sc = new ProjectServiceContainer();
230         $sc->set('foo', $foo = new \stdClass());
231         $this->assertSame($foo, $sc->get('foo'), '->get() returns the service for the given id');
232         $this->assertSame($sc->__bar, $sc->get('bar'), '->get() returns the service for the given id');
233         $this->assertSame($sc->__foo_bar, $sc->get('foo_bar'), '->get() returns the service if a get*Method() is defined');
234         $this->assertSame($sc->__foo_baz, $sc->get('foo.baz'), '->get() returns the service if a get*Method() is defined');
235
236         try {
237             $sc->get('');
238             $this->fail('->get() throws a \InvalidArgumentException exception if the service is empty');
239         } catch (\Exception $e) {
240             $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws a ServiceNotFoundException exception if the service is empty');
241         }
242         $this->assertNull($sc->get('', ContainerInterface::NULL_ON_INVALID_REFERENCE), '->get() returns null if the service is empty');
243     }
244
245     /**
246      * @group legacy
247      * @expectedDeprecation Service identifiers will be made case sensitive in Symfony 4.0. Using "Foo" instead of "foo" is deprecated since Symfony 3.3.
248      */
249     public function testGetInsensitivity()
250     {
251         $sc = new ProjectServiceContainer();
252         $sc->set('foo', $foo = new \stdClass());
253         $this->assertSame($foo, $sc->get('Foo'), '->get() returns the service for the given id, and converts id to lowercase');
254     }
255
256     /**
257      * @group legacy
258      * @expectedDeprecation Service identifiers will be made case sensitive in Symfony 4.0. Using "foo" instead of "Foo" is deprecated since Symfony 3.3.
259      */
260     public function testNormalizeIdKeepsCase()
261     {
262         $sc = new ProjectServiceContainer();
263         $sc->normalizeId('Foo', true);
264         $this->assertSame('Foo', $sc->normalizeId('foo'));
265     }
266
267     /**
268      * @group legacy
269      * @expectedDeprecation Service identifiers will be made case sensitive in Symfony 4.0. Using "Foo" instead of "foo" is deprecated since Symfony 3.3.
270      * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.
271      * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.
272      * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.
273      * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.
274      */
275     public function testLegacyGet()
276     {
277         $sc = new LegacyProjectServiceContainer();
278         $sc->set('foo', $foo = new \stdClass());
279
280         $this->assertSame($foo, $sc->get('foo'), '->get() returns the service for the given id');
281         $this->assertSame($foo, $sc->get('Foo'), '->get() returns the service for the given id, and converts id to lowercase');
282         $this->assertSame($sc->__bar, $sc->get('bar'), '->get() returns the service for the given id');
283         $this->assertSame($sc->__foo_bar, $sc->get('foo_bar'), '->get() returns the service if a get*Method() is defined');
284         $this->assertSame($sc->__foo_baz, $sc->get('foo.baz'), '->get() returns the service if a get*Method() is defined');
285         $this->assertSame($sc->__foo_baz, $sc->get('foo\\baz'), '->get() returns the service if a get*Method() is defined');
286
287         $sc->set('bar', $bar = new \stdClass());
288         $this->assertSame($bar, $sc->get('bar'), '->get() prefers to return a service defined with set() than one defined with a getXXXMethod()');
289
290         try {
291             $sc->get('');
292             $this->fail('->get() throws a \InvalidArgumentException exception if the service is empty');
293         } catch (\Exception $e) {
294             $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws a ServiceNotFoundException exception if the service is empty');
295         }
296         $this->assertNull($sc->get('', ContainerInterface::NULL_ON_INVALID_REFERENCE), '->get() returns null if the service is empty');
297     }
298
299     public function testGetThrowServiceNotFoundException()
300     {
301         $sc = new ProjectServiceContainer();
302         $sc->set('foo', $foo = new \stdClass());
303         $sc->set('baz', $foo = new \stdClass());
304
305         try {
306             $sc->get('foo1');
307             $this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist');
308         } catch (\Exception $e) {
309             $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist');
310             $this->assertEquals('You have requested a non-existent service "foo1". Did you mean this: "foo"?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException with some advices');
311         }
312
313         try {
314             $sc->get('bag');
315             $this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist');
316         } catch (\Exception $e) {
317             $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist');
318             $this->assertEquals('You have requested a non-existent service "bag". Did you mean one of these: "bar", "baz"?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException with some advices');
319         }
320     }
321
322     public function testGetCircularReference()
323     {
324         $sc = new ProjectServiceContainer();
325         try {
326             $sc->get('circular');
327             $this->fail('->get() throws a ServiceCircularReferenceException if it contains circular reference');
328         } catch (\Exception $e) {
329             $this->assertInstanceOf('\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException', $e, '->get() throws a ServiceCircularReferenceException if it contains circular reference');
330             $this->assertStringStartsWith('Circular reference detected for service "circular"', $e->getMessage(), '->get() throws a \LogicException if it contains circular reference');
331         }
332     }
333
334     /**
335      * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException
336      * @expectedExceptionMessage The "request" service is synthetic, it needs to be set at boot time before it can be used.
337      */
338     public function testGetSyntheticServiceThrows()
339     {
340         require_once __DIR__.'/Fixtures/php/services9_compiled.php';
341
342         $container = new \ProjectServiceContainer();
343         $container->get('request');
344     }
345
346     /**
347      * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException
348      * @expectedExceptionMessage The "inlined" service or alias has been removed or inlined when the container was compiled. You should either make it public, or stop using the container directly and use dependency injection instead.
349      */
350     public function testGetRemovedServiceThrows()
351     {
352         require_once __DIR__.'/Fixtures/php/services9_compiled.php';
353
354         $container = new \ProjectServiceContainer();
355         $container->get('inlined');
356     }
357
358     public function testHas()
359     {
360         $sc = new ProjectServiceContainer();
361         $sc->set('foo', new \stdClass());
362         $this->assertFalse($sc->has('foo1'), '->has() returns false if the service does not exist');
363         $this->assertTrue($sc->has('foo'), '->has() returns true if the service exists');
364         $this->assertTrue($sc->has('bar'), '->has() returns true if a get*Method() is defined');
365         $this->assertTrue($sc->has('foo_bar'), '->has() returns true if a get*Method() is defined');
366         $this->assertTrue($sc->has('foo.baz'), '->has() returns true if a get*Method() is defined');
367     }
368
369     /**
370      * @group legacy
371      * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.
372      * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.
373      * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.
374      * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.
375      */
376     public function testLegacyHas()
377     {
378         $sc = new LegacyProjectServiceContainer();
379         $sc->set('foo', new \stdClass());
380
381         $this->assertFalse($sc->has('foo1'), '->has() returns false if the service does not exist');
382         $this->assertTrue($sc->has('foo'), '->has() returns true if the service exists');
383         $this->assertTrue($sc->has('bar'), '->has() returns true if a get*Method() is defined');
384         $this->assertTrue($sc->has('foo_bar'), '->has() returns true if a get*Method() is defined');
385         $this->assertTrue($sc->has('foo.baz'), '->has() returns true if a get*Method() is defined');
386         $this->assertTrue($sc->has('foo\\baz'), '->has() returns true if a get*Method() is defined');
387     }
388
389     public function testInitialized()
390     {
391         $sc = new ProjectServiceContainer();
392         $sc->set('foo', new \stdClass());
393         $this->assertTrue($sc->initialized('foo'), '->initialized() returns true if service is loaded');
394         $this->assertFalse($sc->initialized('foo1'), '->initialized() returns false if service is not loaded');
395         $this->assertFalse($sc->initialized('bar'), '->initialized() returns false if a service is defined, but not currently loaded');
396         $this->assertFalse($sc->initialized('alias'), '->initialized() returns false if an aliased service is not initialized');
397
398         $sc->get('bar');
399         $this->assertTrue($sc->initialized('alias'), '->initialized() returns true for alias if aliased service is initialized');
400     }
401
402     /**
403      * @group legacy
404      * @expectedDeprecation Checking for the initialization of the "internal" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0.
405      */
406     public function testInitializedWithPrivateService()
407     {
408         $sc = new ProjectServiceContainer();
409         $sc->get('internal_dependency');
410         $this->assertTrue($sc->initialized('internal'));
411     }
412
413     public function testReset()
414     {
415         $c = new Container();
416         $c->set('bar', new \stdClass());
417
418         $c->reset();
419
420         $this->assertNull($c->get('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE));
421     }
422
423     /**
424      * @expectedException \Exception
425      * @expectedExceptionMessage Something went terribly wrong!
426      */
427     public function testGetThrowsException()
428     {
429         $c = new ProjectServiceContainer();
430
431         try {
432             $c->get('throw_exception');
433         } catch (\Exception $e) {
434             // Do nothing.
435         }
436
437         // Retry, to make sure that get*Service() will be called.
438         $c->get('throw_exception');
439     }
440
441     public function testGetThrowsExceptionOnServiceConfiguration()
442     {
443         $c = new ProjectServiceContainer();
444
445         try {
446             $c->get('throws_exception_on_service_configuration');
447         } catch (\Exception $e) {
448             // Do nothing.
449         }
450
451         $this->assertFalse($c->initialized('throws_exception_on_service_configuration'));
452
453         // Retry, to make sure that get*Service() will be called.
454         try {
455             $c->get('throws_exception_on_service_configuration');
456         } catch (\Exception $e) {
457             // Do nothing.
458         }
459         $this->assertFalse($c->initialized('throws_exception_on_service_configuration'));
460     }
461
462     protected function getField($obj, $field)
463     {
464         $reflection = new \ReflectionProperty($obj, $field);
465         $reflection->setAccessible(true);
466
467         return $reflection->getValue($obj);
468     }
469
470     public function testAlias()
471     {
472         $c = new ProjectServiceContainer();
473
474         $this->assertTrue($c->has('alias'));
475         $this->assertSame($c->get('alias'), $c->get('bar'));
476     }
477
478     public function testThatCloningIsNotSupported()
479     {
480         $class = new \ReflectionClass('Symfony\Component\DependencyInjection\Container');
481         $clone = $class->getMethod('__clone');
482         $this->assertFalse($class->isCloneable());
483         $this->assertTrue($clone->isPrivate());
484     }
485
486     /**
487      * @group legacy
488      * @expectedDeprecation The "internal" service is private, unsetting it is deprecated since Symfony 3.2 and will fail in 4.0.
489      */
490     public function testUnsetInternalPrivateServiceIsDeprecated()
491     {
492         $c = new ProjectServiceContainer();
493         $c->set('internal', null);
494     }
495
496     /**
497      * @group legacy
498      * @expectedDeprecation The "internal" service is private, replacing it is deprecated since Symfony 3.2 and will fail in 4.0.
499      */
500     public function testChangeInternalPrivateServiceIsDeprecated()
501     {
502         $c = new ProjectServiceContainer();
503         $c->set('internal', $internal = new \stdClass());
504         $this->assertSame($c->get('internal'), $internal);
505     }
506
507     /**
508      * @group legacy
509      * @expectedDeprecation The "internal" service is private, checking for its existence is deprecated since Symfony 3.2 and will fail in 4.0.
510      */
511     public function testCheckExistenceOfAnInternalPrivateServiceIsDeprecated()
512     {
513         $c = new ProjectServiceContainer();
514         $c->get('internal_dependency');
515         $this->assertTrue($c->has('internal'));
516     }
517
518     /**
519      * @group legacy
520      * @expectedDeprecation The "internal" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead.
521      */
522     public function testRequestAnInternalSharedPrivateServiceIsDeprecated()
523     {
524         $c = new ProjectServiceContainer();
525         $c->get('internal_dependency');
526         $c->get('internal');
527     }
528
529     /**
530      * @group legacy
531      * @expectedDeprecation The "bar" service is already initialized, replacing it is deprecated since Symfony 3.3 and will fail in 4.0.
532      */
533     public function testReplacingAPreDefinedServiceIsDeprecated()
534     {
535         $c = new ProjectServiceContainer();
536         $c->set('bar', new \stdClass());
537         $c->set('bar', $bar = new \stdClass());
538
539         $this->assertSame($bar, $c->get('bar'), '->set() replaces a pre-defined service');
540     }
541
542     /**
543      * @group legacy
544      * @expectedDeprecation The "synthetic" service is private, replacing it is deprecated since Symfony 3.2 and will fail in 4.0.
545      */
546     public function testSetWithPrivateSyntheticServiceThrowsDeprecation()
547     {
548         $c = new ProjectServiceContainer();
549         $c->set('synthetic', new \stdClass());
550     }
551 }
552
553 class ProjectServiceContainer extends Container
554 {
555     public $__bar;
556     public $__foo_bar;
557     public $__foo_baz;
558     public $__internal;
559     protected $privates;
560     protected $methodMap = array(
561         'internal' => 'getInternalService',
562         'bar' => 'getBarService',
563         'foo_bar' => 'getFooBarService',
564         'foo.baz' => 'getFoo_BazService',
565         'circular' => 'getCircularService',
566         'throw_exception' => 'getThrowExceptionService',
567         'throws_exception_on_service_configuration' => 'getThrowsExceptionOnServiceConfigurationService',
568         'internal_dependency' => 'getInternalDependencyService',
569     );
570
571     public function __construct()
572     {
573         parent::__construct();
574
575         $this->__bar = new \stdClass();
576         $this->__foo_bar = new \stdClass();
577         $this->__foo_baz = new \stdClass();
578         $this->__internal = new \stdClass();
579         $this->privates = array(
580             'internal' => true,
581             'synthetic' => true,
582         );
583         $this->aliases = array('alias' => 'bar');
584         $this->syntheticIds['synthetic'] = true;
585     }
586
587     protected function getInternalService()
588     {
589         return $this->services['internal'] = $this->__internal;
590     }
591
592     protected function getBarService()
593     {
594         return $this->services['bar'] = $this->__bar;
595     }
596
597     protected function getFooBarService()
598     {
599         return $this->__foo_bar;
600     }
601
602     protected function getFoo_BazService()
603     {
604         return $this->__foo_baz;
605     }
606
607     protected function getCircularService()
608     {
609         return $this->get('circular');
610     }
611
612     protected function getThrowExceptionService()
613     {
614         throw new \Exception('Something went terribly wrong!');
615     }
616
617     protected function getThrowsExceptionOnServiceConfigurationService()
618     {
619         $this->services['throws_exception_on_service_configuration'] = $instance = new \stdClass();
620
621         throw new \Exception('Something was terribly wrong while trying to configure the service!');
622     }
623
624     protected function getInternalDependencyService()
625     {
626         $this->services['internal_dependency'] = $instance = new \stdClass();
627
628         $instance->internal = isset($this->services['internal']) ? $this->services['internal'] : $this->getInternalService();
629
630         return $instance;
631     }
632 }
633
634 class LegacyProjectServiceContainer extends Container
635 {
636     public $__bar;
637     public $__foo_bar;
638     public $__foo_baz;
639     public $__internal;
640
641     public function __construct()
642     {
643         parent::__construct();
644
645         $this->__bar = new \stdClass();
646         $this->__foo_bar = new \stdClass();
647         $this->__foo_baz = new \stdClass();
648         $this->__internal = new \stdClass();
649         $this->privates = array('internal' => true);
650         $this->aliases = array('alias' => 'bar');
651     }
652
653     protected function getInternalService()
654     {
655         return $this->__internal;
656     }
657
658     protected function getBarService()
659     {
660         return $this->__bar;
661     }
662
663     protected function getFooBarService()
664     {
665         return $this->__foo_bar;
666     }
667
668     protected function getFoo_BazService()
669     {
670         return $this->__foo_baz;
671     }
672
673     protected function getCircularService()
674     {
675         return $this->get('circular');
676     }
677
678     protected function getThrowExceptionService()
679     {
680         throw new \Exception('Something went terribly wrong!');
681     }
682
683     protected function getThrowsExceptionOnServiceConfigurationService()
684     {
685         $this->services['throws_exception_on_service_configuration'] = $instance = new \stdClass();
686
687         throw new \Exception('Something was terribly wrong while trying to configure the service!');
688     }
689 }