4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\HttpKernel\Tests;
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\DependencyInjection\ContainerBuilder;
16 use Symfony\Component\HttpKernel\Bundle\BundleInterface;
17 use Symfony\Component\HttpKernel\Config\EnvParametersResource;
18 use Symfony\Component\HttpKernel\Kernel;
19 use Symfony\Component\HttpKernel\HttpKernelInterface;
20 use Symfony\Component\HttpFoundation\Request;
21 use Symfony\Component\HttpFoundation\Response;
22 use Symfony\Component\HttpKernel\Tests\Fixtures\KernelForTest;
23 use Symfony\Component\HttpKernel\Tests\Fixtures\KernelForOverrideName;
25 class KernelTest extends TestCase
27 public function testConstructor()
31 $kernel = new KernelForTest($env, $debug);
33 $this->assertEquals($env, $kernel->getEnvironment());
34 $this->assertEquals($debug, $kernel->isDebug());
35 $this->assertFalse($kernel->isBooted());
36 $this->assertLessThanOrEqual(microtime(true), $kernel->getStartTime());
37 $this->assertNull($kernel->getContainer());
40 public function testClone()
44 $kernel = new KernelForTest($env, $debug);
46 $clone = clone $kernel;
48 $this->assertEquals($env, $clone->getEnvironment());
49 $this->assertEquals($debug, $clone->isDebug());
50 $this->assertFalse($clone->isBooted());
51 $this->assertLessThanOrEqual(microtime(true), $clone->getStartTime());
52 $this->assertNull($clone->getContainer());
55 public function testBootInitializesBundlesAndContainer()
57 $kernel = $this->getKernel(array('initializeBundles', 'initializeContainer'));
58 $kernel->expects($this->once())
59 ->method('initializeBundles');
60 $kernel->expects($this->once())
61 ->method('initializeContainer');
66 public function testBootSetsTheContainerToTheBundles()
68 $bundle = $this->getMockBuilder('Symfony\Component\HttpKernel\Bundle\Bundle')->getMock();
69 $bundle->expects($this->once())
70 ->method('setContainer');
72 $kernel = $this->getKernel(array('initializeBundles', 'initializeContainer', 'getBundles'));
73 $kernel->expects($this->once())
74 ->method('getBundles')
75 ->will($this->returnValue(array($bundle)));
80 public function testBootSetsTheBootedFlagToTrue()
82 // use test kernel to access isBooted()
83 $kernel = $this->getKernelForTest(array('initializeBundles', 'initializeContainer'));
86 $this->assertTrue($kernel->isBooted());
89 public function testClassCacheIsLoaded()
91 $kernel = $this->getKernel(array('initializeBundles', 'initializeContainer', 'doLoadClassCache'));
92 $kernel->loadClassCache('name', '.extension');
93 $kernel->expects($this->once())
94 ->method('doLoadClassCache')
95 ->with('name', '.extension');
100 public function testClassCacheIsNotLoadedByDefault()
102 $kernel = $this->getKernel(array('initializeBundles', 'initializeContainer', 'doLoadClassCache'));
103 $kernel->expects($this->never())
104 ->method('doLoadClassCache');
109 public function testClassCacheIsNotLoadedWhenKernelIsNotBooted()
111 $kernel = $this->getKernel(array('initializeBundles', 'initializeContainer', 'doLoadClassCache'));
112 $kernel->loadClassCache();
113 $kernel->expects($this->never())
114 ->method('doLoadClassCache');
117 public function testEnvParametersResourceIsAdded()
119 $container = new ContainerBuilder();
120 $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\Tests\Fixtures\KernelForTest')
121 ->disableOriginalConstructor()
122 ->setMethods(array('getContainerBuilder', 'prepareContainer', 'getCacheDir', 'getLogDir'))
124 $kernel->expects($this->any())
125 ->method('getContainerBuilder')
126 ->will($this->returnValue($container));
127 $kernel->expects($this->any())
128 ->method('prepareContainer')
129 ->will($this->returnValue(null));
130 $kernel->expects($this->any())
131 ->method('getCacheDir')
132 ->will($this->returnValue(sys_get_temp_dir()));
133 $kernel->expects($this->any())
134 ->method('getLogDir')
135 ->will($this->returnValue(sys_get_temp_dir()));
137 $reflection = new \ReflectionClass(get_class($kernel));
138 $method = $reflection->getMethod('buildContainer');
139 $method->setAccessible(true);
140 $method->invoke($kernel);
143 foreach ($container->getResources() as $resource) {
144 if ($resource instanceof EnvParametersResource) {
150 $this->assertTrue($found);
153 public function testBootKernelSeveralTimesOnlyInitializesBundlesOnce()
155 $kernel = $this->getKernel(array('initializeBundles', 'initializeContainer'));
156 $kernel->expects($this->once())
157 ->method('initializeBundles');
163 public function testShutdownCallsShutdownOnAllBundles()
165 $bundle = $this->getMockBuilder('Symfony\Component\HttpKernel\Bundle\Bundle')->getMock();
166 $bundle->expects($this->once())
167 ->method('shutdown');
169 $kernel = $this->getKernel(array(), array($bundle));
175 public function testShutdownGivesNullContainerToAllBundles()
177 $bundle = $this->getMockBuilder('Symfony\Component\HttpKernel\Bundle\Bundle')->getMock();
178 $bundle->expects($this->at(3))
179 ->method('setContainer')
182 $kernel = $this->getKernel(array('getBundles'));
183 $kernel->expects($this->any())
184 ->method('getBundles')
185 ->will($this->returnValue(array($bundle)));
191 public function testHandleCallsHandleOnHttpKernel()
193 $type = HttpKernelInterface::MASTER_REQUEST;
195 $request = new Request();
197 $httpKernelMock = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernel')
198 ->disableOriginalConstructor()
201 ->expects($this->once())
203 ->with($request, $type, $catch);
205 $kernel = $this->getKernel(array('getHttpKernel'));
206 $kernel->expects($this->once())
207 ->method('getHttpKernel')
208 ->will($this->returnValue($httpKernelMock));
210 $kernel->handle($request, $type, $catch);
213 public function testHandleBootsTheKernel()
215 $type = HttpKernelInterface::MASTER_REQUEST;
217 $request = new Request();
219 $httpKernelMock = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernel')
220 ->disableOriginalConstructor()
223 $kernel = $this->getKernel(array('getHttpKernel', 'boot'));
224 $kernel->expects($this->once())
225 ->method('getHttpKernel')
226 ->will($this->returnValue($httpKernelMock));
228 $kernel->expects($this->once())
231 $kernel->handle($request, $type, $catch);
234 public function testStripComments()
239 $string = 'string should not be modified';
241 $string = 'string should not be
249 Heredoc should not be modified {$a[1+$b]}
257 Nowdoc should not be modified
263 * some class comments to strip
268 * some method comments to strip
270 public function doStuff()
278 $string = 'string should not be modified';
279 $string = 'string should not be
285 Heredoc should not be modified {$a[1+$b]}
292 Nowdoc should not be modified
298 public function doStuff()
304 $output = Kernel::stripComments($source);
306 // Heredocs are preserved, making the output mixing Unix and Windows line
307 // endings, switching to "\n" everywhere on Windows to avoid failure.
308 if ('\\' === DIRECTORY_SEPARATOR) {
309 $expected = str_replace("\r\n", "\n", $expected);
310 $output = str_replace("\r\n", "\n", $output);
313 $this->assertEquals($expected, $output);
316 public function testGetRootDir()
318 $kernel = new KernelForTest('test', true);
320 $this->assertEquals(__DIR__.DIRECTORY_SEPARATOR.'Fixtures', realpath($kernel->getRootDir()));
323 public function testGetName()
325 $kernel = new KernelForTest('test', true);
327 $this->assertEquals('Fixtures', $kernel->getName());
330 public function testOverrideGetName()
332 $kernel = new KernelForOverrideName('test', true);
334 $this->assertEquals('overridden', $kernel->getName());
337 public function testSerialize()
341 $kernel = new KernelForTest($env, $debug);
343 $expected = serialize(array($env, $debug));
344 $this->assertEquals($expected, $kernel->serialize());
348 * @expectedException \InvalidArgumentException
350 public function testLocateResourceThrowsExceptionWhenNameIsNotValid()
352 $this->getKernel()->locateResource('Foo');
356 * @expectedException \RuntimeException
358 public function testLocateResourceThrowsExceptionWhenNameIsUnsafe()
360 $this->getKernel()->locateResource('@FooBundle/../bar');
364 * @expectedException \InvalidArgumentException
366 public function testLocateResourceThrowsExceptionWhenBundleDoesNotExist()
368 $this->getKernel()->locateResource('@FooBundle/config/routing.xml');
372 * @expectedException \InvalidArgumentException
374 public function testLocateResourceThrowsExceptionWhenResourceDoesNotExist()
376 $kernel = $this->getKernel(array('getBundle'));
378 ->expects($this->once())
379 ->method('getBundle')
380 ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle'))))
383 $kernel->locateResource('@Bundle1Bundle/config/routing.xml');
386 public function testLocateResourceReturnsTheFirstThatMatches()
388 $kernel = $this->getKernel(array('getBundle'));
390 ->expects($this->once())
391 ->method('getBundle')
392 ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle'))))
395 $this->assertEquals(__DIR__.'/Fixtures/Bundle1Bundle/foo.txt', $kernel->locateResource('@Bundle1Bundle/foo.txt'));
398 public function testLocateResourceReturnsTheFirstThatMatchesWithParent()
400 $parent = $this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle');
401 $child = $this->getBundle(__DIR__.'/Fixtures/Bundle2Bundle');
403 $kernel = $this->getKernel(array('getBundle'));
405 ->expects($this->exactly(2))
406 ->method('getBundle')
407 ->will($this->returnValue(array($child, $parent)))
410 $this->assertEquals(__DIR__.'/Fixtures/Bundle2Bundle/foo.txt', $kernel->locateResource('@ParentAABundle/foo.txt'));
411 $this->assertEquals(__DIR__.'/Fixtures/Bundle1Bundle/bar.txt', $kernel->locateResource('@ParentAABundle/bar.txt'));
414 public function testLocateResourceReturnsAllMatches()
416 $parent = $this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle');
417 $child = $this->getBundle(__DIR__.'/Fixtures/Bundle2Bundle');
419 $kernel = $this->getKernel(array('getBundle'));
421 ->expects($this->once())
422 ->method('getBundle')
423 ->will($this->returnValue(array($child, $parent)))
426 $this->assertEquals(array(
427 __DIR__.'/Fixtures/Bundle2Bundle/foo.txt',
428 __DIR__.'/Fixtures/Bundle1Bundle/foo.txt', ),
429 $kernel->locateResource('@Bundle1Bundle/foo.txt', null, false));
432 public function testLocateResourceReturnsAllMatchesBis()
434 $kernel = $this->getKernel(array('getBundle'));
436 ->expects($this->once())
437 ->method('getBundle')
438 ->will($this->returnValue(array(
439 $this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle'),
440 $this->getBundle(__DIR__.'/Foobar'),
445 array(__DIR__.'/Fixtures/Bundle1Bundle/foo.txt'),
446 $kernel->locateResource('@Bundle1Bundle/foo.txt', null, false)
450 public function testLocateResourceIgnoresDirOnNonResource()
452 $kernel = $this->getKernel(array('getBundle'));
454 ->expects($this->once())
455 ->method('getBundle')
456 ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle'))))
460 __DIR__.'/Fixtures/Bundle1Bundle/foo.txt',
461 $kernel->locateResource('@Bundle1Bundle/foo.txt', __DIR__.'/Fixtures')
465 public function testLocateResourceReturnsTheDirOneForResources()
467 $kernel = $this->getKernel(array('getBundle'));
469 ->expects($this->once())
470 ->method('getBundle')
471 ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/FooBundle', null, null, 'FooBundle'))))
475 __DIR__.'/Fixtures/Resources/FooBundle/foo.txt',
476 $kernel->locateResource('@FooBundle/Resources/foo.txt', __DIR__.'/Fixtures/Resources')
480 public function testLocateResourceReturnsTheDirOneForResourcesAndBundleOnes()
482 $kernel = $this->getKernel(array('getBundle'));
484 ->expects($this->once())
485 ->method('getBundle')
486 ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle', null, null, 'Bundle1Bundle'))))
489 $this->assertEquals(array(
490 __DIR__.'/Fixtures/Resources/Bundle1Bundle/foo.txt',
491 __DIR__.'/Fixtures/Bundle1Bundle/Resources/foo.txt', ),
492 $kernel->locateResource('@Bundle1Bundle/Resources/foo.txt', __DIR__.'/Fixtures/Resources', false)
496 public function testLocateResourceOverrideBundleAndResourcesFolders()
498 $parent = $this->getBundle(__DIR__.'/Fixtures/BaseBundle', null, 'BaseBundle', 'BaseBundle');
499 $child = $this->getBundle(__DIR__.'/Fixtures/ChildBundle', 'ParentBundle', 'ChildBundle', 'ChildBundle');
501 $kernel = $this->getKernel(array('getBundle'));
503 ->expects($this->exactly(4))
504 ->method('getBundle')
505 ->will($this->returnValue(array($child, $parent)))
508 $this->assertEquals(array(
509 __DIR__.'/Fixtures/Resources/ChildBundle/foo.txt',
510 __DIR__.'/Fixtures/ChildBundle/Resources/foo.txt',
511 __DIR__.'/Fixtures/BaseBundle/Resources/foo.txt',
513 $kernel->locateResource('@BaseBundle/Resources/foo.txt', __DIR__.'/Fixtures/Resources', false)
517 __DIR__.'/Fixtures/Resources/ChildBundle/foo.txt',
518 $kernel->locateResource('@BaseBundle/Resources/foo.txt', __DIR__.'/Fixtures/Resources')
522 $kernel->locateResource('@BaseBundle/Resources/hide.txt', __DIR__.'/Fixtures/Resources', false);
523 $this->fail('Hidden resources should raise an exception when returning an array of matching paths');
524 } catch (\RuntimeException $e) {
528 $kernel->locateResource('@BaseBundle/Resources/hide.txt', __DIR__.'/Fixtures/Resources', true);
529 $this->fail('Hidden resources should raise an exception when returning the first matching path');
530 } catch (\RuntimeException $e) {
534 public function testLocateResourceOnDirectories()
536 $kernel = $this->getKernel(array('getBundle'));
538 ->expects($this->exactly(2))
539 ->method('getBundle')
540 ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/FooBundle', null, null, 'FooBundle'))))
544 __DIR__.'/Fixtures/Resources/FooBundle/',
545 $kernel->locateResource('@FooBundle/Resources/', __DIR__.'/Fixtures/Resources')
548 __DIR__.'/Fixtures/Resources/FooBundle',
549 $kernel->locateResource('@FooBundle/Resources', __DIR__.'/Fixtures/Resources')
552 $kernel = $this->getKernel(array('getBundle'));
554 ->expects($this->exactly(2))
555 ->method('getBundle')
556 ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle', null, null, 'Bundle1Bundle'))))
560 __DIR__.'/Fixtures/Bundle1Bundle/Resources/',
561 $kernel->locateResource('@Bundle1Bundle/Resources/')
564 __DIR__.'/Fixtures/Bundle1Bundle/Resources',
565 $kernel->locateResource('@Bundle1Bundle/Resources')
569 public function testInitializeBundles()
571 $parent = $this->getBundle(null, null, 'ParentABundle');
572 $child = $this->getBundle(null, 'ParentABundle', 'ChildABundle');
574 // use test kernel so we can access getBundleMap()
575 $kernel = $this->getKernelForTest(array('registerBundles'));
577 ->expects($this->once())
578 ->method('registerBundles')
579 ->will($this->returnValue(array($parent, $child)))
583 $map = $kernel->getBundleMap();
584 $this->assertEquals(array($child, $parent), $map['ParentABundle']);
587 public function testInitializeBundlesSupportInheritanceCascade()
589 $grandparent = $this->getBundle(null, null, 'GrandParentBBundle');
590 $parent = $this->getBundle(null, 'GrandParentBBundle', 'ParentBBundle');
591 $child = $this->getBundle(null, 'ParentBBundle', 'ChildBBundle');
593 // use test kernel so we can access getBundleMap()
594 $kernel = $this->getKernelForTest(array('registerBundles'));
596 ->expects($this->once())
597 ->method('registerBundles')
598 ->will($this->returnValue(array($grandparent, $parent, $child)))
602 $map = $kernel->getBundleMap();
603 $this->assertEquals(array($child, $parent, $grandparent), $map['GrandParentBBundle']);
604 $this->assertEquals(array($child, $parent), $map['ParentBBundle']);
605 $this->assertEquals(array($child), $map['ChildBBundle']);
609 * @expectedException \LogicException
610 * @expectedExceptionMessage Bundle "ChildCBundle" extends bundle "FooBar", which is not registered.
612 public function testInitializeBundlesThrowsExceptionWhenAParentDoesNotExists()
614 $child = $this->getBundle(null, 'FooBar', 'ChildCBundle');
615 $kernel = $this->getKernel(array(), array($child));
619 public function testInitializeBundlesSupportsArbitraryBundleRegistrationOrder()
621 $grandparent = $this->getBundle(null, null, 'GrandParentCBundle');
622 $parent = $this->getBundle(null, 'GrandParentCBundle', 'ParentCBundle');
623 $child = $this->getBundle(null, 'ParentCBundle', 'ChildCBundle');
625 // use test kernel so we can access getBundleMap()
626 $kernel = $this->getKernelForTest(array('registerBundles'));
628 ->expects($this->once())
629 ->method('registerBundles')
630 ->will($this->returnValue(array($parent, $grandparent, $child)))
634 $map = $kernel->getBundleMap();
635 $this->assertEquals(array($child, $parent, $grandparent), $map['GrandParentCBundle']);
636 $this->assertEquals(array($child, $parent), $map['ParentCBundle']);
637 $this->assertEquals(array($child), $map['ChildCBundle']);
641 * @expectedException \LogicException
642 * @expectedExceptionMessage Bundle "ParentCBundle" is directly extended by two bundles "ChildC2Bundle" and "ChildC1Bundle".
644 public function testInitializeBundlesThrowsExceptionWhenABundleIsDirectlyExtendedByTwoBundles()
646 $parent = $this->getBundle(null, null, 'ParentCBundle');
647 $child1 = $this->getBundle(null, 'ParentCBundle', 'ChildC1Bundle');
648 $child2 = $this->getBundle(null, 'ParentCBundle', 'ChildC2Bundle');
650 $kernel = $this->getKernel(array(), array($parent, $child1, $child2));
655 * @expectedException \LogicException
656 * @expectedExceptionMessage Trying to register two bundles with the same name "DuplicateName"
658 public function testInitializeBundleThrowsExceptionWhenRegisteringTwoBundlesWithTheSameName()
660 $fooBundle = $this->getBundle(null, null, 'FooBundle', 'DuplicateName');
661 $barBundle = $this->getBundle(null, null, 'BarBundle', 'DuplicateName');
663 $kernel = $this->getKernel(array(), array($fooBundle, $barBundle));
668 * @expectedException \LogicException
669 * @expectedExceptionMessage Bundle "CircularRefBundle" can not extend itself.
671 public function testInitializeBundleThrowsExceptionWhenABundleExtendsItself()
673 $circularRef = $this->getBundle(null, 'CircularRefBundle', 'CircularRefBundle');
675 $kernel = $this->getKernel(array(), array($circularRef));
679 public function testTerminateReturnsSilentlyIfKernelIsNotBooted()
681 $kernel = $this->getKernel(array('getHttpKernel'));
682 $kernel->expects($this->never())
683 ->method('getHttpKernel');
685 $kernel->terminate(Request::create('/'), new Response());
688 public function testTerminateDelegatesTerminationOnlyForTerminableInterface()
690 // does not implement TerminableInterface
691 $httpKernel = new TestKernel();
693 $kernel = $this->getKernel(array('getHttpKernel'));
694 $kernel->expects($this->once())
695 ->method('getHttpKernel')
696 ->willReturn($httpKernel);
699 $kernel->terminate(Request::create('/'), new Response());
701 $this->assertFalse($httpKernel->terminateCalled, 'terminate() is never called if the kernel class does not implement TerminableInterface');
703 // implements TerminableInterface
704 $httpKernelMock = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernel')
705 ->disableOriginalConstructor()
706 ->setMethods(array('terminate'))
710 ->expects($this->once())
711 ->method('terminate');
713 $kernel = $this->getKernel(array('getHttpKernel'));
714 $kernel->expects($this->exactly(2))
715 ->method('getHttpKernel')
716 ->will($this->returnValue($httpKernelMock));
719 $kernel->terminate(Request::create('/'), new Response());
722 public function testKernelRootDirNameStartingWithANumber()
724 $dir = __DIR__.'/Fixtures/123';
725 require_once $dir.'/Kernel123.php';
726 $kernel = new \Symfony\Component\HttpKernel\Tests\Fixtures\_123\Kernel123('dev', true);
727 $this->assertEquals('_123', $kernel->getName());
731 * Returns a mock for the BundleInterface.
733 * @return BundleInterface
735 protected function getBundle($dir = null, $parent = null, $className = null, $bundleName = null)
738 ->getMockBuilder('Symfony\Component\HttpKernel\Bundle\BundleInterface')
739 ->setMethods(array('getPath', 'getParent', 'getName'))
740 ->disableOriginalConstructor()
744 $bundle->setMockClassName($className);
747 $bundle = $bundle->getMockForAbstractClass();
750 ->expects($this->any())
752 ->will($this->returnValue(null === $bundleName ? get_class($bundle) : $bundleName))
756 ->expects($this->any())
758 ->will($this->returnValue($dir))
762 ->expects($this->any())
763 ->method('getParent')
764 ->will($this->returnValue($parent))
771 * Returns a mock for the abstract kernel.
773 * @param array $methods Additional methods to mock (besides the abstract ones)
774 * @param array $bundles Bundles to register
778 protected function getKernel(array $methods = array(), array $bundles = array())
780 $methods[] = 'registerBundles';
783 ->getMockBuilder('Symfony\Component\HttpKernel\Kernel')
784 ->setMethods($methods)
785 ->setConstructorArgs(array('test', false))
786 ->getMockForAbstractClass()
788 $kernel->expects($this->any())
789 ->method('registerBundles')
790 ->will($this->returnValue($bundles))
792 $p = new \ReflectionProperty($kernel, 'rootDir');
793 $p->setAccessible(true);
794 $p->setValue($kernel, __DIR__.'/Fixtures');
799 protected function getKernelForTest(array $methods = array())
801 $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\Tests\Fixtures\KernelForTest')
802 ->setConstructorArgs(array('test', false))
803 ->setMethods($methods)
805 $p = new \ReflectionProperty($kernel, 'rootDir');
806 $p->setAccessible(true);
807 $p->setValue($kernel, __DIR__.'/Fixtures');
813 class TestKernel implements HttpKernelInterface
815 public $terminateCalled = false;
817 public function terminate()
819 $this->terminateCalled = true;
822 public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true)