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\DependencyInjection\Tests\Loader;
14 use Psr\Container\ContainerInterface as PsrContainerInterface;
15 use PHPUnit\Framework\TestCase;
16 use Symfony\Component\Config\FileLocator;
17 use Symfony\Component\Config\Loader\LoaderResolver;
18 use Symfony\Component\DependencyInjection\ContainerBuilder;
19 use Symfony\Component\DependencyInjection\ContainerInterface;
20 use Symfony\Component\DependencyInjection\Definition;
21 use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
22 use Symfony\Component\DependencyInjection\Loader\FileLoader;
23 use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
24 use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
25 use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
26 use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
27 use Symfony\Component\DependencyInjection\Reference;
28 use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\BadClasses\MissingParent;
29 use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\AnotherSub\DeeperBaz;
30 use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\Baz;
31 use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo;
32 use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\FooInterface;
33 use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar;
34 use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\BarInterface;
36 class FileLoaderTest extends TestCase
38 protected static $fixturesPath;
40 public static function setUpBeforeClass()
42 self::$fixturesPath = realpath(__DIR__.'/../');
45 public function testImportWithGlobPattern()
47 $container = new ContainerBuilder();
48 $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath));
50 $resolver = new LoaderResolver(array(
51 new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/ini')),
52 new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')),
53 new PhpFileLoader($container, new FileLocator(self::$fixturesPath.'/php')),
54 new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')),
57 $loader->setResolver($resolver);
58 $loader->import('{F}ixtures/{xml,yaml}/services2.{yml,xml}');
60 $actual = $container->getParameterBag()->all();
78 'mixedcase' => array('MixedCaseKey' => 'value'),
79 'constant' => PHP_EOL,
81 'escape' => '@escapeme',
82 'foo_bar' => new Reference('foo_bar'),
85 $this->assertEquals(array_keys($expected), array_keys($actual), '->load() imports and merges imported files');
88 public function testRegisterClasses()
90 $container = new ContainerBuilder();
91 $container->setParameter('sub_dir', 'Sub');
92 $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures'));
94 $loader->registerClasses(new Definition(), 'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\\', 'Prototype/%sub_dir%/*');
97 array('service_container', Bar::class),
98 array_keys($container->getDefinitions())
102 PsrContainerInterface::class,
103 ContainerInterface::class,
106 array_keys($container->getAliases())
110 public function testRegisterClassesWithExclude()
112 $container = new ContainerBuilder();
113 $container->setParameter('other_dir', 'OtherDir');
114 $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures'));
116 $loader->registerClasses(
118 'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\\',
120 // load everything, except OtherDir/AnotherSub & Foo.php
121 'Prototype/{%other_dir%/AnotherSub,Foo.php}'
124 $this->assertTrue($container->has(Bar::class));
125 $this->assertTrue($container->has(Baz::class));
126 $this->assertFalse($container->has(Foo::class));
127 $this->assertFalse($container->has(DeeperBaz::class));
131 PsrContainerInterface::class,
132 ContainerInterface::class,
135 array_keys($container->getAliases())
139 public function testNestedRegisterClasses()
141 $container = new ContainerBuilder();
142 $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures'));
144 $prototype = new Definition();
145 $prototype->setPublic(true)->setPrivate(true);
146 $loader->registerClasses($prototype, 'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\\', 'Prototype/*');
148 $this->assertTrue($container->has(Bar::class));
149 $this->assertTrue($container->has(Baz::class));
150 $this->assertTrue($container->has(Foo::class));
154 PsrContainerInterface::class,
155 ContainerInterface::class,
158 array_keys($container->getAliases())
161 $alias = $container->getAlias(FooInterface::class);
162 $this->assertSame(Foo::class, (string) $alias);
163 $this->assertFalse($alias->isPublic());
164 $this->assertFalse($alias->isPrivate());
167 public function testMissingParentClass()
169 $container = new ContainerBuilder();
170 $container->setParameter('bad_classes_dir', 'BadClasses');
171 $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures'));
173 $loader->registerClasses(
174 (new Definition())->setPublic(false),
175 'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\BadClasses\\',
176 'Prototype/%bad_classes_dir%/*'
179 $this->assertTrue($container->has(MissingParent::class));
182 array('While discovering services from namespace "Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\BadClasses\", an error was thrown when processing the class "Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\BadClasses\MissingParent": "Class Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\BadClasses\MissingClass not found".'),
183 $container->getDefinition(MissingParent::class)->getErrors()
188 * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
189 * @expectedExceptionMessageRegExp /Expected to find class "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\Prototype\\Bar" in file ".+" while importing services from resource "Prototype\/Sub\/\*", but it was not found\! Check the namespace prefix used with the resource/
191 public function testRegisterClassesWithBadPrefix()
193 $container = new ContainerBuilder();
194 $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures'));
196 // the Sub is missing from namespace prefix
197 $loader->registerClasses(new Definition(), 'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\\', 'Prototype/Sub/*');
201 * @dataProvider getIncompatibleExcludeTests
203 public function testRegisterClassesWithIncompatibleExclude($resourcePattern, $excludePattern)
205 $container = new ContainerBuilder();
206 $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures'));
209 $loader->registerClasses(
211 'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\\',
215 } catch (InvalidArgumentException $e) {
217 sprintf('Invalid "exclude" pattern when importing classes for "Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\": make sure your "exclude" pattern (%s) is a subset of the "resource" pattern (%s)', $excludePattern, $resourcePattern),
223 public function getIncompatibleExcludeTests()
225 yield array('Prototype/*', 'yaml/*', false);
226 yield array('Prototype/OtherDir/*', 'Prototype/*', false);
230 class TestFileLoader extends FileLoader
232 public function load($resource, $type = null)
237 public function supports($resource, $type = null)