[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.
|
* 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.
|
* This method is applicable to prototype nodes only.
|
||||||
*
|
*
|
||||||
@ -111,7 +111,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
|||||||
*/
|
*/
|
||||||
public function addDefaultChildrenIfNoneSet($children = null)
|
public function addDefaultChildrenIfNoneSet($children = null)
|
||||||
{
|
{
|
||||||
$this->addDefaultChildren = null === $children ? 'defaults' : $children;
|
$this->addDefaultChildren = $children;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -394,10 +394,24 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->default && false !== $this->addDefaultChildren) {
|
if (false !== $this->addDefaultChildren) {
|
||||||
throw new InvalidDefinitionException(
|
if ($this->default) {
|
||||||
sprintf('A default value and default children might not be used together at path "%s"', $path)
|
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,11 +124,15 @@ class PrototypedArrayNode extends ArrayNode
|
|||||||
/**
|
/**
|
||||||
* Adds default children when none are set.
|
* 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'))
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,6 +13,7 @@ namespace Symfony\Tests\Component\Config\Definition\Builder;
|
|||||||
|
|
||||||
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
|
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
|
||||||
use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
|
use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
|
||||||
|
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
|
||||||
|
|
||||||
class ArrayNodeDefinitionTest extends \PHPUnit_Framework_TestCase
|
class ArrayNodeDefinitionTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
@ -21,7 +22,7 @@ class ArrayNodeDefinitionTest extends \PHPUnit_Framework_TestCase
|
|||||||
$parent = new ArrayNodeDefinition('root');
|
$parent = new ArrayNodeDefinition('root');
|
||||||
$child = new ScalarNodeDefinition('child');
|
$child = new ScalarNodeDefinition('child');
|
||||||
|
|
||||||
$node = $parent
|
$parent
|
||||||
->children()
|
->children()
|
||||||
->scalarNode('foo')->end()
|
->scalarNode('foo')->end()
|
||||||
->scalarNode('bar')->end()
|
->scalarNode('bar')->end()
|
||||||
@ -79,7 +80,7 @@ class ArrayNodeDefinitionTest extends \PHPUnit_Framework_TestCase
|
|||||||
$node->getNode();
|
$node->getNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testArrayNodeDefaultWhenUsingDefaultChildren()
|
public function testPrototypedArrayNodeDefaultWhenUsingDefaultChildren()
|
||||||
{
|
{
|
||||||
$node = new ArrayNodeDefinition('root');
|
$node = new ArrayNodeDefinition('root');
|
||||||
$node
|
$node
|
||||||
@ -90,6 +91,53 @@ class ArrayNodeDefinitionTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals(array(array()), $tree->getDefaultValue());
|
$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()
|
public function testNestedPrototypedArrayNodes()
|
||||||
{
|
{
|
||||||
$node = new ArrayNodeDefinition('root');
|
$node = new ArrayNodeDefinition('root');
|
||||||
@ -98,7 +146,7 @@ class ArrayNodeDefinitionTest extends \PHPUnit_Framework_TestCase
|
|||||||
->prototype('array')
|
->prototype('array')
|
||||||
->prototype('array')
|
->prototype('array')
|
||||||
;
|
;
|
||||||
$tree = $node->getNode();
|
$node->getNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getField($object, $field)
|
protected function getField($object, $field)
|
||||||
|
Reference in New Issue
Block a user