Skip to content

Commit

Permalink
[Config] Throw exceptions on invalid definition
Browse files Browse the repository at this point in the history
  • Loading branch information
vicb committed Feb 15, 2012
1 parent fb27de0 commit 6745b28
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 3 deletions.
Expand Up @@ -13,6 +13,7 @@

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.
Expand Down Expand Up @@ -259,13 +260,38 @@ protected function getNodeBuilder()
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) {
Expand All @@ -284,7 +310,6 @@ protected function createNode()
$node->setPrototype($this->prototype->getNode());
}

$node->setAddIfNotSet($this->addDefaults);
$node->setAllowNewKeys($this->allowNewKeys);
$node->addEquivalentValue(null, $this->nullEquivalent);
$node->addEquivalentValue(true, $this->trueEquivalent);
Expand Down
Expand Up @@ -325,6 +325,8 @@ protected function normalization()
* 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();

Expand Down
@@ -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
{
}
Expand Up @@ -14,6 +14,7 @@
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.
Expand Down Expand Up @@ -158,7 +159,7 @@ public function getPrototype()
*/
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.');
}

/**
Expand Down
Expand Up @@ -32,6 +32,38 @@ public function testAppendingSomeNode()
$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);
Expand Down

0 comments on commit 6745b28

Please sign in to comment.