Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / vendor / symfony / http-kernel / Tests / KernelTest.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\HttpKernel\Tests;
13
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\Config\Loader\LoaderInterface;
16 use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
17 use Symfony\Component\DependencyInjection\ContainerBuilder;
18 use Symfony\Component\Filesystem\Filesystem;
19 use Symfony\Component\HttpFoundation\Request;
20 use Symfony\Component\HttpFoundation\Response;
21 use Symfony\Component\HttpKernel\Bundle\BundleInterface;
22 use Symfony\Component\HttpKernel\Config\EnvParametersResource;
23 use Symfony\Component\HttpKernel\DependencyInjection\ResettableServicePass;
24 use Symfony\Component\HttpKernel\DependencyInjection\ServicesResetter;
25 use Symfony\Component\HttpKernel\HttpKernelInterface;
26 use Symfony\Component\HttpKernel\Kernel;
27 use Symfony\Component\HttpKernel\Tests\Fixtures\KernelForOverrideName;
28 use Symfony\Component\HttpKernel\Tests\Fixtures\KernelForTest;
29 use Symfony\Component\HttpKernel\Tests\Fixtures\KernelWithoutBundles;
30 use Symfony\Component\HttpKernel\Tests\Fixtures\ResettableService;
31
32 class KernelTest extends TestCase
33 {
34     public static function tearDownAfterClass()
35     {
36         $fs = new Filesystem();
37         $fs->remove(__DIR__.'/Fixtures/cache');
38     }
39
40     public function testConstructor()
41     {
42         $env = 'test_env';
43         $debug = true;
44         $kernel = new KernelForTest($env, $debug);
45
46         $this->assertEquals($env, $kernel->getEnvironment());
47         $this->assertEquals($debug, $kernel->isDebug());
48         $this->assertFalse($kernel->isBooted());
49         $this->assertLessThanOrEqual(microtime(true), $kernel->getStartTime());
50         $this->assertNull($kernel->getContainer());
51     }
52
53     public function testClone()
54     {
55         $env = 'test_env';
56         $debug = true;
57         $kernel = new KernelForTest($env, $debug);
58
59         $clone = clone $kernel;
60
61         $this->assertEquals($env, $clone->getEnvironment());
62         $this->assertEquals($debug, $clone->isDebug());
63         $this->assertFalse($clone->isBooted());
64         $this->assertLessThanOrEqual(microtime(true), $clone->getStartTime());
65         $this->assertNull($clone->getContainer());
66     }
67
68     public function testInitializeContainerClearsOldContainers()
69     {
70         $fs = new Filesystem();
71         $legacyContainerDir = __DIR__.'/Fixtures/cache/custom/ContainerA123456';
72         $fs->mkdir($legacyContainerDir);
73         touch($legacyContainerDir.'.legacy');
74
75         $kernel = new CustomProjectDirKernel();
76         $kernel->boot();
77
78         $containerDir = __DIR__.'/Fixtures/cache/custom/'.substr(\get_class($kernel->getContainer()), 0, 16);
79         $this->assertTrue(unlink(__DIR__.'/Fixtures/cache/custom/FixturesCustomDebugProjectContainer.php.meta'));
80         $this->assertFileExists($containerDir);
81         $this->assertFileNotExists($containerDir.'.legacy');
82
83         $kernel = new CustomProjectDirKernel(function ($container) { $container->register('foo', 'stdClass')->setPublic(true); });
84         $kernel->boot();
85
86         $this->assertFileExists($containerDir);
87         $this->assertFileExists($containerDir.'.legacy');
88
89         $this->assertFileNotExists($legacyContainerDir);
90         $this->assertFileNotExists($legacyContainerDir.'.legacy');
91     }
92
93     public function testBootInitializesBundlesAndContainer()
94     {
95         $kernel = $this->getKernel(array('initializeBundles', 'initializeContainer'));
96         $kernel->expects($this->once())
97             ->method('initializeBundles');
98         $kernel->expects($this->once())
99             ->method('initializeContainer');
100
101         $kernel->boot();
102     }
103
104     public function testBootSetsTheContainerToTheBundles()
105     {
106         $bundle = $this->getMockBuilder('Symfony\Component\HttpKernel\Bundle\Bundle')->getMock();
107         $bundle->expects($this->once())
108             ->method('setContainer');
109
110         $kernel = $this->getKernel(array('initializeBundles', 'initializeContainer', 'getBundles'));
111         $kernel->expects($this->once())
112             ->method('getBundles')
113             ->will($this->returnValue(array($bundle)));
114
115         $kernel->boot();
116     }
117
118     public function testBootSetsTheBootedFlagToTrue()
119     {
120         // use test kernel to access isBooted()
121         $kernel = $this->getKernelForTest(array('initializeBundles', 'initializeContainer'));
122         $kernel->boot();
123
124         $this->assertTrue($kernel->isBooted());
125     }
126
127     /**
128      * @group legacy
129      */
130     public function testClassCacheIsLoaded()
131     {
132         $kernel = $this->getKernel(array('initializeBundles', 'initializeContainer', 'doLoadClassCache'));
133         $kernel->loadClassCache('name', '.extension');
134         $kernel->expects($this->once())
135             ->method('doLoadClassCache')
136             ->with('name', '.extension');
137
138         $kernel->boot();
139     }
140
141     public function testClassCacheIsNotLoadedByDefault()
142     {
143         $kernel = $this->getKernel(array('initializeBundles', 'initializeContainer', 'doLoadClassCache'));
144         $kernel->expects($this->never())
145             ->method('doLoadClassCache');
146
147         $kernel->boot();
148     }
149
150     /**
151      * @group legacy
152      */
153     public function testClassCacheIsNotLoadedWhenKernelIsNotBooted()
154     {
155         $kernel = $this->getKernel(array('initializeBundles', 'initializeContainer', 'doLoadClassCache'));
156         $kernel->loadClassCache();
157         $kernel->expects($this->never())
158             ->method('doLoadClassCache');
159     }
160
161     public function testEnvParametersResourceIsAdded()
162     {
163         $container = new ContainerBuilder();
164         $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\Tests\Fixtures\KernelForTest')
165             ->disableOriginalConstructor()
166             ->setMethods(array('getContainerBuilder', 'prepareContainer', 'getCacheDir', 'getLogDir'))
167             ->getMock();
168         $kernel->expects($this->any())
169             ->method('getContainerBuilder')
170             ->will($this->returnValue($container));
171         $kernel->expects($this->any())
172             ->method('prepareContainer')
173             ->will($this->returnValue(null));
174         $kernel->expects($this->any())
175             ->method('getCacheDir')
176             ->will($this->returnValue(sys_get_temp_dir()));
177         $kernel->expects($this->any())
178             ->method('getLogDir')
179             ->will($this->returnValue(sys_get_temp_dir()));
180
181         $reflection = new \ReflectionClass(\get_class($kernel));
182         $method = $reflection->getMethod('buildContainer');
183         $method->setAccessible(true);
184         $method->invoke($kernel);
185
186         $found = false;
187         foreach ($container->getResources() as $resource) {
188             if ($resource instanceof EnvParametersResource) {
189                 $found = true;
190                 break;
191             }
192         }
193
194         $this->assertTrue($found);
195     }
196
197     public function testBootKernelSeveralTimesOnlyInitializesBundlesOnce()
198     {
199         $kernel = $this->getKernel(array('initializeBundles', 'initializeContainer'));
200         $kernel->expects($this->once())
201             ->method('initializeBundles');
202
203         $kernel->boot();
204         $kernel->boot();
205     }
206
207     public function testShutdownCallsShutdownOnAllBundles()
208     {
209         $bundle = $this->getMockBuilder('Symfony\Component\HttpKernel\Bundle\Bundle')->getMock();
210         $bundle->expects($this->once())
211             ->method('shutdown');
212
213         $kernel = $this->getKernel(array(), array($bundle));
214
215         $kernel->boot();
216         $kernel->shutdown();
217     }
218
219     public function testShutdownGivesNullContainerToAllBundles()
220     {
221         $bundle = $this->getMockBuilder('Symfony\Component\HttpKernel\Bundle\Bundle')->getMock();
222         $bundle->expects($this->at(3))
223             ->method('setContainer')
224             ->with(null);
225
226         $kernel = $this->getKernel(array('getBundles'));
227         $kernel->expects($this->any())
228             ->method('getBundles')
229             ->will($this->returnValue(array($bundle)));
230
231         $kernel->boot();
232         $kernel->shutdown();
233     }
234
235     public function testHandleCallsHandleOnHttpKernel()
236     {
237         $type = HttpKernelInterface::MASTER_REQUEST;
238         $catch = true;
239         $request = new Request();
240
241         $httpKernelMock = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernel')
242             ->disableOriginalConstructor()
243             ->getMock();
244         $httpKernelMock
245             ->expects($this->once())
246             ->method('handle')
247             ->with($request, $type, $catch);
248
249         $kernel = $this->getKernel(array('getHttpKernel'));
250         $kernel->expects($this->once())
251             ->method('getHttpKernel')
252             ->will($this->returnValue($httpKernelMock));
253
254         $kernel->handle($request, $type, $catch);
255     }
256
257     public function testHandleBootsTheKernel()
258     {
259         $type = HttpKernelInterface::MASTER_REQUEST;
260         $catch = true;
261         $request = new Request();
262
263         $httpKernelMock = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernel')
264             ->disableOriginalConstructor()
265             ->getMock();
266
267         $kernel = $this->getKernel(array('getHttpKernel', 'boot'));
268         $kernel->expects($this->once())
269             ->method('getHttpKernel')
270             ->will($this->returnValue($httpKernelMock));
271
272         $kernel->expects($this->once())
273             ->method('boot');
274
275         $kernel->handle($request, $type, $catch);
276     }
277
278     public function testStripComments()
279     {
280         $source = <<<'EOF'
281 <?php
282
283 $string = 'string should not be   modified';
284
285 $string = 'string should not be
286
287 modified';
288
289
290 $heredoc = <<<HD
291
292
293 Heredoc should not be   modified {$a[1+$b]}
294
295
296 HD;
297
298 $nowdoc = <<<'ND'
299
300
301 Nowdoc should not be   modified
302
303
304 ND;
305
306 /**
307  * some class comments to strip
308  */
309 class TestClass
310 {
311     /**
312      * some method comments to strip
313      */
314     public function doStuff()
315     {
316         // inline comment
317     }
318 }
319 EOF;
320         $expected = <<<'EOF'
321 <?php
322 $string = 'string should not be   modified';
323 $string = 'string should not be
324
325 modified';
326 $heredoc = <<<HD
327
328
329 Heredoc should not be   modified {$a[1+$b]}
330
331
332 HD;
333 $nowdoc = <<<'ND'
334
335
336 Nowdoc should not be   modified
337
338
339 ND;
340 class TestClass
341 {
342     public function doStuff()
343     {
344         }
345 }
346 EOF;
347
348         $output = Kernel::stripComments($source);
349
350         // Heredocs are preserved, making the output mixing Unix and Windows line
351         // endings, switching to "\n" everywhere on Windows to avoid failure.
352         if ('\\' === \DIRECTORY_SEPARATOR) {
353             $expected = str_replace("\r\n", "\n", $expected);
354             $output = str_replace("\r\n", "\n", $output);
355         }
356
357         $this->assertEquals($expected, $output);
358     }
359
360     public function testGetRootDir()
361     {
362         $kernel = new KernelForTest('test', true);
363
364         $this->assertEquals(__DIR__.\DIRECTORY_SEPARATOR.'Fixtures', realpath($kernel->getRootDir()));
365     }
366
367     public function testGetName()
368     {
369         $kernel = new KernelForTest('test', true);
370
371         $this->assertEquals('Fixtures', $kernel->getName());
372     }
373
374     public function testOverrideGetName()
375     {
376         $kernel = new KernelForOverrideName('test', true);
377
378         $this->assertEquals('overridden', $kernel->getName());
379     }
380
381     public function testSerialize()
382     {
383         $env = 'test_env';
384         $debug = true;
385         $kernel = new KernelForTest($env, $debug);
386
387         $expected = serialize(array($env, $debug));
388         $this->assertEquals($expected, $kernel->serialize());
389     }
390
391     /**
392      * @expectedException \InvalidArgumentException
393      */
394     public function testLocateResourceThrowsExceptionWhenNameIsNotValid()
395     {
396         $this->getKernel()->locateResource('Foo');
397     }
398
399     /**
400      * @expectedException \RuntimeException
401      */
402     public function testLocateResourceThrowsExceptionWhenNameIsUnsafe()
403     {
404         $this->getKernel()->locateResource('@FooBundle/../bar');
405     }
406
407     /**
408      * @expectedException \InvalidArgumentException
409      */
410     public function testLocateResourceThrowsExceptionWhenBundleDoesNotExist()
411     {
412         $this->getKernel()->locateResource('@FooBundle/config/routing.xml');
413     }
414
415     /**
416      * @expectedException \InvalidArgumentException
417      */
418     public function testLocateResourceThrowsExceptionWhenResourceDoesNotExist()
419     {
420         $kernel = $this->getKernel(array('getBundle'));
421         $kernel
422             ->expects($this->once())
423             ->method('getBundle')
424             ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle'))))
425         ;
426
427         $kernel->locateResource('@Bundle1Bundle/config/routing.xml');
428     }
429
430     public function testLocateResourceReturnsTheFirstThatMatches()
431     {
432         $kernel = $this->getKernel(array('getBundle'));
433         $kernel
434             ->expects($this->once())
435             ->method('getBundle')
436             ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle'))))
437         ;
438
439         $this->assertEquals(__DIR__.'/Fixtures/Bundle1Bundle/foo.txt', $kernel->locateResource('@Bundle1Bundle/foo.txt'));
440     }
441
442     /**
443      * @group legacy
444      */
445     public function testLocateResourceReturnsTheFirstThatMatchesWithParent()
446     {
447         $parent = $this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle');
448         $child = $this->getBundle(__DIR__.'/Fixtures/Bundle2Bundle');
449
450         $kernel = $this->getKernel(array('getBundle'));
451         $kernel
452             ->expects($this->exactly(2))
453             ->method('getBundle')
454             ->will($this->returnValue(array($child, $parent)))
455         ;
456
457         $this->assertEquals(__DIR__.'/Fixtures/Bundle2Bundle/foo.txt', $kernel->locateResource('@ParentAABundle/foo.txt'));
458         $this->assertEquals(__DIR__.'/Fixtures/Bundle1Bundle/bar.txt', $kernel->locateResource('@ParentAABundle/bar.txt'));
459     }
460
461     /**
462      * @group legacy
463      */
464     public function testLocateResourceReturnsAllMatches()
465     {
466         $parent = $this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle');
467         $child = $this->getBundle(__DIR__.'/Fixtures/Bundle2Bundle');
468
469         $kernel = $this->getKernel(array('getBundle'));
470         $kernel
471             ->expects($this->once())
472             ->method('getBundle')
473             ->will($this->returnValue(array($child, $parent)))
474         ;
475
476         $this->assertEquals(array(
477             __DIR__.'/Fixtures/Bundle2Bundle/foo.txt',
478             __DIR__.'/Fixtures/Bundle1Bundle/foo.txt', ),
479             $kernel->locateResource('@Bundle1Bundle/foo.txt', null, false));
480     }
481
482     /**
483      * @group legacy
484      */
485     public function testLocateResourceReturnsAllMatchesBis()
486     {
487         $kernel = $this->getKernel(array('getBundle'));
488         $kernel
489             ->expects($this->once())
490             ->method('getBundle')
491             ->will($this->returnValue(array(
492                 $this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle'),
493                 $this->getBundle(__DIR__.'/Foobar'),
494             )))
495         ;
496
497         $this->assertEquals(
498             array(__DIR__.'/Fixtures/Bundle1Bundle/foo.txt'),
499             $kernel->locateResource('@Bundle1Bundle/foo.txt', null, false)
500         );
501     }
502
503     public function testLocateResourceIgnoresDirOnNonResource()
504     {
505         $kernel = $this->getKernel(array('getBundle'));
506         $kernel
507             ->expects($this->once())
508             ->method('getBundle')
509             ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle'))))
510         ;
511
512         $this->assertEquals(
513             __DIR__.'/Fixtures/Bundle1Bundle/foo.txt',
514             $kernel->locateResource('@Bundle1Bundle/foo.txt', __DIR__.'/Fixtures')
515         );
516     }
517
518     public function testLocateResourceReturnsTheDirOneForResources()
519     {
520         $kernel = $this->getKernel(array('getBundle'));
521         $kernel
522             ->expects($this->once())
523             ->method('getBundle')
524             ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/FooBundle', null, null, 'FooBundle'))))
525         ;
526
527         $this->assertEquals(
528             __DIR__.'/Fixtures/Resources/FooBundle/foo.txt',
529             $kernel->locateResource('@FooBundle/Resources/foo.txt', __DIR__.'/Fixtures/Resources')
530         );
531     }
532
533     /**
534      * @group legacy
535      */
536     public function testLocateResourceReturnsTheDirOneForResourcesAndBundleOnes()
537     {
538         $kernel = $this->getKernel(array('getBundle'));
539         $kernel
540             ->expects($this->once())
541             ->method('getBundle')
542             ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle', null, null, 'Bundle1Bundle'))))
543         ;
544
545         $this->assertEquals(array(
546             __DIR__.'/Fixtures/Resources/Bundle1Bundle/foo.txt',
547             __DIR__.'/Fixtures/Bundle1Bundle/Resources/foo.txt', ),
548             $kernel->locateResource('@Bundle1Bundle/Resources/foo.txt', __DIR__.'/Fixtures/Resources', false)
549         );
550     }
551
552     /**
553      * @group legacy
554      */
555     public function testLocateResourceOverrideBundleAndResourcesFolders()
556     {
557         $parent = $this->getBundle(__DIR__.'/Fixtures/BaseBundle', null, 'BaseBundle', 'BaseBundle');
558         $child = $this->getBundle(__DIR__.'/Fixtures/ChildBundle', 'ParentBundle', 'ChildBundle', 'ChildBundle');
559
560         $kernel = $this->getKernel(array('getBundle'));
561         $kernel
562             ->expects($this->exactly(4))
563             ->method('getBundle')
564             ->will($this->returnValue(array($child, $parent)))
565         ;
566
567         $this->assertEquals(array(
568             __DIR__.'/Fixtures/Resources/ChildBundle/foo.txt',
569             __DIR__.'/Fixtures/ChildBundle/Resources/foo.txt',
570             __DIR__.'/Fixtures/BaseBundle/Resources/foo.txt',
571             ),
572             $kernel->locateResource('@BaseBundle/Resources/foo.txt', __DIR__.'/Fixtures/Resources', false)
573         );
574
575         $this->assertEquals(
576             __DIR__.'/Fixtures/Resources/ChildBundle/foo.txt',
577             $kernel->locateResource('@BaseBundle/Resources/foo.txt', __DIR__.'/Fixtures/Resources')
578         );
579
580         try {
581             $kernel->locateResource('@BaseBundle/Resources/hide.txt', __DIR__.'/Fixtures/Resources', false);
582             $this->fail('Hidden resources should raise an exception when returning an array of matching paths');
583         } catch (\RuntimeException $e) {
584         }
585
586         try {
587             $kernel->locateResource('@BaseBundle/Resources/hide.txt', __DIR__.'/Fixtures/Resources', true);
588             $this->fail('Hidden resources should raise an exception when returning the first matching path');
589         } catch (\RuntimeException $e) {
590         }
591     }
592
593     public function testLocateResourceOnDirectories()
594     {
595         $kernel = $this->getKernel(array('getBundle'));
596         $kernel
597             ->expects($this->exactly(2))
598             ->method('getBundle')
599             ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/FooBundle', null, null, 'FooBundle'))))
600         ;
601
602         $this->assertEquals(
603             __DIR__.'/Fixtures/Resources/FooBundle/',
604             $kernel->locateResource('@FooBundle/Resources/', __DIR__.'/Fixtures/Resources')
605         );
606         $this->assertEquals(
607             __DIR__.'/Fixtures/Resources/FooBundle',
608             $kernel->locateResource('@FooBundle/Resources', __DIR__.'/Fixtures/Resources')
609         );
610
611         $kernel = $this->getKernel(array('getBundle'));
612         $kernel
613             ->expects($this->exactly(2))
614             ->method('getBundle')
615             ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle', null, null, 'Bundle1Bundle'))))
616         ;
617
618         $this->assertEquals(
619             __DIR__.'/Fixtures/Bundle1Bundle/Resources/',
620             $kernel->locateResource('@Bundle1Bundle/Resources/')
621         );
622         $this->assertEquals(
623             __DIR__.'/Fixtures/Bundle1Bundle/Resources',
624             $kernel->locateResource('@Bundle1Bundle/Resources')
625         );
626     }
627
628     /**
629      * @group legacy
630      */
631     public function testInitializeBundles()
632     {
633         $parent = $this->getBundle(null, null, 'ParentABundle');
634         $child = $this->getBundle(null, 'ParentABundle', 'ChildABundle');
635
636         // use test kernel so we can access getBundleMap()
637         $kernel = $this->getKernelForTest(array('registerBundles'));
638         $kernel
639             ->expects($this->once())
640             ->method('registerBundles')
641             ->will($this->returnValue(array($parent, $child)))
642         ;
643         $kernel->boot();
644
645         $map = $kernel->getBundleMap();
646         $this->assertEquals(array($child, $parent), $map['ParentABundle']);
647     }
648
649     /**
650      * @group legacy
651      */
652     public function testInitializeBundlesSupportInheritanceCascade()
653     {
654         $grandparent = $this->getBundle(null, null, 'GrandParentBBundle');
655         $parent = $this->getBundle(null, 'GrandParentBBundle', 'ParentBBundle');
656         $child = $this->getBundle(null, 'ParentBBundle', 'ChildBBundle');
657
658         // use test kernel so we can access getBundleMap()
659         $kernel = $this->getKernelForTest(array('registerBundles'));
660         $kernel
661             ->expects($this->once())
662             ->method('registerBundles')
663             ->will($this->returnValue(array($grandparent, $parent, $child)))
664         ;
665         $kernel->boot();
666
667         $map = $kernel->getBundleMap();
668         $this->assertEquals(array($child, $parent, $grandparent), $map['GrandParentBBundle']);
669         $this->assertEquals(array($child, $parent), $map['ParentBBundle']);
670         $this->assertEquals(array($child), $map['ChildBBundle']);
671     }
672
673     /**
674      * @group legacy
675      * @expectedException \LogicException
676      * @expectedExceptionMessage Bundle "ChildCBundle" extends bundle "FooBar", which is not registered.
677      */
678     public function testInitializeBundlesThrowsExceptionWhenAParentDoesNotExists()
679     {
680         $child = $this->getBundle(null, 'FooBar', 'ChildCBundle');
681         $kernel = $this->getKernel(array(), array($child));
682         $kernel->boot();
683     }
684
685     /**
686      * @group legacy
687      */
688     public function testInitializeBundlesSupportsArbitraryBundleRegistrationOrder()
689     {
690         $grandparent = $this->getBundle(null, null, 'GrandParentCBundle');
691         $parent = $this->getBundle(null, 'GrandParentCBundle', 'ParentCBundle');
692         $child = $this->getBundle(null, 'ParentCBundle', 'ChildCBundle');
693
694         // use test kernel so we can access getBundleMap()
695         $kernel = $this->getKernelForTest(array('registerBundles'));
696         $kernel
697             ->expects($this->once())
698             ->method('registerBundles')
699             ->will($this->returnValue(array($parent, $grandparent, $child)))
700         ;
701         $kernel->boot();
702
703         $map = $kernel->getBundleMap();
704         $this->assertEquals(array($child, $parent, $grandparent), $map['GrandParentCBundle']);
705         $this->assertEquals(array($child, $parent), $map['ParentCBundle']);
706         $this->assertEquals(array($child), $map['ChildCBundle']);
707     }
708
709     /**
710      * @group legacy
711      * @expectedException \LogicException
712      * @expectedExceptionMessage Bundle "ParentCBundle" is directly extended by two bundles "ChildC2Bundle" and "ChildC1Bundle".
713      */
714     public function testInitializeBundlesThrowsExceptionWhenABundleIsDirectlyExtendedByTwoBundles()
715     {
716         $parent = $this->getBundle(null, null, 'ParentCBundle');
717         $child1 = $this->getBundle(null, 'ParentCBundle', 'ChildC1Bundle');
718         $child2 = $this->getBundle(null, 'ParentCBundle', 'ChildC2Bundle');
719
720         $kernel = $this->getKernel(array(), array($parent, $child1, $child2));
721         $kernel->boot();
722     }
723
724     /**
725      * @group legacy
726      * @expectedException \LogicException
727      * @expectedExceptionMessage Trying to register two bundles with the same name "DuplicateName"
728      */
729     public function testInitializeBundleThrowsExceptionWhenRegisteringTwoBundlesWithTheSameName()
730     {
731         $fooBundle = $this->getBundle(null, null, 'FooBundle', 'DuplicateName');
732         $barBundle = $this->getBundle(null, null, 'BarBundle', 'DuplicateName');
733
734         $kernel = $this->getKernel(array(), array($fooBundle, $barBundle));
735         $kernel->boot();
736     }
737
738     /**
739      * @group legacy
740      * @expectedException \LogicException
741      * @expectedExceptionMessage Bundle "CircularRefBundle" can not extend itself.
742      */
743     public function testInitializeBundleThrowsExceptionWhenABundleExtendsItself()
744     {
745         $circularRef = $this->getBundle(null, 'CircularRefBundle', 'CircularRefBundle');
746
747         $kernel = $this->getKernel(array(), array($circularRef));
748         $kernel->boot();
749     }
750
751     public function testTerminateReturnsSilentlyIfKernelIsNotBooted()
752     {
753         $kernel = $this->getKernel(array('getHttpKernel'));
754         $kernel->expects($this->never())
755             ->method('getHttpKernel');
756
757         $kernel->terminate(Request::create('/'), new Response());
758     }
759
760     public function testTerminateDelegatesTerminationOnlyForTerminableInterface()
761     {
762         // does not implement TerminableInterface
763         $httpKernel = new TestKernel();
764
765         $kernel = $this->getKernel(array('getHttpKernel'));
766         $kernel->expects($this->once())
767             ->method('getHttpKernel')
768             ->willReturn($httpKernel);
769
770         $kernel->boot();
771         $kernel->terminate(Request::create('/'), new Response());
772
773         $this->assertFalse($httpKernel->terminateCalled, 'terminate() is never called if the kernel class does not implement TerminableInterface');
774
775         // implements TerminableInterface
776         $httpKernelMock = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernel')
777             ->disableOriginalConstructor()
778             ->setMethods(array('terminate'))
779             ->getMock();
780
781         $httpKernelMock
782             ->expects($this->once())
783             ->method('terminate');
784
785         $kernel = $this->getKernel(array('getHttpKernel'));
786         $kernel->expects($this->exactly(2))
787             ->method('getHttpKernel')
788             ->will($this->returnValue($httpKernelMock));
789
790         $kernel->boot();
791         $kernel->terminate(Request::create('/'), new Response());
792     }
793
794     public function testKernelWithoutBundles()
795     {
796         $kernel = new KernelWithoutBundles('test', true);
797         $kernel->boot();
798
799         $this->assertTrue($kernel->getContainer()->getParameter('test_executed'));
800     }
801
802     public function testKernelRootDirNameStartingWithANumber()
803     {
804         $dir = __DIR__.'/Fixtures/123';
805         require_once $dir.'/Kernel123.php';
806         $kernel = new \Symfony\Component\HttpKernel\Tests\Fixtures\_123\Kernel123('dev', true);
807         $this->assertEquals('_123', $kernel->getName());
808     }
809
810     /**
811      * @group legacy
812      * @expectedDeprecation The "Symfony\Component\HttpKernel\Kernel::getEnvParameters()" method is deprecated as of 3.3 and will be removed in 4.0. Use the %cenv()%c syntax to get the value of any environment variable from configuration files instead.
813      * @expectedDeprecation The support of special environment variables that start with SYMFONY__ (such as "SYMFONY__FOO__BAR") is deprecated as of 3.3 and will be removed in 4.0. Use the %cenv()%c syntax instead to get the value of environment variables in configuration files.
814      */
815     public function testSymfonyEnvironmentVariables()
816     {
817         $_SERVER['SYMFONY__FOO__BAR'] = 'baz';
818
819         $kernel = $this->getKernel();
820         $method = new \ReflectionMethod($kernel, 'getEnvParameters');
821         $method->setAccessible(true);
822
823         $envParameters = $method->invoke($kernel);
824         $this->assertSame('baz', $envParameters['foo.bar']);
825
826         unset($_SERVER['SYMFONY__FOO__BAR']);
827     }
828
829     public function testProjectDirExtension()
830     {
831         $kernel = new CustomProjectDirKernel();
832         $kernel->boot();
833
834         $this->assertSame('foo', $kernel->getProjectDir());
835         $this->assertSame('foo', $kernel->getContainer()->getParameter('kernel.project_dir'));
836     }
837
838     public function testKernelReset()
839     {
840         (new Filesystem())->remove(__DIR__.'/Fixtures/cache');
841
842         $kernel = new CustomProjectDirKernel();
843         $kernel->boot();
844
845         $containerClass = \get_class($kernel->getContainer());
846         $containerFile = (new \ReflectionClass($kernel->getContainer()))->getFileName();
847         unlink(__DIR__.'/Fixtures/cache/custom/FixturesCustomDebugProjectContainer.php.meta');
848
849         $kernel = new CustomProjectDirKernel();
850         $kernel->boot();
851
852         $this->assertInstanceOf($containerClass, $kernel->getContainer());
853         $this->assertFileExists($containerFile);
854         unlink(__DIR__.'/Fixtures/cache/custom/FixturesCustomDebugProjectContainer.php.meta');
855
856         $kernel = new CustomProjectDirKernel(function ($container) { $container->register('foo', 'stdClass')->setPublic(true); });
857         $kernel->boot();
858
859         $this->assertNotInstanceOf($containerClass, $kernel->getContainer());
860         $this->assertFileExists($containerFile);
861         $this->assertFileExists(\dirname($containerFile).'.legacy');
862     }
863
864     public function testKernelPass()
865     {
866         $kernel = new PassKernel();
867         $kernel->boot();
868
869         $this->assertTrue($kernel->getContainer()->getParameter('test.processed'));
870     }
871
872     public function testServicesResetter()
873     {
874         $httpKernelMock = $this->getMockBuilder(HttpKernelInterface::class)
875             ->disableOriginalConstructor()
876             ->getMock();
877         $httpKernelMock
878             ->expects($this->exactly(2))
879             ->method('handle');
880
881         $kernel = new CustomProjectDirKernel(function ($container) {
882             $container->addCompilerPass(new ResettableServicePass());
883             $container->register('one', ResettableService::class)
884                 ->setPublic(true)
885                 ->addTag('kernel.reset', array('method' => 'reset'));
886             $container->register('services_resetter', ServicesResetter::class)->setPublic(true);
887         }, $httpKernelMock, 'resetting');
888
889         ResettableService::$counter = 0;
890
891         $request = new Request();
892
893         $kernel->handle($request);
894         $kernel->getContainer()->get('one');
895
896         $this->assertEquals(0, ResettableService::$counter);
897         $this->assertFalse($kernel->getContainer()->initialized('services_resetter'));
898
899         $kernel->handle($request);
900
901         $this->assertEquals(1, ResettableService::$counter);
902     }
903
904     /**
905      * @group time-sensitive
906      */
907     public function testKernelStartTimeIsResetWhileBootingAlreadyBootedKernel()
908     {
909         $kernel = $this->getKernelForTest(array('initializeBundles'), true);
910         $kernel->boot();
911         $preReBoot = $kernel->getStartTime();
912
913         sleep(3600); //Intentionally large value to detect if ClockMock ever breaks
914         $kernel->reboot(null);
915
916         $this->assertGreaterThan($preReBoot, $kernel->getStartTime());
917     }
918
919     /**
920      * Returns a mock for the BundleInterface.
921      *
922      * @return BundleInterface
923      */
924     protected function getBundle($dir = null, $parent = null, $className = null, $bundleName = null)
925     {
926         $bundle = $this
927             ->getMockBuilder('Symfony\Component\HttpKernel\Bundle\BundleInterface')
928             ->setMethods(array('getPath', 'getParent', 'getName'))
929             ->disableOriginalConstructor()
930         ;
931
932         if ($className) {
933             $bundle->setMockClassName($className);
934         }
935
936         $bundle = $bundle->getMockForAbstractClass();
937
938         $bundle
939             ->expects($this->any())
940             ->method('getName')
941             ->will($this->returnValue(null === $bundleName ? \get_class($bundle) : $bundleName))
942         ;
943
944         $bundle
945             ->expects($this->any())
946             ->method('getPath')
947             ->will($this->returnValue($dir))
948         ;
949
950         $bundle
951             ->expects($this->any())
952             ->method('getParent')
953             ->will($this->returnValue($parent))
954         ;
955
956         return $bundle;
957     }
958
959     /**
960      * Returns a mock for the abstract kernel.
961      *
962      * @param array $methods Additional methods to mock (besides the abstract ones)
963      * @param array $bundles Bundles to register
964      *
965      * @return Kernel
966      */
967     protected function getKernel(array $methods = array(), array $bundles = array())
968     {
969         $methods[] = 'registerBundles';
970
971         $kernel = $this
972             ->getMockBuilder('Symfony\Component\HttpKernel\Kernel')
973             ->setMethods($methods)
974             ->setConstructorArgs(array('test', false))
975             ->getMockForAbstractClass()
976         ;
977         $kernel->expects($this->any())
978             ->method('registerBundles')
979             ->will($this->returnValue($bundles))
980         ;
981         $p = new \ReflectionProperty($kernel, 'rootDir');
982         $p->setAccessible(true);
983         $p->setValue($kernel, __DIR__.'/Fixtures');
984
985         return $kernel;
986     }
987
988     protected function getKernelForTest(array $methods = array(), $debug = false)
989     {
990         $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\Tests\Fixtures\KernelForTest')
991             ->setConstructorArgs(array('test', $debug))
992             ->setMethods($methods)
993             ->getMock();
994         $p = new \ReflectionProperty($kernel, 'rootDir');
995         $p->setAccessible(true);
996         $p->setValue($kernel, __DIR__.'/Fixtures');
997
998         return $kernel;
999     }
1000 }
1001
1002 class TestKernel implements HttpKernelInterface
1003 {
1004     public $terminateCalled = false;
1005
1006     public function terminate()
1007     {
1008         $this->terminateCalled = true;
1009     }
1010
1011     public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true)
1012     {
1013     }
1014 }
1015
1016 class CustomProjectDirKernel extends Kernel
1017 {
1018     private $baseDir;
1019     private $buildContainer;
1020     private $httpKernel;
1021
1022     public function __construct(\Closure $buildContainer = null, HttpKernelInterface $httpKernel = null, $name = 'custom')
1023     {
1024         parent::__construct($name, true);
1025
1026         $this->baseDir = 'foo';
1027         $this->buildContainer = $buildContainer;
1028         $this->httpKernel = $httpKernel;
1029     }
1030
1031     public function registerBundles()
1032     {
1033         return array();
1034     }
1035
1036     public function registerContainerConfiguration(LoaderInterface $loader)
1037     {
1038     }
1039
1040     public function getProjectDir()
1041     {
1042         return $this->baseDir;
1043     }
1044
1045     public function getRootDir()
1046     {
1047         return __DIR__.'/Fixtures';
1048     }
1049
1050     protected function build(ContainerBuilder $container)
1051     {
1052         if ($build = $this->buildContainer) {
1053             $build($container);
1054         }
1055     }
1056
1057     protected function getHttpKernel()
1058     {
1059         return $this->httpKernel;
1060     }
1061 }
1062
1063 class PassKernel extends CustomProjectDirKernel implements CompilerPassInterface
1064 {
1065     public function __construct()
1066     {
1067         parent::__construct();
1068         Kernel::__construct('pass', true);
1069     }
1070
1071     public function process(ContainerBuilder $container)
1072     {
1073         $container->setParameter('test.processed', true);
1074     }
1075 }