merged branch Tobion/loaders (PR #6172)

This PR was merged into the master branch.

Commits
-------

237bbd0 fixed and refactored YamlFileLoader in the same sense as the XmlFileLoader
392d785 removed covers annotation from loader tests and unneeded use statements
45987eb added tests for the previous XmlFileLoader fixes
b20d6a7 ensure id, pattern and resource are specified
8361b5a refactor the XMlFileLoader
83fc5ff fix namespace handling in xml loader; it could not handle prefixes
1a60a3c make resource and key attributes required in xsd
02e01b9 improve exception messages in xml loader
51fbffe remove unneeded cast
358e9c4 fix some phpdoc

Discussion
----------

[Routing] improve loaders

BC break: no

Main points:
- fixed Xml loader that could not handle namespace prefixes but is valid xml
- fixed Yaml loader where some nonsesense configs were not validated correctly like an imported resource with a pattern key.

Added tests for all. Some refactoring + a few tweaks like better exception messages and more consistency between Xml loader and yaml loader. See also commits.

---------------------------------------------------------------------------

by Tobion at 2012-12-07T18:16:08Z

@fabpot this is ready

---------------------------------------------------------------------------

by Tobion at 2012-12-11T17:30:10Z

@fabpot rebased. Please don't squash to one big commit where one does not see what changed why.

---------------------------------------------------------------------------

by fabpot at 2012-12-11T17:32:40Z

I only squash when most commits are CS fixes and feedback.

---------------------------------------------------------------------------

by Tobion at 2012-12-11T17:37:49Z

Well, you squashed #6022 so it's not possible to revert a specific deprecation.
This commit is contained in:
Fabien Potencier 2012-12-11 18:46:52 +01:00
commit 18c520a5e8
18 changed files with 246 additions and 193 deletions

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Routing\Loader;
use Symfony\Component\Config\Loader\Loader;
use Symfony\Component\Routing\RouteCollection;
/**
* ClosureLoader loads routes from a PHP closure.
@ -30,6 +31,8 @@ class ClosureLoader extends Loader
* @param \Closure $closure A Closure
* @param string|null $type The resource type
*
* @return RouteCollection A RouteCollection instance
*
* @api
*/
public function load($closure, $type = null)

View File

@ -11,8 +11,9 @@
namespace Symfony\Component\Routing\Loader;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Config\Loader\FileLoader;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Routing\RouteCollection;
/**
* PhpFileLoader loads routes from a PHP file.
@ -31,6 +32,8 @@ class PhpFileLoader extends FileLoader
* @param string $file A PHP file path
* @param string|null $type The resource type
*
* @return RouteCollection A RouteCollection instance
*
* @api
*/
public function load($file, $type = null)

View File

@ -20,11 +20,15 @@ use Symfony\Component\Config\Loader\FileLoader;
* XmlFileLoader loads XML routing files.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Tobias Schultze <http://tobion.de>
*
* @api
*/
class XmlFileLoader extends FileLoader
{
const NAMESPACE_URI = 'http://symfony.com/schema/routing';
const SCHEME_PATH = '/schema/routing/routing-1.0.xsd';
/**
* Loads an XML file.
*
@ -33,7 +37,8 @@ class XmlFileLoader extends FileLoader
*
* @return RouteCollection A RouteCollection instance
*
* @throws \InvalidArgumentException When a tag can't be parsed
* @throws \InvalidArgumentException When the file cannot be loaded or when the XML cannot be
* parsed because it does not validate against the scheme.
*
* @api
*/
@ -61,65 +66,28 @@ class XmlFileLoader extends FileLoader
/**
* Parses a node from a loaded XML file.
*
* @param RouteCollection $collection the collection to associate with the node
* @param \DOMElement $node the node to parse
* @param string $path the path of the XML file being processed
* @param string $file
* @param RouteCollection $collection Collection to associate with the node
* @param \DOMElement $node Element to parse
* @param string $path Full path of the XML file being processed
* @param string $file Loaded file name
*
* @throws \InvalidArgumentException When a tag can't be parsed
* @throws \InvalidArgumentException When the XML is invalid
*/
protected function parseNode(RouteCollection $collection, \DOMElement $node, $path, $file)
{
switch ($node->tagName) {
if (self::NAMESPACE_URI !== $node->namespaceURI) {
return;
}
switch ($node->localName) {
case 'route':
$this->parseRoute($collection, $node, $path);
break;
case 'import':
$resource = $node->getAttribute('resource');
$type = $node->getAttribute('type');
$prefix = $node->getAttribute('prefix');
$hostnamePattern = $node->hasAttribute('hostname-pattern') ? $node->getAttribute('hostname-pattern') : null;
$defaults = array();
$requirements = array();
$options = array();
foreach ($node->childNodes as $n) {
if (!$n instanceof \DOMElement) {
continue;
}
switch ($n->tagName) {
case 'default':
$defaults[$n->getAttribute('key')] = trim($n->nodeValue);
break;
case 'requirement':
$requirements[$n->getAttribute('key')] = trim($n->nodeValue);
break;
case 'option':
$options[$n->getAttribute('key')] = trim($n->nodeValue);
break;
default:
throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $n->tagName));
}
}
$this->setCurrentDir(dirname($path));
$subCollection = $this->import($resource, ('' !== $type ? $type : null), false, $file);
/* @var $subCollection RouteCollection */
$subCollection->addPrefix($prefix);
if (null !== $hostnamePattern) {
$subCollection->setHostnamePattern($hostnamePattern);
}
$subCollection->addDefaults($defaults);
$subCollection->addRequirements($requirements);
$subCollection->addOptions($options);
$collection->addCollection($subCollection);
$this->parseImport($collection, $node, $path, $file);
break;
default:
throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName));
throw new \InvalidArgumentException(sprintf('Unknown tag "%s" used in file "%s". Expected "route" or "import".', $node->localName, $path));
}
}
@ -136,41 +104,59 @@ class XmlFileLoader extends FileLoader
/**
* Parses a route and adds it to the RouteCollection.
*
* @param RouteCollection $collection A RouteCollection instance
* @param \DOMElement $definition Route definition
* @param string $file An XML file path
* @param RouteCollection $collection RouteCollection instance
* @param \DOMElement $node Element to parse that represents a Route
* @param string $path Full path of the XML file being processed
*
* @throws \InvalidArgumentException When the definition cannot be parsed
* @throws \InvalidArgumentException When the XML is invalid
*/
protected function parseRoute(RouteCollection $collection, \DOMElement $definition, $file)
protected function parseRoute(RouteCollection $collection, \DOMElement $node, $path)
{
$defaults = array();
$requirements = array();
$options = array();
foreach ($definition->childNodes as $node) {
if (!$node instanceof \DOMElement) {
continue;
}
switch ($node->tagName) {
case 'default':
$defaults[$node->getAttribute('key')] = trim((string) $node->nodeValue);
break;
case 'option':
$options[$node->getAttribute('key')] = trim((string) $node->nodeValue);
break;
case 'requirement':
$requirements[$node->getAttribute('key')] = trim((string) $node->nodeValue);
break;
default:
throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName));
}
if ('' === ($id = $node->getAttribute('id')) || !$node->hasAttribute('pattern')) {
throw new \InvalidArgumentException(sprintf('The <route> element in file "%s" must have an "id" and a "pattern" attribute.', $path));
}
$route = new Route($definition->getAttribute('pattern'), $defaults, $requirements, $options, $definition->getAttribute('hostname-pattern'));
list($defaults, $requirements, $options) = $this->parseConfigs($node, $path);
$collection->add($definition->getAttribute('id'), $route);
$route = new Route($node->getAttribute('pattern'), $defaults, $requirements, $options, $node->getAttribute('hostname-pattern'));
$collection->add($id, $route);
}
/**
* Parses an import and adds the routes in the resource to the RouteCollection.
*
* @param RouteCollection $collection RouteCollection instance
* @param \DOMElement $node Element to parse that represents a Route
* @param string $path Full path of the XML file being processed
* @param string $file Loaded file name
*
* @throws \InvalidArgumentException When the XML is invalid
*/
protected function parseImport(RouteCollection $collection, \DOMElement $node, $path, $file)
{
if ('' === $resource = $node->getAttribute('resource')) {
throw new \InvalidArgumentException(sprintf('The <import> element in file "%s" must have a "resource" attribute.', $path));
}
$type = $node->getAttribute('type');
$prefix = $node->getAttribute('prefix');
$hostnamePattern = $node->hasAttribute('hostname-pattern') ? $node->getAttribute('hostname-pattern') : null;
list($defaults, $requirements, $options) = $this->parseConfigs($node, $path);
$this->setCurrentDir(dirname($path));
$subCollection = $this->import($resource, ('' !== $type ? $type : null), false, $file);
/* @var $subCollection RouteCollection */
$subCollection->addPrefix($prefix);
if (null !== $hostnamePattern) {
$subCollection->setHostnamePattern($hostnamePattern);
}
$subCollection->addDefaults($defaults);
$subCollection->addRequirements($requirements);
$subCollection->addOptions($options);
$collection->addCollection($subCollection);
}
/**
@ -180,7 +166,9 @@ class XmlFileLoader extends FileLoader
*
* @return \DOMDocument
*
* @throws \InvalidArgumentException When loading of XML file returns error
* @throws \InvalidArgumentException When loading of XML file fails because of syntax errors
* or when the XML structure is not as expected by the scheme -
* see validate()
*/
protected function loadFile($file)
{
@ -220,12 +208,10 @@ class XmlFileLoader extends FileLoader
*/
protected function validate(\DOMDocument $dom)
{
$location = __DIR__.'/schema/routing/routing-1.0.xsd';
$current = libxml_use_internal_errors(true);
libxml_clear_errors();
if (!$dom->schemaValidate($location)) {
if (!$dom->schemaValidate(__DIR__ . static::SCHEME_PATH)) {
throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors($current)));
}
libxml_use_internal_errors($current);
@ -255,4 +241,39 @@ class XmlFileLoader extends FileLoader
return $errors;
}
/**
* Parses the config elements (default, requirement, option).
*
* @param \DOMElement $node Element to parse that contains the configs
* @param string $path Full path of the XML file being processed
*
* @return array An array with the defaults as first item, requirements as second and options as third.
*
* @throws \InvalidArgumentException When the XML is invalid
*/
private function parseConfigs(\DOMElement $node, $path)
{
$defaults = array();
$requirements = array();
$options = array();
foreach ($node->getElementsByTagNameNS(self::NAMESPACE_URI, '*') as $n) {
switch ($n->localName) {
case 'default':
$defaults[$n->getAttribute('key')] = trim($n->textContent);
break;
case 'requirement':
$requirements[$n->getAttribute('key')] = trim($n->textContent);
break;
case 'option':
$options[$n->getAttribute('key')] = trim($n->textContent);
break;
default:
throw new \InvalidArgumentException(sprintf('Unknown tag "%s" used in file "%s". Expected "default", "requirement" or "option".', $n->localName, $path));
}
}
return array($defaults, $requirements, $options);
}
}

View File

@ -21,13 +21,14 @@ use Symfony\Component\Config\Loader\FileLoader;
* YamlFileLoader loads Yaml routing files.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Tobias Schultze <http://tobion.de>
*
* @api
*/
class YamlFileLoader extends FileLoader
{
private static $availableKeys = array(
'type', 'resource', 'prefix', 'pattern', 'options', 'defaults', 'requirements', 'hostname_pattern',
'resource', 'type', 'prefix', 'pattern', 'hostname_pattern', 'defaults', 'requirements', 'options',
);
/**
@ -38,7 +39,7 @@ class YamlFileLoader extends FileLoader
*
* @return RouteCollection A RouteCollection instance
*
* @throws \InvalidArgumentException When route can't be parsed
* @throws \InvalidArgumentException When a route can't be parsed because YAML is invalid
*
* @api
*/
@ -53,38 +54,19 @@ class YamlFileLoader extends FileLoader
// empty file
if (null === $config) {
$config = array();
return $collection;
}
// not an array
if (!is_array($config)) {
throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $file));
throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $path));
}
foreach ($config as $name => $config) {
$config = $this->normalizeRouteConfig($config);
$this->validate($config, $name, $path);
if (isset($config['resource'])) {
$type = isset($config['type']) ? $config['type'] : null;
$prefix = isset($config['prefix']) ? $config['prefix'] : '';
$defaults = isset($config['defaults']) ? $config['defaults'] : array();
$requirements = isset($config['requirements']) ? $config['requirements'] : array();
$options = isset($config['options']) ? $config['options'] : array();
$hostnamePattern = isset($config['hostname_pattern']) ? $config['hostname_pattern'] : null;
$this->setCurrentDir(dirname($path));
$subCollection = $this->import($config['resource'], $type, false, $file);
/* @var $subCollection RouteCollection */
$subCollection->addPrefix($prefix);
if (null !== $hostnamePattern) {
$subCollection->setHostnamePattern($hostnamePattern);
}
$subCollection->addDefaults($defaults);
$subCollection->addRequirements($requirements);
$subCollection->addOptions($options);
$collection->addCollection($subCollection);
$this->parseImport($collection, $config, $path, $file);
} else {
$this->parseRoute($collection, $name, $config, $path);
}
@ -109,46 +91,90 @@ class YamlFileLoader extends FileLoader
* @param RouteCollection $collection A RouteCollection instance
* @param string $name Route name
* @param array $config Route definition
* @param string $file A Yaml file path
*
* @throws \InvalidArgumentException When config pattern is not defined for the given route
* @param string $path Full path of the YAML file being processed
*/
protected function parseRoute(RouteCollection $collection, $name, $config, $file)
protected function parseRoute(RouteCollection $collection, $name, array $config, $path)
{
$defaults = isset($config['defaults']) ? $config['defaults'] : array();
$requirements = isset($config['requirements']) ? $config['requirements'] : array();
$options = isset($config['options']) ? $config['options'] : array();
$hostnamePattern = isset($config['hostname_pattern']) ? $config['hostname_pattern'] : null;
if (!isset($config['pattern'])) {
throw new \InvalidArgumentException(sprintf('You must define a "pattern" for the "%s" route.', $name));
}
$route = new Route($config['pattern'], $defaults, $requirements, $options, $hostnamePattern);
$collection->add($name, $route);
}
/**
* Normalize route configuration.
* Parses an import and adds the routes in the resource to the RouteCollection.
*
* @param array $config A resource config
*
* @return array
*
* @throws \InvalidArgumentException if one of the provided config keys is not supported
* @param RouteCollection $collection A RouteCollection instance
* @param array $config Route definition
* @param string $path Full path of the YAML file being processed
* @param string $file Loaded file name
*/
private function normalizeRouteConfig(array $config)
protected function parseImport(RouteCollection $collection, array $config, $path, $file)
{
foreach ($config as $key => $value) {
if (!in_array($key, self::$availableKeys)) {
throw new \InvalidArgumentException(sprintf(
'Yaml routing loader does not support given key: "%s". Expected one of the (%s).',
$key, implode(', ', self::$availableKeys)
));
}
}
$type = isset($config['type']) ? $config['type'] : null;
$prefix = isset($config['prefix']) ? $config['prefix'] : '';
$defaults = isset($config['defaults']) ? $config['defaults'] : array();
$requirements = isset($config['requirements']) ? $config['requirements'] : array();
$options = isset($config['options']) ? $config['options'] : array();
$hostnamePattern = isset($config['hostname_pattern']) ? $config['hostname_pattern'] : null;
return $config;
$this->setCurrentDir(dirname($path));
$subCollection = $this->import($config['resource'], $type, false, $file);
/* @var $subCollection RouteCollection */
$subCollection->addPrefix($prefix);
if (null !== $hostnamePattern) {
$subCollection->setHostnamePattern($hostnamePattern);
}
$subCollection->addDefaults($defaults);
$subCollection->addRequirements($requirements);
$subCollection->addOptions($options);
$collection->addCollection($subCollection);
}
/**
* Validates the route configuration.
*
* @param array $config A resource config
* @param string $name The config key
* @param string $path The loaded file path
*
* @throws \InvalidArgumentException If one of the provided config keys is not supported,
* something is missing or the combination is nonesense
*/
protected function validate($config, $name, $path)
{
if (!is_array($config)) {
throw new \InvalidArgumentException(sprintf('The definition of "%s" in "%s" must be a YAML array.', $name, $path));
}
if ($extraKeys = array_diff(array_keys($config), self::$availableKeys)) {
throw new \InvalidArgumentException(sprintf(
'The routing file "%s" contains unsupport keys for "%s": "%s". Expected one of: "%s".',
$path, $name, implode('", "', $extraKeys), implode('", "', self::$availableKeys)
));
}
if (isset($config['resource']) && isset($config['pattern'])) {
throw new \InvalidArgumentException(sprintf(
'The routing file "%s" must not specify both the "resource" key and the "pattern" key for "%s". Choose between an import and a route definition.',
$path, $name
));
}
if (!isset($config['resource']) && isset($config['type'])) {
throw new \InvalidArgumentException(sprintf(
'The "type" key for the route definition "%s" in "%s" is unsupported. It is only available for imports in combination with the "resource" key.',
$name, $path
));
}
if (!isset($config['resource']) && !isset($config['pattern'])) {
throw new \InvalidArgumentException(sprintf(
'You must define a "pattern" for the route "%s" in file "%s".',
$name, $path
));
}
}
}

View File

@ -36,14 +36,14 @@
<xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
<xsd:attribute name="id" type="xsd:string" use="required" />
<xsd:attribute name="pattern" type="xsd:string" default="/" />
<xsd:attribute name="pattern" type="xsd:string" use="required" />
<xsd:attribute name="hostname-pattern" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="import">
<xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
<xsd:attribute name="resource" type="xsd:string" />
<xsd:attribute name="resource" type="xsd:string" use="required" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="prefix" type="xsd:string" />
<xsd:attribute name="hostname-pattern" type="xsd:string" />
@ -52,7 +52,7 @@
<xsd:complexType name="element">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="key" type="xsd:string" />
<xsd:attribute name="key" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route pattern="/test"></route>
</routes>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="myroute"></route>
</routes>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<r:routes xmlns:r="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<r:route id="blog_show" pattern="/blog/{slug}" hostname-pattern="{_locale}.example.com">
<r:default key="_controller">MyBundle:Blog:show</r:default>
<requirement xmlns="http://symfony.com/schema/routing" key="slug">\w+</requirement>
<r2:requirement xmlns:r2="http://symfony.com/schema/routing" key="_locale">en|fr|de</r2:requirement>
<r:option key="compiler_class">RouteCompiler</r:option>
</r:route>
</r:routes>

View File

@ -0,0 +1,3 @@
blog_show:
resource: validpattern.yml
pattern: /test

View File

@ -0,0 +1,3 @@
blog_show:
pattern: /blog/{slug}
type: custom

View File

@ -0,0 +1 @@
route: string

View File

@ -11,8 +11,6 @@
namespace Symfony\Component\Routing\Tests\Loader;
use Symfony\Component\Routing\Loader\AnnotationClassLoader;
class AnnotationClassLoaderTest extends AbstractAnnotationLoaderTest
{
protected $loader;
@ -42,7 +40,6 @@ class AnnotationClassLoaderTest extends AbstractAnnotationLoaderTest
}
/**
* @covers Symfony\Component\Routing\Loader\AnnotationClassLoader::supports
* @dataProvider provideTestSupportsChecksResource
*/
public function testSupportsChecksResource($resource, $expectedSupports)
@ -63,9 +60,6 @@ class AnnotationClassLoaderTest extends AbstractAnnotationLoaderTest
);
}
/**
* @covers Symfony\Component\Routing\Loader\AnnotationClassLoader::supports
*/
public function testSupportsChecksTypeIfSpecified()
{
$this->assertTrue($this->loader->supports('class', 'annotation'), '->supports() checks the resource type if specified');

View File

@ -40,9 +40,6 @@ class AnnotationDirectoryLoaderTest extends AbstractAnnotationLoaderTest
$this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses');
}
/**
* @covers Symfony\Component\Routing\Loader\AnnotationDirectoryLoader::supports
*/
public function testSupports()
{
$fixturesDir = __DIR__.'/../Fixtures';

View File

@ -34,9 +34,6 @@ class AnnotationFileLoaderTest extends AbstractAnnotationLoaderTest
$this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/FooClass.php');
}
/**
* @covers Symfony\Component\Routing\Loader\AnnotationFileLoader::supports
*/
public function testSupports()
{
$fixture = __DIR__.'/../Fixtures/annotated.php';

View File

@ -24,9 +24,6 @@ class ClosureLoaderTest extends \PHPUnit_Framework_TestCase
}
}
/**
* @covers Symfony\Component\Routing\Loader\ClosureLoader::supports
*/
public function testSupports()
{
$loader = new ClosureLoader();
@ -40,9 +37,6 @@ class ClosureLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($loader->supports($closure, 'foo'), '->supports() checks the resource type if specified');
}
/**
* @covers Symfony\Component\Routing\Loader\ClosureLoader::load
*/
public function testLoad()
{
$loader = new ClosureLoader();

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Routing\Tests\Loader;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\PhpFileLoader;
use Symfony\Component\Routing\Route;
class PhpFileLoaderTest extends \PHPUnit_Framework_TestCase
{
@ -24,9 +23,6 @@ class PhpFileLoaderTest extends \PHPUnit_Framework_TestCase
}
}
/**
* @covers Symfony\Component\Routing\Loader\PhpFileLoader::supports
*/
public function testSupports()
{
$loader = new PhpFileLoader($this->getMock('Symfony\Component\Config\FileLocator'));

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Routing\Tests\Loader;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\XmlFileLoader;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\Tests\Fixtures\CustomXmlFileLoader;
class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
@ -25,9 +24,6 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
}
}
/**
* @covers Symfony\Component\Routing\Loader\XmlFileLoader::supports
*/
public function testSupports()
{
$loader = new XmlFileLoader($this->getMock('Symfony\Component\Config\FileLocator'));
@ -56,6 +52,21 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('RouteCompiler', $route->getOption('compiler_class'));
}
public function testLoadWithNamespacePrefix()
{
$loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
$routeCollection = $loader->load('namespaceprefix.xml');
$this->assertCount(1, $routeCollection, 'One route is loaded');
$route = $routeCollection->get('blog_show');
$this->assertEquals('/blog/{slug}', $route->getPattern());
$this->assertEquals('MyBundle:Blog:show', $route->getDefault('_controller'));
$this->assertEquals('\w+', $route->getRequirement('slug'));
$this->assertEquals('en|fr|de', $route->getRequirement('_locale'));
$this->assertEquals('{_locale}.example.com', $route->getHostnamePattern());
$this->assertEquals('RouteCompiler', $route->getOption('compiler_class'));
}
public function testLoadWithImport()
{
$loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
@ -94,7 +105,7 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
public function getPathsToInvalidFiles()
{
return array(array('nonvalidnode.xml'), array('nonvalidroute.xml'), array('nonvalid.xml'));
return array(array('nonvalidnode.xml'), array('nonvalidroute.xml'), array('nonvalid.xml'), array('missing_id.xml'), array('missing_path.xml'));
}
/**

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Routing\Tests\Loader;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\YamlFileLoader;
use Symfony\Component\Routing\Route;
use Symfony\Component\Config\Resource\FileResource;
class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
@ -29,9 +28,6 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
}
}
/**
* @covers Symfony\Component\Routing\Loader\YamlFileLoader::supports
*/
public function testSupports()
{
$loader = new YamlFileLoader($this->getMock('Symfony\Component\Config\FileLocator'));
@ -54,29 +50,17 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \InvalidArgumentException
* @dataProvider getPathsToInvalidFiles
*/
public function testLoadThrowsExceptionIfNotAnArray()
public function testLoadThrowsExceptionWithInvalidFile($filePath)
{
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
$loader->load('nonvalid.yml');
$loader->load($filePath);
}
/**
* @expectedException \InvalidArgumentException
*/
public function testLoadThrowsExceptionIfArrayHasUnsupportedKeys()
public function getPathsToInvalidFiles()
{
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
$loader->load('nonvalidkeys.yml');
}
/**
* @expectedException \InvalidArgumentException
*/
public function testLoadThrowsExceptionWhenIncomplete()
{
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
$loader->load('incomplete.yml');
return array(array('nonvalid.yml'), array('nonvalid2.yml'), array('incomplete.yml'), array('nonvalidkeys.yml'), array('nonesense_resource_plus_path.yml'), array('nonesense_type_without_resource.yml'));
}
public function testLoadSpecialRouteName()
@ -121,13 +105,4 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('bar', $routes['blog_show']->getOption('foo'));
$this->assertEquals('{locale}.example.com', $routes['blog_show']->getHostnamePattern());
}
/**
* @expectedException \InvalidArgumentException
*/
public function testParseRouteThrowsExceptionWithMissingPattern()
{
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
$loader->load('incomplete.yml');
}
}