[Config] Improve handling of PrototypedArrayNode defaults
This commit is contained in:
parent
4feba09aa9
commit
b269e27191
@ -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) {
|
||||
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)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,12 +124,16 @@ 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'))
|
||||
{
|
||||
if (null === $children) {
|
||||
$this->defaultChildren = array('defaults');
|
||||
} else {
|
||||
$this->defaultChildren = is_integer($children) && $children > 0 ? range(1, $children) : (array) $children;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the default value.
|
||||
|
@ -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)
|
||||
|
Reference in New Issue
Block a user