From 311e1c4e9e98f34528577a604b2198e16f85eb70 Mon Sep 17 00:00:00 2001 From: Alexandre Parent Date: Mon, 12 Aug 2019 09:40:46 -0400 Subject: [PATCH] [Config] Add handling for ignored keys in ArrayNode::mergeValues. --- .../Component/Config/Definition/ArrayNode.php | 7 ++- .../Config/Tests/Definition/ArrayNodeTest.php | 62 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Config/Definition/ArrayNode.php b/src/Symfony/Component/Config/Definition/ArrayNode.php index e741b8a02d..a063978ef1 100644 --- a/src/Symfony/Component/Config/Definition/ArrayNode.php +++ b/src/Symfony/Component/Config/Definition/ArrayNode.php @@ -396,7 +396,12 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface } if (!isset($this->children[$k])) { - throw new \RuntimeException('merge() expects a normalized config array.'); + if (!$this->ignoreExtraKeys || $this->removeExtraKeys) { + throw new \RuntimeException('merge() expects a normalized config array.'); + } + + $leftSide[$k] = $v; + continue; } $leftSide[$k] = $this->children[$k]->merge($leftSide[$k], $v); diff --git a/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php index 33bede7427..fa91b47b51 100644 --- a/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php @@ -255,4 +255,66 @@ class ArrayNodeTest extends TestCase restore_error_handler(); $this->assertTrue($deprecationTriggered, '->finalize() should trigger if the deprecated node is set'); } + + /** + * @dataProvider getDataWithIncludedExtraKeys + */ + public function testMergeWithoutIgnoringExtraKeys($prenormalizeds, $merged) + { + $this->expectException('RuntimeException'); + $this->expectExceptionMessage('merge() expects a normalized config array.'); + $node = new ArrayNode('root'); + $node->addChild(new ScalarNode('foo')); + $node->addChild(new ScalarNode('bar')); + $node->setIgnoreExtraKeys(false); + + $r = new \ReflectionMethod($node, 'mergeValues'); + $r->setAccessible(true); + + $r->invoke($node, ...$prenormalizeds); + } + + /** + * @dataProvider getDataWithIncludedExtraKeys + */ + public function testMergeWithIgnoringAndRemovingExtraKeys($prenormalizeds, $merged) + { + $this->expectException('RuntimeException'); + $this->expectExceptionMessage('merge() expects a normalized config array.'); + $node = new ArrayNode('root'); + $node->addChild(new ScalarNode('foo')); + $node->addChild(new ScalarNode('bar')); + $node->setIgnoreExtraKeys(true); + + $r = new \ReflectionMethod($node, 'mergeValues'); + $r->setAccessible(true); + + $r->invoke($node, ...$prenormalizeds); + } + + /** + * @dataProvider getDataWithIncludedExtraKeys + */ + public function testMergeWithIgnoringExtraKeys($prenormalizeds, $merged) + { + $node = new ArrayNode('root'); + $node->addChild(new ScalarNode('foo')); + $node->addChild(new ScalarNode('bar')); + $node->setIgnoreExtraKeys(true, false); + + $r = new \ReflectionMethod($node, 'mergeValues'); + $r->setAccessible(true); + + $this->assertEquals($merged, $r->invoke($node, ...$prenormalizeds)); + } + + public function getDataWithIncludedExtraKeys() + { + return [ + [ + [['foo' => 'bar', 'baz' => 'not foo'], ['bar' => 'baz', 'baz' => 'foo']], + ['foo' => 'bar', 'bar' => 'baz', 'baz' => 'foo'], + ], + ]; + } }