View source
<?php
namespace Symfony\Component\DependencyInjection\Tests\Loader;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\ExpressionLanguage\Expression;
class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase {
protected static $fixturesPath;
public static function setUpBeforeClass() {
self::$fixturesPath = realpath(__DIR__ . '/../Fixtures/');
require_once self::$fixturesPath . '/includes/foo.php';
require_once self::$fixturesPath . '/includes/ProjectExtension.php';
}
public function testLoadFile() {
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath . '/ini'));
$r = new \ReflectionObject($loader);
$m = $r
->getMethod('loadFile');
$m
->setAccessible(true);
try {
$m
->invoke($loader, 'foo.yml');
$this
->fail('->load() throws an InvalidArgumentException if the loaded file does not exist');
} catch (\Exception $e) {
$this
->assertInstanceOf('\\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file does not exist');
$this
->assertEquals('The service file "foo.yml" is not valid.', $e
->getMessage(), '->load() throws an InvalidArgumentException if the loaded file does not exist');
}
try {
$m
->invoke($loader, 'parameters.ini');
$this
->fail('->load() throws an InvalidArgumentException if the loaded file is not a valid YAML file');
} catch (\Exception $e) {
$this
->assertInstanceOf('\\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file is not a valid YAML file');
$this
->assertEquals('The service file "parameters.ini" is not valid.', $e
->getMessage(), '->load() throws an InvalidArgumentException if the loaded file is not a valid YAML file');
}
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath . '/yaml'));
foreach (array(
'nonvalid1',
'nonvalid2',
) as $fixture) {
try {
$m
->invoke($loader, $fixture . '.yml');
$this
->fail('->load() throws an InvalidArgumentException if the loaded file does not validate');
} catch (\Exception $e) {
$this
->assertInstanceOf('\\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file does not validate');
$this
->assertStringMatchesFormat('The service file "nonvalid%d.yml" is not valid.', $e
->getMessage(), '->load() throws an InvalidArgumentException if the loaded file does not validate');
}
}
}
public function testLoadInvalidFile($file) {
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath . '/yaml'));
$loader
->load($file . '.yml');
}
public function provideInvalidFiles() {
return array(
array(
'bad_parameters',
),
array(
'bad_imports',
),
array(
'bad_import',
),
array(
'bad_services',
),
array(
'bad_service',
),
array(
'bad_calls',
),
);
}
public function testLoadParameters() {
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath . '/yaml'));
$loader
->load('services2.yml');
$this
->assertEquals(array(
'foo' => 'bar',
'mixedcase' => array(
'MixedCaseKey' => 'value',
),
'values' => array(
true,
false,
0,
1000.3,
),
'bar' => 'foo',
'escape' => '@escapeme',
'foo_bar' => new Reference('foo_bar'),
), $container
->getParameterBag()
->all(), '->load() converts YAML keys to lowercase');
}
public function testLoadImports() {
$container = new ContainerBuilder();
$resolver = new LoaderResolver(array(
new IniFileLoader($container, new FileLocator(self::$fixturesPath . '/yaml')),
new XmlFileLoader($container, new FileLocator(self::$fixturesPath . '/yaml')),
new PhpFileLoader($container, new FileLocator(self::$fixturesPath . '/php')),
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath . '/yaml')),
));
$loader
->setResolver($resolver);
$loader
->load('services4.yml');
$actual = $container
->getParameterBag()
->all();
$expected = array(
'foo' => 'bar',
'values' => array(
true,
false,
),
'bar' => '%foo%',
'escape' => '@escapeme',
'foo_bar' => new Reference('foo_bar'),
'mixedcase' => array(
'MixedCaseKey' => 'value',
),
'imported_from_ini' => true,
'imported_from_xml' => true,
);
$this
->assertEquals(array_keys($expected), array_keys($actual), '->load() imports and merges imported files');
$loader
->load('services4_bad_import.yml');
}
public function testLegacyLoadServices() {
$this
->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath . '/yaml'));
$loader
->load('legacy-services6.yml');
$services = $container
->getDefinitions();
$this
->assertEquals('FooClass', $services['constructor']
->getClass());
$this
->assertEquals('getInstance', $services['constructor']
->getFactoryMethod());
$this
->assertEquals('BazClass', $services['factory_service']
->getClass());
$this
->assertEquals('baz_factory', $services['factory_service']
->getFactoryService());
$this
->assertEquals('getInstance', $services['factory_service']
->getFactoryMethod());
$this
->assertTrue($services['request']
->isSynthetic(), '->load() parses the synthetic flag');
$this
->assertTrue($services['request']
->isSynchronized(), '->load() parses the synchronized flag');
$this
->assertTrue($services['request']
->isLazy(), '->load() parses the lazy flag');
$this
->assertNull($services['request']
->getDecoratedService());
}
public function testLoadServices() {
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath . '/yaml'));
$loader
->load('services6.yml');
$services = $container
->getDefinitions();
$this
->assertTrue(isset($services['foo']), '->load() parses service elements');
$this
->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Definition', $services['foo'], '->load() converts service element to Definition instances');
$this
->assertEquals('FooClass', $services['foo']
->getClass(), '->load() parses the class attribute');
$this
->assertEquals('container', $services['scope.container']
->getScope());
$this
->assertEquals('custom', $services['scope.custom']
->getScope());
$this
->assertEquals('prototype', $services['scope.prototype']
->getScope());
$this
->assertEquals('%path%/foo.php', $services['file']
->getFile(), '->load() parses the file tag');
$this
->assertEquals(array(
'foo',
new Reference('foo'),
array(
true,
false,
),
), $services['arguments']
->getArguments(), '->load() parses the argument tags');
$this
->assertEquals('sc_configure', $services['configurator1']
->getConfigurator(), '->load() parses the configurator tag');
$this
->assertEquals(array(
new Reference('baz'),
'configure',
), $services['configurator2']
->getConfigurator(), '->load() parses the configurator tag');
$this
->assertEquals(array(
'BazClass',
'configureStatic',
), $services['configurator3']
->getConfigurator(), '->load() parses the configurator tag');
$this
->assertEquals(array(
array(
'setBar',
array(),
),
array(
'setBar',
array(),
),
array(
'setBar',
array(
new Expression('service("foo").foo() ~ (container.hasparameter("foo") ? parameter("foo") : "default")'),
),
),
), $services['method_call1']
->getMethodCalls(), '->load() parses the method_call tag');
$this
->assertEquals(array(
array(
'setBar',
array(
'foo',
new Reference('foo'),
array(
true,
false,
),
),
),
), $services['method_call2']
->getMethodCalls(), '->load() parses the method_call tag');
$this
->assertEquals('factory', $services['new_factory1']
->getFactory(), '->load() parses the factory tag');
$this
->assertEquals(array(
new Reference('baz'),
'getClass',
), $services['new_factory2']
->getFactory(), '->load() parses the factory tag');
$this
->assertEquals(array(
'BazClass',
'getInstance',
), $services['new_factory3']
->getFactory(), '->load() parses the factory tag');
$aliases = $container
->getAliases();
$this
->assertTrue(isset($aliases['alias_for_foo']), '->load() parses aliases');
$this
->assertEquals('foo', (string) $aliases['alias_for_foo'], '->load() parses aliases');
$this
->assertTrue($aliases['alias_for_foo']
->isPublic());
$this
->assertTrue(isset($aliases['another_alias_for_foo']));
$this
->assertEquals('foo', (string) $aliases['another_alias_for_foo']);
$this
->assertFalse($aliases['another_alias_for_foo']
->isPublic());
$this
->assertEquals(array(
'decorated',
null,
), $services['decorator_service']
->getDecoratedService());
$this
->assertEquals(array(
'decorated',
'decorated.pif-pouf',
), $services['decorator_service_with_name']
->getDecoratedService());
}
public function testLoadFactoryShortSyntax() {
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath . '/yaml'));
$loader
->load('services14.yml');
$services = $container
->getDefinitions();
$this
->assertEquals(array(
new Reference('baz'),
'getClass',
), $services['factory']
->getFactory(), '->load() parses the factory tag with service:method');
$this
->assertEquals(array(
'FooBacFactory',
'createFooBar',
), $services['factory_with_static_call']
->getFactory(), '->load() parses the factory tag with Class::method');
}
public function testExtensions() {
$container = new ContainerBuilder();
$container
->registerExtension(new \ProjectExtension());
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath . '/yaml'));
$loader
->load('services10.yml');
$container
->compile();
$services = $container
->getDefinitions();
$parameters = $container
->getParameterBag()
->all();
$this
->assertTrue(isset($services['project.service.bar']), '->load() parses extension elements');
$this
->assertTrue(isset($parameters['project.parameter.bar']), '->load() parses extension elements');
$this
->assertEquals('BAR', $services['project.service.foo']
->getClass(), '->load() parses extension elements');
$this
->assertEquals('BAR', $parameters['project.parameter.foo'], '->load() parses extension elements');
try {
$loader
->load('services11.yml');
$this
->fail('->load() throws an InvalidArgumentException if the tag is not valid');
} catch (\Exception $e) {
$this
->assertInstanceOf('\\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the tag is not valid');
$this
->assertStringStartsWith('There is no extension able to load the configuration for "foobarfoobar" (in', $e
->getMessage(), '->load() throws an InvalidArgumentException if the tag is not valid');
}
}
public function testSupports() {
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator());
$this
->assertTrue($loader
->supports('foo.yml'), '->supports() returns true if the resource is loadable');
$this
->assertTrue($loader
->supports('foo.yaml'), '->supports() returns true if the resource is loadable');
$this
->assertFalse($loader
->supports('foo.foo'), '->supports() returns true if the resource is loadable');
}
public function testNonArrayTagsThrowsException() {
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath . '/yaml'));
try {
$loader
->load('badtag1.yml');
$this
->fail('->load() should throw an exception when the tags key of a service is not an array');
} catch (\Exception $e) {
$this
->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the tags key is not an array');
$this
->assertStringStartsWith('Parameter "tags" must be an array for service', $e
->getMessage(), '->load() throws an InvalidArgumentException if the tags key is not an array');
}
}
public function testNonArrayTagThrowsException() {
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath . '/yaml'));
$loader
->load('badtag4.yml');
}
public function testTagWithoutNameThrowsException() {
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath . '/yaml'));
try {
$loader
->load('badtag2.yml');
$this
->fail('->load() should throw an exception when a tag is missing the name key');
} catch (\Exception $e) {
$this
->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if a tag is missing the name key');
$this
->assertStringStartsWith('A "tags" entry is missing a "name" key for service ', $e
->getMessage(), '->load() throws an InvalidArgumentException if a tag is missing the name key');
}
}
public function testTagWithAttributeArrayThrowsException() {
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath . '/yaml'));
try {
$loader
->load('badtag3.yml');
$this
->fail('->load() should throw an exception when a tag-attribute is not a scalar');
} catch (\Exception $e) {
$this
->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if a tag-attribute is not a scalar');
$this
->assertStringStartsWith('A "tags" attribute must be of a scalar-type for service "foo_service", tag "foo", attribute "bar"', $e
->getMessage(), '->load() throws an InvalidArgumentException if a tag-attribute is not a scalar');
}
}
public function testLoadYamlOnlyWithKeys() {
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath . '/yaml'));
$loader
->load('services21.yml');
$definition = $container
->getDefinition('manager');
$this
->assertEquals(array(
array(
'setLogger',
array(
new Reference('logger'),
),
),
array(
'setClass',
array(
'User',
),
),
), $definition
->getMethodCalls());
$this
->assertEquals(array(
true,
), $definition
->getArguments());
$this
->assertEquals(array(
'manager' => array(
array(
'alias' => 'user',
),
),
), $definition
->getTags());
}
}