From 8308aea9d17c3abb0d69e11fa9f8b5f600a564cd Mon Sep 17 00:00:00 2001 From: "Johannes M. Schmitt" Date: Fri, 25 May 2012 22:44:51 -0500 Subject: [PATCH] [Config] added EnumNode --- .../Definition/Builder/EnumNodeDefinition.php | 41 +++++++++++++++ .../Config/Definition/Builder/NodeBuilder.php | 13 +++++ .../Builder/ScalarNodeDefinition.php | 1 - .../Component/Config/Definition/EnumNode.php | 50 +++++++++++++++++++ .../Builder/EnumNodeDefinitionTest.php | 37 ++++++++++++++ .../Config/Tests/Definition/EnumNodeTest.php | 41 +++++++++++++++ .../Tests/Definition/FinalizationTest.php | 1 - 7 files changed, 182 insertions(+), 2 deletions(-) create mode 100755 src/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php create mode 100755 src/Symfony/Component/Config/Definition/EnumNode.php create mode 100755 src/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php create mode 100755 src/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php diff --git a/src/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php new file mode 100755 index 0000000000000..ff47958705179 --- /dev/null +++ b/src/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php @@ -0,0 +1,41 @@ + + */ +class EnumNodeDefinition extends ScalarNodeDefinition +{ + private $values; + + public function values(array $values) + { + $values = array_unique($values); + + if (count($values) <= 1) { + throw new \InvalidArgumentException('->values() must be called with at least two distinct values.'); + } + + $this->values = $values; + } + + /** + * Instantiate a Node + * + * @return EnumNode The node + */ + protected function instantiateNode() + { + if (null === $this->values) { + throw new \RuntimeException('You must call ->values() on enum nodes.'); + } + + return new EnumNode($this->name, $this->parent, $this->values); + } +} \ No newline at end of file diff --git a/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php b/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php index 021e0651af431..c960ac43a6c12 100644 --- a/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php +++ b/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php @@ -32,6 +32,7 @@ public function __construct() 'scalar' => __NAMESPACE__.'\\ScalarNodeDefinition', 'boolean' => __NAMESPACE__.'\\BooleanNodeDefinition', 'array' => __NAMESPACE__.'\\ArrayNodeDefinition', + 'enum' => __NAMESPACE__.'\\EnumNodeDefinition', ); } @@ -85,6 +86,18 @@ public function booleanNode($name) return $this->node($name, 'boolean'); } + /** + * Creates a child EnumNode. + * + * @param string $name + * + * @return EnumNodeDefinition + */ + public function enumNode($name) + { + return $this->node($name, 'enum'); + } + /** * Creates a child variable node. * diff --git a/src/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php index 0307ecd6e2bb9..6a115fe1d1ae2 100644 --- a/src/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php +++ b/src/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php @@ -29,5 +29,4 @@ protected function instantiateNode() { return new ScalarNode($this->name, $this->parent); } - } diff --git a/src/Symfony/Component/Config/Definition/EnumNode.php b/src/Symfony/Component/Config/Definition/EnumNode.php new file mode 100755 index 0000000000000..301dfd76351f8 --- /dev/null +++ b/src/Symfony/Component/Config/Definition/EnumNode.php @@ -0,0 +1,50 @@ + + */ +class EnumNode extends ScalarNode +{ + private $values; + + public function __construct($name, NodeInterface $parent = null, array $values = array()) + { + $values = array_unique($values); + if (count($values) <= 1) { + throw new \InvalidArgumentException('$values must contain at least two distinct elements.'); + } + + parent::__construct($name, $parent); + $this->values = $values; + } + + public function getValues() + { + return $this->values; + } + + protected function finalizeValue($value) + { + $value = parent::finalizeValue($value); + + if (!in_array($value, $this->values, true)) { + $ex = new InvalidConfigurationException(sprintf( + 'The value %s is not allowed for path "%s". Permissible values: %s', + json_encode($value), + $this->getPath(), + implode(', ', array_map('json_encode', $this->values)))); + $ex->setPath($this->getPath()); + + throw $ex; + } + + return $value; + } +} \ No newline at end of file diff --git a/src/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php b/src/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php new file mode 100755 index 0000000000000..9f1955e4d0791 --- /dev/null +++ b/src/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php @@ -0,0 +1,37 @@ +values() must be called with at least two distinct values. + */ + public function testNoDistinctValues() + { + $def = new EnumNodeDefinition('foo'); + $def->values(array('foo', 'foo')); + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage You must call ->values() on enum nodes. + */ + public function testNoValuesPassed() + { + $def = new EnumNodeDefinition('foo'); + $def->getNode(); + } + + public function testGetNode() + { + $def = new EnumNodeDefinition('foo'); + $def->values(array('foo', 'bar')); + + $node = $def->getNode(); + $this->assertEquals(array('foo', 'bar'), $node->getValues()); + } +} \ No newline at end of file diff --git a/src/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php new file mode 100755 index 0000000000000..9c18da6276af0 --- /dev/null +++ b/src/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use Symfony\Component\Config\Definition\EnumNode; + +class EnumNodeTest extends \PHPUnit_Framework_TestCase +{ + public function testFinalizeValue() + { + $node = new EnumNode('foo', null, array('foo', 'bar')); + $this->assertSame('foo', $node->finalize('foo')); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testConstructionWithOneValue() + { + new EnumNode('foo', null, array('foo', 'foo')); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * @expectedExceptionMessage The value "foobar" is not allowed for path "foo". Permissible values: "foo", "bar" + */ + public function testFinalizeWithInvalidValue() + { + $node = new EnumNode('foo', null, array('foo', 'bar')); + $node->finalize('foobar'); + } +} \ No newline at end of file diff --git a/src/Symfony/Component/Config/Tests/Definition/FinalizationTest.php b/src/Symfony/Component/Config/Tests/Definition/FinalizationTest.php index 29a556f100f38..19fc347d8f060 100644 --- a/src/Symfony/Component/Config/Tests/Definition/FinalizationTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/FinalizationTest.php @@ -17,7 +17,6 @@ class FinalizationTest extends \PHPUnit_Framework_TestCase { - public function testUnsetKeyWithDeepHierarchy() { $tb = new TreeBuilder();