[Config] Improve handling of PrototypedArrayNode defaults

This commit is contained in:
Victor Berchet 2012-02-20 23:07:03 +01:00
parent 4feba09aa9
commit b269e27191
3 changed files with 77 additions and 11 deletions

View File

@ -103,7 +103,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
/**
* Adds children with a default value when none are defined.
*
* @param integer|string|array $children The number of children|The child name|The children names to be added
* @param integer|string|array|null $children The number of children|The child name|The children names to be added
*
* This method is applicable to prototype nodes only.
*
@ -111,7 +111,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
*/
public function addDefaultChildrenIfNoneSet($children = null)
{
$this->addDefaultChildren = null === $children ? 'defaults' : $children;
$this->addDefaultChildren = $children;
return $this;
}
@ -394,10 +394,24 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
);
}
if ($this->default && false !== $this->addDefaultChildren) {
throw new InvalidDefinitionException(
sprintf('A default value and default children might not be used together at path "%s"', $path)
);
if (false !== $this->addDefaultChildren) {
if ($this->default) {
throw new InvalidDefinitionException(
sprintf('A default value and default children might not be used together at path "%s"', $path)
);
}
if (null !== $this->key && (null === $this->addDefaultChildren || is_integer($this->addDefaultChildren) && $this->addDefaultChildren > 0)) {
throw new InvalidDefinitionException(
sprintf('->addDefaultChildrenIfNoneSet() should set default children names as ->useAttributeAsKey() is used at path "%s"', $path)
);
}
if (null === $this->key && (is_string($this->addDefaultChildren) || is_array($this->addDefaultChildren))) {
throw new InvalidDefinitionException(
sprintf('->addDefaultChildrenIfNoneSet() might not set default children names as ->useAttributeAsKey() is not used at path "%s"', $path)
);
}
}
}
}

View File

@ -124,11 +124,15 @@ class PrototypedArrayNode extends ArrayNode
/**
* Adds default children when none are set.
*
* @param integer|string|array $children The number of children|The child name|The children names to be added
* @param integer|string|array|null $children The number of children|The child name|The children names to be added
*/
public function setAddChildrenIfNoneSet($children = array('defaults'))
{
$this->defaultChildren = is_integer($children) && $children > 0 ? range(1, $children) : (array) $children;
if (null === $children) {
$this->defaultChildren = array('defaults');
} else {
$this->defaultChildren = is_integer($children) && $children > 0 ? range(1, $children) : (array) $children;
}
}
/**

View File

@ -13,6 +13,7 @@ namespace Symfony\Tests\Component\Config\Definition\Builder;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
class ArrayNodeDefinitionTest extends \PHPUnit_Framework_TestCase
{
@ -21,7 +22,7 @@ class ArrayNodeDefinitionTest extends \PHPUnit_Framework_TestCase
$parent = new ArrayNodeDefinition('root');
$child = new ScalarNodeDefinition('child');
$node = $parent
$parent
->children()
->scalarNode('foo')->end()
->scalarNode('bar')->end()
@ -79,7 +80,7 @@ class ArrayNodeDefinitionTest extends \PHPUnit_Framework_TestCase
$node->getNode();
}
public function testArrayNodeDefaultWhenUsingDefaultChildren()
public function testPrototypedArrayNodeDefaultWhenUsingDefaultChildren()
{
$node = new ArrayNodeDefinition('root');
$node
@ -90,6 +91,53 @@ class ArrayNodeDefinitionTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array(array()), $tree->getDefaultValue());
}
/**
* @dataProvider providePrototypedArrayNodeDefaults
*/
public function testPrototypedArrayNodeDefault($args, $shouldThrowWhenUsingAttrAsKey, $shouldThrowWhenNotUsingAttrAsKey, $defaults)
{
$node = new ArrayNodeDefinition('root');
$node
->addDefaultChildrenIfNoneSet($args)
->prototype('array')
;
try {
$tree = $node->getNode();
$this->assertFalse($shouldThrowWhenNotUsingAttrAsKey);
$this->assertEquals($defaults, $tree->getDefaultValue());
} catch (InvalidDefinitionException $e) {
$this->assertTrue($shouldThrowWhenNotUsingAttrAsKey);
}
$node = new ArrayNodeDefinition('root');
$node
->useAttributeAsKey('attr')
->addDefaultChildrenIfNoneSet($args)
->prototype('array')
;
try {
$tree = $node->getNode();
$this->assertFalse($shouldThrowWhenUsingAttrAsKey);
$this->assertEquals($defaults, $tree->getDefaultValue());
} catch (InvalidDefinitionException $e) {
$this->assertTrue($shouldThrowWhenUsingAttrAsKey);
}
}
public function providePrototypedArrayNodeDefaults()
{
return array(
array(null, true, false, array(array())),
array(2, true, false, array(array(), array())),
array('2', false, true, array('2' => array())),
array('foo', false, true, array('foo' => array())),
array(array('foo'), false, true, array('foo' => array())),
array(array('foo', 'bar'), false, true, array('foo' => array(), 'bar' => array())),
);
}
public function testNestedPrototypedArrayNodes()
{
$node = new ArrayNodeDefinition('root');
@ -98,7 +146,7 @@ class ArrayNodeDefinitionTest extends \PHPUnit_Framework_TestCase
->prototype('array')
->prototype('array')
;
$tree = $node->getNode();
$node->getNode();
}
protected function getField($object, $field)