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\Compiler;
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\Config\Definition\Builder\TreeBuilder;
16 use Symfony\Component\Config\Definition\ConfigurationInterface;
17 use Symfony\Component\Config\Resource\FileResource;
18 use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationContainerBuilder;
19 use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPass;
20 use Symfony\Component\DependencyInjection\ContainerBuilder;
21 use Symfony\Component\DependencyInjection\Extension\Extension;
22 use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
24 class MergeExtensionConfigurationPassTest extends TestCase
26 public function testExpressionLanguageProviderForwarding()
28 $tmpProviders = array();
30 $extension = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface')->getMock();
31 $extension->expects($this->any())
32 ->method('getXsdValidationBasePath')
33 ->will($this->returnValue(false));
34 $extension->expects($this->any())
35 ->method('getNamespace')
36 ->will($this->returnValue('http://example.org/schema/dic/foo'));
37 $extension->expects($this->any())
39 ->will($this->returnValue('foo'));
40 $extension->expects($this->once())
42 ->will($this->returnCallback(function (array $config, ContainerBuilder $container) use (&$tmpProviders) {
43 $tmpProviders = $container->getExpressionLanguageProviders();
46 $provider = $this->getMockBuilder('Symfony\\Component\\ExpressionLanguage\\ExpressionFunctionProviderInterface')->getMock();
47 $container = new ContainerBuilder(new ParameterBag());
48 $container->registerExtension($extension);
49 $container->prependExtensionConfig('foo', array('bar' => true));
50 $container->addExpressionLanguageProvider($provider);
52 $pass = new MergeExtensionConfigurationPass();
53 $pass->process($container);
55 $this->assertEquals(array($provider), $tmpProviders);
58 public function testExtensionLoadGetAMergeExtensionConfigurationContainerBuilderInstance()
60 $extension = $this->getMockBuilder(FooExtension::class)->setMethods(array('load'))->getMock();
61 $extension->expects($this->once())
63 ->with($this->isType('array'), $this->isInstanceOf(MergeExtensionConfigurationContainerBuilder::class))
66 $container = new ContainerBuilder(new ParameterBag());
67 $container->registerExtension($extension);
68 $container->prependExtensionConfig('foo', array());
70 $pass = new MergeExtensionConfigurationPass();
71 $pass->process($container);
74 public function testExtensionConfigurationIsTrackedByDefault()
76 $extension = $this->getMockBuilder(FooExtension::class)->setMethods(array('getConfiguration'))->getMock();
77 $extension->expects($this->exactly(2))
78 ->method('getConfiguration')
79 ->will($this->returnValue(new FooConfiguration()));
81 $container = new ContainerBuilder(new ParameterBag());
82 $container->registerExtension($extension);
83 $container->prependExtensionConfig('foo', array('bar' => true));
85 $pass = new MergeExtensionConfigurationPass();
86 $pass->process($container);
88 $this->assertContains(new FileResource(__FILE__), $container->getResources(), '', false, false);
91 public function testOverriddenEnvsAreMerged()
93 $container = new ContainerBuilder();
94 $container->registerExtension(new FooExtension());
95 $container->prependExtensionConfig('foo', array('bar' => '%env(FOO)%'));
96 $container->prependExtensionConfig('foo', array('bar' => '%env(BAR)%', 'baz' => '%env(BAZ)%'));
98 $pass = new MergeExtensionConfigurationPass();
99 $pass->process($container);
101 $this->assertSame(array('BAZ', 'FOO'), array_keys($container->getParameterBag()->getEnvPlaceholders()));
102 $this->assertSame(array('BAZ' => 1, 'FOO' => 0), $container->getEnvCounters());
106 * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
107 * @expectedExceptionMessage Using a cast in "env(int:FOO)" is incompatible with resolution at compile time in "Symfony\Component\DependencyInjection\Tests\Compiler\BarExtension". The logic in the extension should be moved to a compiler pass, or an env parameter with no cast should be used instead.
109 public function testProcessedEnvsAreIncompatibleWithResolve()
111 $container = new ContainerBuilder();
112 $container->registerExtension(new BarExtension());
113 $container->prependExtensionConfig('bar', array());
115 (new MergeExtensionConfigurationPass())->process($container);
118 public function testThrowingExtensionsGetMergedBag()
120 $container = new ContainerBuilder();
121 $container->registerExtension(new ThrowingExtension());
122 $container->prependExtensionConfig('throwing', array('bar' => '%env(FOO)%'));
125 $pass = new MergeExtensionConfigurationPass();
126 $pass->process($container);
127 $this->fail('An exception should have been thrown.');
128 } catch (\Exception $e) {
131 $this->assertSame(array('FOO'), array_keys($container->getParameterBag()->getEnvPlaceholders()));
135 class FooConfiguration implements ConfigurationInterface
137 public function getConfigTreeBuilder()
139 $treeBuilder = new TreeBuilder();
140 $rootNode = $treeBuilder->root('foo');
143 ->scalarNode('bar')->end()
144 ->scalarNode('baz')->end()
151 class FooExtension extends Extension
153 public function getAlias()
158 public function getConfiguration(array $config, ContainerBuilder $container)
160 return new FooConfiguration();
163 public function load(array $configs, ContainerBuilder $container)
165 $configuration = $this->getConfiguration($configs, $container);
166 $config = $this->processConfiguration($configuration, $configs);
168 if (isset($config['baz'])) {
169 $container->getParameterBag()->get('env(BOZ)');
170 $container->resolveEnvPlaceholders($config['baz']);
175 class BarExtension extends Extension
177 public function load(array $configs, ContainerBuilder $container)
179 $container->resolveEnvPlaceholders('%env(int:FOO)%', true);
183 class ThrowingExtension extends Extension
185 public function getAlias()
190 public function getConfiguration(array $config, ContainerBuilder $container)
192 return new FooConfiguration();
195 public function load(array $configs, ContainerBuilder $container)
197 throw new \Exception();