[Config] Throw exceptions on invalid definition

This commit is contained in:
Victor Berchet 2012-02-15 00:48:14 +01:00
parent fb27de0f8a
commit 6745b28b3d
5 changed files with 84 additions and 3 deletions

View File

@ -13,6 +13,7 @@ namespace Symfony\Component\Config\Definition\Builder;
use Symfony\Component\Config\Definition\ArrayNode;
use Symfony\Component\Config\Definition\PrototypedArrayNode;
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
/**
* This class provides a fluent interface for defining an array node.
@ -259,13 +260,38 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
protected function createNode()
{
if (null === $this->prototype) {
$node = new ArrayNode($this->name, $this->parent);
if (null !== $this->key) {
throw new InvalidDefinitionException(
sprintf('%s::useAttributeAsKey() is not applicable to concrete nodes.', __CLASS__)
);
}
if (true === $this->atLeastOne) {
throw new InvalidDefinitionException(
sprintf('%s::requiresAtLeastOneElement() is not applicable to concrete nodes.', __CLASS__)
);
}
if ($this->default) {
throw new InvalidDefinitionException(
sprintf('%s::defaultValue() is not applicable to concrete nodes.', __CLASS__)
);
}
$node = new ArrayNode($this->name, $this->parent);
$node->setAddIfNotSet($this->addDefaults);
foreach ($this->children as $child) {
$child->parent = $node;
$node->addChild($child->getNode());
}
} else {
if ($this->addDefaults) {
throw new InvalidDefinitionException(
sprintf('%s::addDefaultsIfNotSet() is not applicable to prototype nodes.', __CLASS__)
);
}
$node = new PrototypedArrayNode($this->name, $this->parent);
if (null !== $this->key) {
@ -284,7 +310,6 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
$node->setPrototype($this->prototype->getNode());
}
$node->setAddIfNotSet($this->addDefaults);
$node->setAllowNewKeys($this->allowNewKeys);
$node->addEquivalentValue(null, $this->nullEquivalent);
$node->addEquivalentValue(true, $this->trueEquivalent);

View File

@ -325,6 +325,8 @@ abstract class NodeDefinition implements NodeParentInterface
* Instantiate and configure the node according to this definition
*
* @return NodeInterface $node The node instance
*
* @throws Symfony\Component\Config\Definition\Exception\InvalidDefinitionException When the definition is invalid
*/
abstract protected function createNode();

View File

@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Config\Definition\Exception;
/**
* Thrown when an error is detected in a node Definition.
*
* @author Victor Berchet <victor.berchet@suumit.com>
*/
class InvalidDefinitionException extends Exception
{
}

View File

@ -14,6 +14,7 @@ namespace Symfony\Component\Config\Definition;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\Exception\DuplicateKeyException;
use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
use Symfony\Component\Config\Definition\Exception\Exception;
/**
* Represents a prototyped Array node in the config tree.
@ -158,7 +159,7 @@ class PrototypedArrayNode extends ArrayNode
*/
public function addChild(NodeInterface $node)
{
throw new \RuntimeException('A prototyped array node can not have concrete children.');
throw new Exception('A prototyped array node can not have concrete children.');
}
/**

View File

@ -32,6 +32,38 @@ class ArrayNodeDefinitionTest extends \PHPUnit_Framework_TestCase
$this->assertTrue(in_array($child, $this->getField($parent, 'children')));
}
/**
* @expectedException Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
* @dataProvider providePrototypeNodeSpecificCalls
*/
public function testPrototypeNodeSpecificOption($method, $args)
{
$node = new ArrayNodeDefinition('root');
call_user_method_array($method, $node, $args);
$node->getNode();
}
public function providePrototypeNodeSpecificCalls()
{
return array(
array('defaultValue', array(array())),
array('requiresAtLeastOneElement', array()),
array('useAttributeAsKey', array('foo'))
);
}
/**
* @expectedException Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
*/
public function testConcreteNodeSpecificOption()
{
$node = new ArrayNodeDefinition('root');
$node->addDefaultsIfNotSet()->prototype('array');
$node->getNode();
}
protected function getField($object, $field)
{
$reflection = new \ReflectionProperty($object, $field);