[Config] Numerical keys for prot. arrays if useAttributeAsKey is set

This commit is contained in:
Alexander 2012-05-14 16:12:22 +02:00
parent 46ffbd5282
commit b7fc009316
2 changed files with 68 additions and 1 deletions

View File

@ -242,10 +242,11 @@ class PrototypedArrayNode extends ArrayNode
$value = $this->remapXml($value);
$isAssoc = array_keys($value) === range(0, count($value) -1);
$normalized = array();
foreach ($value as $k => $v) {
if (null !== $this->keyAttribute && is_array($v)) {
if (!isset($v[$this->keyAttribute]) && is_int($k)) {
if (!isset($v[$this->keyAttribute]) && is_int($k) && $isAssoc) {
$msg = sprintf('The attribute "%s" must be set for path "%s".', $this->keyAttribute, $this->getPath());
$ex = new InvalidConfigurationException($msg);
$ex->setPath($this->getPath());

View File

@ -137,8 +137,74 @@ class NormalizerTest extends \PHPUnit_Framework_TestCase
return array_map(function($v) { return array($v); }, $configs);
}
/**
* @dataProvider getNumericKeysTests
*/
public function testNumericKeysAsAttributes($denormalized)
{
$normalized = array(
'thing' => array(42 => array('foo', 'bar'), 1337 => array('baz', 'qux')),
);
$this->assertNormalized($this->getNumericKeysTestTree(), $denormalized, $normalized);
}
public function getNumericKeysTests()
{
$configs = array();
$configs[] = array(
'thing' => array(
42 => array('foo', 'bar'), 1337 => array('baz', 'qux'),
),
);
$configs[] = array(
'thing' => array(
array('foo', 'bar', 'id' => 42), array('baz', 'qux', 'id' => 1337),
),
);
return array_map(function($v) { return array($v); }, $configs);
}
/**
* @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
* @expectedExceptionMessage The attribute "id" must be set for path "root.thing".
*/
public function testNonAssociativeArrayThrowsExceptionIfAttributeNotSet()
{
$denormalized = array(
'thing' => array(
array('foo', 'bar'), array('baz', 'qux')
)
);
$this->assertNormalized($this->getNumericKeysTestTree(), $denormalized, array());
}
public static function assertNormalized(NodeInterface $tree, $denormalized, $normalized)
{
self::assertSame($normalized, $tree->normalize($denormalized));
}
private function getNumericKeysTestTree()
{
$tb = new TreeBuilder();
$tree = $tb
->root('root', 'array')
->children()
->node('thing', 'array')
->useAttributeAsKey('id')
->prototype('array')
->prototype('scalar')->end()
->end()
->end()
->end()
->end()
->buildTree()
;
return $tree;
}
}