[Config] added EnumNode

This commit is contained in:
Johannes M. Schmitt 2012-05-25 22:44:51 -05:00
parent ff4d446c5e
commit 8308aea9d1
7 changed files with 182 additions and 2 deletions

View File

@ -0,0 +1,41 @@
<?php
namespace Symfony\Component\Config\Definition\Builder;
use Symfony\Component\Config\Definition\EnumNode;
use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
/**
* Enum Node Definition.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
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);
}
}

View File

@ -32,6 +32,7 @@ class NodeBuilder implements NodeParentInterface
'scalar' => __NAMESPACE__.'\\ScalarNodeDefinition',
'boolean' => __NAMESPACE__.'\\BooleanNodeDefinition',
'array' => __NAMESPACE__.'\\ArrayNodeDefinition',
'enum' => __NAMESPACE__.'\\EnumNodeDefinition',
);
}
@ -85,6 +86,18 @@ class NodeBuilder implements NodeParentInterface
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.
*

View File

@ -29,5 +29,4 @@ class ScalarNodeDefinition extends VariableNodeDefinition
{
return new ScalarNode($this->name, $this->parent);
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace Symfony\Component\Config\Definition;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\ScalarNode;
/**
* Node which only allows a finite set of values.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
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;
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace Symfony\Component\Config\Tests\Definition\Builder;
use Symfony\Component\Config\Definition\Builder\EnumNodeDefinition;
class EnumNodeDefinitionTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage ->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());
}
}

View File

@ -0,0 +1,41 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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');
}
}

View File

@ -17,7 +17,6 @@ use Symfony\Component\Config\Definition\NodeInterface;
class FinalizationTest extends \PHPUnit_Framework_TestCase
{
public function testUnsetKeyWithDeepHierarchy()
{
$tb = new TreeBuilder();