Skip to content

Commit

Permalink
[Config] added EnumNode
Browse files Browse the repository at this point in the history
  • Loading branch information
schmittjoh committed May 26, 2012
1 parent ff4d446 commit 8308aea
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 2 deletions.
@@ -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);
}
}
13 changes: 13 additions & 0 deletions src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php
Expand Up @@ -32,6 +32,7 @@ public function __construct()
'scalar' => __NAMESPACE__.'\\ScalarNodeDefinition',
'boolean' => __NAMESPACE__.'\\BooleanNodeDefinition',
'array' => __NAMESPACE__.'\\ArrayNodeDefinition',
'enum' => __NAMESPACE__.'\\EnumNodeDefinition',
);
}

Expand Down Expand Up @@ -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.
*
Expand Down
Expand Up @@ -29,5 +29,4 @@ protected function instantiateNode()
{
return new ScalarNode($this->name, $this->parent);
}

}
50 changes: 50 additions & 0 deletions src/Symfony/Component/Config/Definition/EnumNode.php
@@ -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;
}
}
@@ -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());
}
}
41 changes: 41 additions & 0 deletions src/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php
@@ -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');
}
}
Expand Up @@ -17,7 +17,6 @@

class FinalizationTest extends \PHPUnit_Framework_TestCase
{

public function testUnsetKeyWithDeepHierarchy()
{
$tb = new TreeBuilder();
Expand Down

0 comments on commit 8308aea

Please sign in to comment.