[FrameworkBundle] Implemented single-pass config loading with intelligent option merging for FrameworkExtension

Restructured config format to make processing more straightforward. Important changes that might break existing configs:

 * Added "enabled" option for translator (improves multi-format compat)
 * Removed hash variation of validation annotations option (only boolean)
 * Moved namespace option directly under validation (improves multi-format compat)

The new merge process depends on an internal array of all supported options and their default values, which is used for both validating the config schema and inferring how to merge options (as an added benefit, it helps make the extension self-documenting). Exceptions will now be thrown for merge errors resulting from unrecognized options or invalid types. Since incoming configurations are all merged atop the defaults, many isset() checks were removed. As a rule of thumb, we probably only want to ignore null values when an option would be used to set a parameter.

Also:

 * Added missing attributes to symfony-1.0.xsd
   * profiler: added only-exceptions attribute
   * session: fix types and add pdo attributes
 * Create FrameworkExtension tests with PHP/XML/YAML fixtures
 * Use "%" syntax instead of calling getParameter() within FrameworkExtension
 * Normalize config keys and arrays with helper methods for PHP/XML/YAML compatibility

Earlier changes:

 * Remove nonexistent "DependencyInjection/Resources/" path from XmlFileLoaders
 * Remove hasDefinition() checks, as register methods should only execute once
 * Remove first-run logic from registerTranslatorConfiguration(), as it is only run once
 * Removed apparently obsolete clearTags() calls on definitions for non-enabled features
This commit is contained in:
Jeremy Mikola 2011-01-24 14:50:31 -05:00 committed by Fabien Potencier
parent 199e6bf893
commit f9138d313b
15 changed files with 914 additions and 463 deletions

View File

@ -9,34 +9,50 @@
<xsd:complexType name="config">
<xsd:all>
<xsd:element name="router" type="router" minOccurs="0" maxOccurs="1" />
<xsd:element name="validation" type="validation" minOccurs="0" maxOccurs="1" />
<xsd:element name="csrf-protection" type="csrf_protection" minOccurs="0" maxOccurs="1" />
<xsd:element name="esi" type="esi" minOccurs="0" maxOccurs="1" />
<xsd:element name="profiler" type="profiler" minOccurs="0" maxOccurs="1" />
<xsd:element name="router" type="router" minOccurs="0" maxOccurs="1" />
<xsd:element name="session" type="session" minOccurs="0" maxOccurs="1" />
<xsd:element name="templating" type="templating" minOccurs="0" maxOccurs="1" />
<xsd:element name="translator" type="translator" minOccurs="0" maxOccurs="1" />
<xsd:element name="csrf-protection" type="csrf_protection" minOccurs="0" maxOccurs="1" />
<xsd:element name="esi" type="esi" minOccurs="0" maxOccurs="1" />
<xsd:element name="validation" type="validation" minOccurs="0" maxOccurs="1" />
</xsd:all>
<xsd:attribute name="ide" type="xsd:string" />
<xsd:attribute name="cache-warmer" type="cache_warmer" />
<xsd:attribute name="charset" type="xsd:string" />
<xsd:attribute name="error-handler" type="xsd:string" />
<xsd:attribute name="cache-warmer" type="cache_warmer" />
<xsd:attribute name="ide" type="xsd:string" />
</xsd:complexType>
<xsd:simpleType name="cache_warmer">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="false" />
<xsd:enumeration value="true" />
<xsd:enumeration value="full" />
<xsd:enumeration value="true" />
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="csrf_protection">
<xsd:attribute name="enabled" type="xsd:boolean" />
<xsd:attribute name="field-name" type="xsd:string" />
<xsd:attribute name="secret" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="esi">
<xsd:attribute name="enabled" type="xsd:boolean" />
</xsd:complexType>
<xsd:complexType name="param_converter">
<xsd:attribute name="enabled" type="xsd:boolean" />
</xsd:complexType>
<xsd:complexType name="profiler">
<xsd:all>
<xsd:element name="matcher" type="profiler_matcher" minOccurs="0" maxOccurs="1" />
</xsd:all>
<xsd:attribute name="only-exceptions" type="xsd:boolean" />
</xsd:complexType>
<xsd:complexType name="profiler_matcher">
@ -51,11 +67,6 @@
<xsd:attribute name="cache-warmer" type="cache_warmer" />
</xsd:complexType>
<xsd:complexType name="validation">
<xsd:attribute name="enabled" type="xsd:boolean" />
<xsd:attribute name="annotations" type="xsd:boolean" />
</xsd:complexType>
<xsd:complexType name="session">
<xsd:attribute name="class" type="xsd:string" />
<xsd:attribute name="storage-id" type="xsd:string" />
@ -64,11 +75,14 @@
<xsd:attribute name="lifetime" type="xsd:integer" />
<xsd:attribute name="path" type="xsd:string" />
<xsd:attribute name="domain" type="xsd:string" />
<xsd:attribute name="secure" type="xsd:string" />
<xsd:attribute name="httponly" type="xsd:string" />
<xsd:attribute name="secure" type="xsd:boolean" />
<xsd:attribute name="httponly" type="xsd:boolean" />
<xsd:attribute name="cache-limiter" type="xsd:string" />
<xsd:attribute name="auto-start" type="xsd:boolean" />
<xsd:attribute name="pdo.db-table" type="xsd:string" />
<xsd:attribute name="pdo.db-id-col" type="xsd:string" />
<xsd:attribute name="pdo.db-data-col" type="xsd:string" />
<xsd:attribute name="pdo.db-time-col" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="templating">
@ -83,21 +97,26 @@
<xsd:attribute name="cache-warmer" type="cache_warmer" />
</xsd:complexType>
<xsd:complexType name="translator">
<xsd:attribute name="fallback" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="csrf_protection">
<xsd:attribute name="enabled" type="xsd:boolean" />
<xsd:attribute name="field-name" type="xsd:string" />
<xsd:attribute name="secret" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="esi">
<xsd:attribute name="enabled" type="xsd:boolean" />
</xsd:complexType>
<xsd:complexType name="templating_engine">
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="translator">
<xsd:attribute name="enabled" type="xsd:boolean" />
<xsd:attribute name="fallback" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="validation">
<xsd:sequence>
<xsd:element name="namespace" type="validation_namespace" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
<xsd:attribute name="enabled" type="xsd:boolean" />
<xsd:attribute name="annotations" type="xsd:boolean" />
</xsd:complexType>
<xsd:complexType name="validation_namespace">
<xsd:attribute name="prefix" type="xsd:string" />
<xsd:attribute name="namespace" type="xsd:string" />
</xsd:complexType>
</xsd:schema>

View File

@ -0,0 +1,45 @@
<?php
$container->loadFromExtension('app', 'config', array(
'csrf_protection' => array(
'enabled' => true,
'field_name' => '_csrf',
'secret' => 's3cr3t',
),
'esi' => array(
'enabled' => true,
),
'profiler' => array(
'only_exceptions' => true,
),
'router' => array(
'resource' => '%kernel.root_dir%/config/routing.xml',
'cache_warmer' => true,
),
'session' => array(
'auto_start' => true,
'class' => 'Session',
'default_locale' => 'fr',
'storage_id' => 'native',
'name' => '_SYMFONY',
'lifetime' => 86400,
'path' => '/',
'domain' => 'example.com',
'secure' => true,
'httponly' => true,
),
'templating' => array(
'assets_version' => 'SomeVersionScheme',
'assets_base_urls' => 'http://cdn.example.com',
'cache_warmer' => true,
'engines' => array('php', 'twig'),
'loader' => array('loader.foo', 'loader.bar'),
),
'translator' => array(
'enabled' => true,
'fallback' => 'fr',
),
'validation' => array(
'enabled' => true,
),
));

View File

@ -0,0 +1,17 @@
<?php
$container->loadFromExtension('app', 'config', array(
'router' => array(
'resource' => '%kernel.root_dir%/config/routing.xml',
),
'session' => array(
'storage_id' => 'pdo',
'pdo.db_table' => 'table',
'pdo.db_id_col' => 'id',
'pdo.db_data_col' => 'data',
'pdo.db_time_col' => 'time',
),
'templating' => array(
'engine' => 'php'
),
));

View File

@ -0,0 +1,17 @@
<?php
$container->loadFromExtension('app', 'config', array(
'router' => array(
'resource' => '%kernel.root_dir%/config/routing.xml',
),
'validation' => array(
'enabled' => true,
'annotations' => true,
'namespaces' => array(
'app' => 'Application\\Validator\\Constraints\\',
),
),
'templating' => array(
'engine' => 'php'
),
));

View File

@ -0,0 +1,24 @@
<?xml version="1.0" ?>
<container xmlns="http://www.symfony-project.org/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:app="http://www.symfony-project.org/schema/dic/symfony"
xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd
http://www.symfony-project.org/schema/dic/symfony http://www.symfony-project.org/schema/dic/symfony/symfony-1.0.xsd">
<app:config>
<app:csrf-protection enabled="true" field-name="_csrf" secret="s3cr3t" />
<app:esi enabled="true" />
<app:profiler only-exceptions="true" />
<app:router resource="%kernel.root_dir%/config/routing.xml" cache-warmer="true" />
<app:session auto-start="true" class="Session" default-locale="fr" storage-id="native" name="_SYMFONY" lifetime="86400" path="/" domain="example.com" secure="true" httponly="true" />
<app:templating assets-version="SomeVersionScheme" assets-base-urls="http://cdn.example.com" cache-warmer="true">
<app:loader>loader.foo</app:loader>
<app:loader>loader.bar</app:loader>
<app:engine id="php" />
<app:engine id="twig" />
</app:templating>
<app:translator enabled="true" fallback="fr" />
<app:validation enabled="true" />
</app:config>
</container>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" ?>
<container xmlns="http://www.symfony-project.org/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:app="http://www.symfony-project.org/schema/dic/symfony"
xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd
http://www.symfony-project.org/schema/dic/symfony http://www.symfony-project.org/schema/dic/symfony/symfony-1.0.xsd">
<app:config>
<app:router resource="%kernel.root_dir%/config/routing.xml" />
<app:session storage-id="pdo" pdo.db-table="table" pdo.db-id-col="id" pdo.db-data-col="data" pdo.db-time-col="time" />
<app:templating>
<app:engine id="php" />
</app:templating>
</app:config>
</container>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" ?>
<container xmlns="http://www.symfony-project.org/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:app="http://www.symfony-project.org/schema/dic/symfony"
xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd
http://www.symfony-project.org/schema/dic/symfony http://www.symfony-project.org/schema/dic/symfony/symfony-1.0.xsd">
<app:config>
<app:router resource="%kernel.root_dir%/config/routing.xml" />
<app:validation enabled="true" annotations="true">
<app:namespace prefix="app" namespace="Application\Validator\Constraints\" />
</app:validation>
<app:templating>
<app:engine id="php" />
</app:templating>
</app:config>
</container>

View File

@ -0,0 +1,34 @@
app.config:
csrf_protection:
enabled: true
field_name: _csrf
secret: s3cr3t
esi:
enabled: true
profiler:
only_exceptions: true
router:
resource: %kernel.root_dir%/config/routing.xml
cache_warmer: true
session:
auto_start: true
class: Session
default_locale: fr
storage_id: native
name: _SYMFONY
lifetime: 86400
path: /
domain: example.com
secure: true
httponly: true
templating:
assets_version: SomeVersionScheme
assets_base_urls: http://cdn.example.com
cache_warmer: true
engines: [php, twig]
loader: [loader.foo, loader.bar]
translator:
enabled: true,
fallback: fr
validation:
enabled: true

View File

@ -0,0 +1,11 @@
app.config:
router:
resource: %kernel.root_dir%/config/routing.xml
session:
storage_id: pdo
pdo.db_table: table
pdo.db_id_col: id
pdo.db_data_col: data
pdo.db_time_col: time
templating:
engine: php

View File

@ -0,0 +1,10 @@
app.config:
router:
resource: %kernel.root_dir%/config/routing.xml
validation:
enabled: true
annotations: true
namespaces:
app: Application\Validator\Constraints\
templating:
engine: php

View File

@ -16,43 +16,182 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
class FrameworkExtensionTest extends TestCase
abstract class FrameworkExtensionTest extends TestCase
{
public function testConfigLoad()
abstract protected function loadFromFile(ContainerBuilder $container, $file);
public function testCsrfProtection()
{
$container = $this->getContainer();
$loader = new FrameworkExtension();
$container = $this->createContainerFromFile('full');
$loader->configLoad(array(array()), $container);
$this->assertEquals('Symfony\\Bundle\\FrameworkBundle\\RequestListener', $container->getParameter('request_listener.class'), '->webLoad() loads the web.xml file if not already loaded');
$container = $this->getContainer();
$loader = new FrameworkExtension();
// profiler
$loader->configLoad(array(array('profiler' => true)), $container);
$this->assertEquals('Symfony\Component\HttpKernel\Profiler\Profiler', $container->getParameter('profiler.class'), '->configLoad() loads the collectors.xml file if not already loaded');
// templating
$loader->configLoad(array(array('templating' => array('engines' => array('php')))), $container);
$this->assertEquals('Symfony\\Bundle\\FrameworkBundle\\Templating\\PhpEngine', $container->getParameter('templating.engine.php.class'), '->templatingLoad() loads the templating.xml file if not already loaded');
// validation
$loader->configLoad(array(array('validation' => array('enabled' => true))), $container);
$this->assertEquals('Symfony\Component\Validator\Validator', $container->getParameter('validator.class'), '->validationLoad() loads the validation.xml file if not already loaded');
$this->assertFalse($container->hasDefinition('validator.mapping.loader.annotation_loader'), '->validationLoad() doesn\'t load the annotations service unless its needed');
$loader->configLoad(array(array('validation' => array('enabled' => true, 'annotations' => true))), $container);
$this->assertTrue($container->hasDefinition('validator.mapping.loader.annotation_loader'), '->validationLoad() loads the annotations service');
$this->assertTrue($container->getParameter('form.csrf_protection.enabled'));
$this->assertEquals('_csrf', $container->getParameter('form.csrf_protection.field_name'));
$this->assertEquals('s3cr3t', $container->getParameter('form.csrf_protection.secret'));
}
protected function getContainer()
public function testEsi()
{
$container = $this->createContainerFromFile('full');
$this->assertTrue($container->hasDefinition('esi'), '->registerEsiConfiguration() loads esi.xml');
}
public function testProfiler()
{
$container = $this->createContainerFromFile('full');
$this->assertTrue($container->hasDefinition('profiler'), '->registerProfilerConfiguration() loads profiling.xml');
$this->assertTrue($container->hasDefinition('data_collector.config'), '->registerProfilerConfiguration() loads collectors.xml');
$this->assertTrue($container->getParameter('profiler_listener.only_exceptions'));
}
public function testRouter()
{
$container = $this->createContainerFromFile('full');
$this->assertTrue($container->hasDefinition('router.real'), '->registerRouterConfiguration() loads routing.xml');
$this->assertEquals($container->getParameter('kernel.root_dir').'/config/routing.xml', $container->getParameter('routing.resource'), '->registerRouterConfiguration() sets routing resource');
$this->assertTrue($container->getDefinition('router.cache_warmer')->hasTag('kernel.cache_warmer'), '->registerRouterConfiguration() tags router cache warmer if cache warming is set');
$this->assertEquals('router.cached', (string) $container->getAlias('router'), '->registerRouterConfiguration() changes router alias to cached if cache warming is set');
}
/**
* @expectedException InvalidArgumentException
*/
public function testRouterRequiresResourceOption()
{
$container = $this->createContainer();
$loader = new FrameworkExtension();
$loader->configLoad(array(array('router' => true)), $container);
}
public function testSession()
{
$container = $this->createContainerFromFile('full');
$this->assertTrue($container->hasDefinition('session'), '->registerSessionConfiguration() loads session.xml');
$this->assertEquals('fr', $container->getParameter('session.default_locale'));
$this->assertTrue($container->getDefinition('session')->hasMethodCall('start'));
$this->assertEquals('Session', $container->getParameter('session.class'));
$this->assertEquals('session.storage.native', (string) $container->getAlias('session.storage'));
$options = $container->getParameter('session.storage.native.options');
$this->assertEquals('_SYMFONY', $options['name']);
$this->assertEquals(86400, $options['lifetime']);
$this->assertEquals('/', $options['path']);
$this->assertEquals('example.com', $options['domain']);
$this->assertTrue($options['secure']);
$this->assertTrue($options['httponly']);
}
public function testSessionPdo()
{
$container = $this->createContainerFromFile('session_pdo');
$options = $container->getParameter('session.storage.pdo.options');
$this->assertEquals('session.storage.pdo', (string) $container->getAlias('session.storage'));
$this->assertEquals('table', $options['db_table']);
$this->assertEquals('id', $options['db_id_col']);
$this->assertEquals('data', $options['db_data_col']);
$this->assertEquals('time', $options['db_time_col']);
}
public function testTemplating()
{
$container = $this->createContainerFromFile('full');
$this->assertTrue($container->hasDefinition('templating.name_parser'), '->registerTemplatingConfiguration() loads templating.xml');
$this->assertEquals('SomeVersionScheme', $container->getParameter('templating.assets.version'));
$this->assertEquals('http://cdn.example.com', $container->getParameter('templating.assets.base_urls'));
$this->assertTrue($container->getDefinition('templating.cache_warmer.template_paths')->hasTag('kernel.cache_warmer'), '->registerTemplatingConfiguration() tags templating cache warmer if cache warming is set');
$this->assertEquals('templating.locator.cached', (string) $container->getAlias('templating.locator'), '->registerTemplatingConfiguration() changes templating.locator alias to cached if cache warming is set');
$this->assertEquals('templating.engine.delegating', (string) $container->getAlias('templating'), '->registerTemplatingConfiguration() configures delegating loader if multiple engines are provided');
$this->assertEquals('templating.loader.chain', (string) $container->getAlias('templating.loader'), '->registerTemplatingConfiguration() configures loader chain if multiple loaders are provided');
}
public function testTranslator()
{
$container = $this->createContainerFromFile('full');
$this->assertTrue($container->hasDefinition('translator.real'), '->registerTranslatorConfiguration() loads translation.xml');
$this->assertSame($container->getDefinition('translator.real'), $container->getDefinition('translator'), '->registerTranslatorConfiguration() redefines translator service from identity to real translator');
$this->assertContains(
realpath(__DIR__.'/../../Resources/translations/validators.fr.xliff'),
array_map(function($resource) { return $resource[1]; }, $container->getParameter('translation.resources')),
'->registerTranslatorConfiguration() finds FrameworkExtension translation resources'
);
$this->assertEquals('fr', $container->getParameter('translator.fallback_locale'));
}
/**
* @expectedException LogicException
*/
public function testTemplatingRequiresAtLeastOneEngine()
{
$container = $this->createContainer();
$loader = new FrameworkExtension();
$loader->configLoad(array(array('templating' => null)), $container);
}
public function testValidation()
{
$container = $this->createContainerFromFile('full');
$this->assertTrue($container->hasDefinition('validator'), '->registerValidationConfiguration() loads validator.xml');
$this->assertTrue($container->hasDefinition('validator.mapping.loader.xml_files_loader'), '->registerValidationConfiguration() defines the XML loader');
$this->assertTrue($container->hasDefinition('validator.mapping.loader.yaml_files_loader'), '->registerValidationConfiguration() defines the YAML loader');
$xmlLoaderArgs = $container->getDefinition('validator.mapping.loader.xml_files_loader')->getArguments();
$xmlFiles = $xmlLoaderArgs[0];
$this->assertContains(
realpath(__DIR__.'/../../../../Component/Form/Resources/config/validation.xml'),
array_map('realpath', $xmlFiles),
'->registerValidationConfiguration() adds Form validation.xml to XML loader'
);
$this->assertFalse($container->hasDefinition('validator.mapping.loader.annotation_loader'), '->registerValidationConfiguration() does not define the annotation loader unless needed');
}
public function testValidationAnnotations()
{
$container = $this->createContainerFromFile('validation_annotations');
$this->assertTrue($container->hasDefinition('validator.mapping.loader.annotation_loader'), '->registerValidationConfiguration() defines the annotation loader');
$namespaces = $container->getParameter('validator.annotations.namespaces');
$this->assertEquals('Symfony\\Component\\Validator\\Constraints\\', $namespaces['validation'], '->registerValidationConfiguration() loads the default "validation" namespace');
$this->assertEquals('Application\\Validator\\Constraints\\', $namespaces['app'], '->registerValidationConfiguration() loads custom validation namespaces');
}
protected function createContainer()
{
return new ContainerBuilder(new ParameterBag(array(
'kernel.bundles' => array('FrameworkBundle' => 'Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle'),
'kernel.root_dir' => __DIR__,
'kernel.debug' => false,
'kernel.cache_dir' => __DIR__,
'kernel.compiled_classes' => array(),
'kernel.debug' => false,
'kernel.environment' => 'test',
'kernel.name' => 'kernel',
'kernel.root_dir' => __DIR__,
)));
}
protected function createContainerFromFile($file)
{
$container = $this->createContainer();
$container->registerExtension(new FrameworkExtension());
$this->loadFromFile($container, $file);
$container->getCompilerPassConfig()->setOptimizationPasses(array());
$container->getCompilerPassConfig()->setRemovingPasses(array());
$container->compile();
return $container;
}
}

View File

@ -0,0 +1,24 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
class PhpFrameworkExtensionTest extends FrameworkExtensionTest
{
protected function loadFromFile(ContainerBuilder $container, $file)
{
$loader = new PhpFileLoader($container, __DIR__.'/Fixtures/php');
$loader->load($file.'.php');
}
}

View File

@ -0,0 +1,24 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
class XmlFrameworkExtensionTest extends FrameworkExtensionTest
{
protected function loadFromFile(ContainerBuilder $container, $file)
{
$loader = new XmlFileLoader($container, __DIR__.'/Fixtures/xml');
$loader->load($file.'.xml');
}
}

View File

@ -0,0 +1,24 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
class YamlFrameworkExtensionTest extends FrameworkExtensionTest
{
protected function loadFromFile(ContainerBuilder $container, $file)
{
$loader = new YamlFileLoader($container, __DIR__.'/Fixtures/yml');
$loader->load($file.'.yml');
}
}