[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\ArrayNode;
use Symfony\Component\Config\Definition\PrototypedArrayNode; use Symfony\Component\Config\Definition\PrototypedArrayNode;
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
/** /**
* This class provides a fluent interface for defining an array node. * This class provides a fluent interface for defining an array node.
@ -259,13 +260,38 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
protected function createNode() protected function createNode()
{ {
if (null === $this->prototype) { 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) { foreach ($this->children as $child) {
$child->parent = $node; $child->parent = $node;
$node->addChild($child->getNode()); $node->addChild($child->getNode());
} }
} else { } else {
if ($this->addDefaults) {
throw new InvalidDefinitionException(
sprintf('%s::addDefaultsIfNotSet() is not applicable to prototype nodes.', __CLASS__)
);
}
$node = new PrototypedArrayNode($this->name, $this->parent); $node = new PrototypedArrayNode($this->name, $this->parent);
if (null !== $this->key) { if (null !== $this->key) {
@ -284,7 +310,6 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
$node->setPrototype($this->prototype->getNode()); $node->setPrototype($this->prototype->getNode());
} }
$node->setAddIfNotSet($this->addDefaults);
$node->setAllowNewKeys($this->allowNewKeys); $node->setAllowNewKeys($this->allowNewKeys);
$node->addEquivalentValue(null, $this->nullEquivalent); $node->addEquivalentValue(null, $this->nullEquivalent);
$node->addEquivalentValue(true, $this->trueEquivalent); $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 * Instantiate and configure the node according to this definition
* *
* @return NodeInterface $node The node instance * @return NodeInterface $node The node instance
*
* @throws Symfony\Component\Config\Definition\Exception\InvalidDefinitionException When the definition is invalid
*/ */
abstract protected function createNode(); 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\InvalidConfigurationException;
use Symfony\Component\Config\Definition\Exception\DuplicateKeyException; use Symfony\Component\Config\Definition\Exception\DuplicateKeyException;
use Symfony\Component\Config\Definition\Exception\UnsetKeyException; use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
use Symfony\Component\Config\Definition\Exception\Exception;
/** /**
* Represents a prototyped Array node in the config tree. * Represents a prototyped Array node in the config tree.
@ -158,7 +159,7 @@ class PrototypedArrayNode extends ArrayNode
*/ */
public function addChild(NodeInterface $node) 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'))); $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) protected function getField($object, $field)
{ {
$reflection = new \ReflectionProperty($object, $field); $reflection = new \ReflectionProperty($object, $field);