8000 [Config] added EnumNode · symfony/symfony@8308aea · GitHub
[go: up one dir, main page]

Skip to content

Commit 8308aea

Browse files
committed
[Config] added EnumNode
1 parent ff4d446 commit 8308aea

File tree

7 files changed

+182
-2
lines changed

7 files changed

+182
-2
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace Symfony\Component\Config\Definition\Builder;
4+
5+
use Symfony\Component\Config\Definition\EnumNode;
6+
use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
7+
8+
/**
9+
* Enum Node Definition.
10+
*
11+
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
12+
*/
13+
class EnumNodeDefinition extends ScalarNodeDefinition
14+
{
15+
private $values;
16+
17+
public function values(array $values)
18+
{
19+
$values = array_unique($values);
20+
21+
if (count($values) <= 1) {
22+
throw new \InvalidArgumentException('->values() must be called with at least two distinct values.');
23+
}
24+
25+
$this->values = $values;
26+
}
27+
28+
/**
29+
* Instantiate a Node
30+
*
31+
* @return EnumNode The node
32+
*/
33+
protected function instantiateNode()
34+
{
35+
if (null === $this->values) {
36+
throw new \RuntimeException('You must call ->values() on enum nodes.');
37+
}
38+
39+
return new EnumNode($this->name, $this->parent, $this->values);
40+
}
41+
}

src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public function __construct()
3232
'scalar' => __NAMESPACE__.'\\ScalarNodeDefinition',
3333
'boolean' => __NAMESPACE__.'\\BooleanNodeDefinition',
3434
'array' => __NAMESPACE__.'\\ArrayNodeDefinition',
35+
'enum' => __NAMESPACE__.'\\EnumNodeDefinition',
3536
);
3637
}
3738

@@ -85,6 +86,18 @@ public function booleanNode($name)
8586
return $this->node($name, 'boolean');
8687
}
8788

89+
/**
90+
* Creates a child EnumNode.
91+
*
92+
* @param string $name
93+
*
94+
* @return EnumNodeDefinition
95+
*/
96+
public function enumNode($name)
97+
{
98+
return $this->node($name, 'enum');
99+
}
100+
88101
/**
89102
* Creates a child variable node.
90103
*

src/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,4 @@ protected function instantiateNode()
2929
{
3030
return new ScalarNode($this->name, $this->parent);
3131
}
32-
3332
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace Symfony\Component\Config\Definition;
4+
5+
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
6+
use Symfony\Component\Config\Definition\ScalarNode;
7+
8+
/**
9+
* Node which only allows a finite set of values.
10+
*
11+
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
12+
*/
13+
class EnumNode extends ScalarNode
14+
{
15+
private $values;
16+
17+
public function __construct($name, NodeInterface $parent = null, array $values = array())
18+
{
19+
$values = array_unique($values);
20+
if (count($values) <= 1) {
21+
throw new \InvalidArgumentException('$values must contain at least two distinct elements.');
22+
}
23+
24+
parent::__construct($name, $parent);
25+
$this->values = $values;
26+
}
27+
28+
public function getValues()
29+
{
30+
return $this->values;
31+
}
32+
33+
protected function finalizeValue($value)
34+
{
35+
$value = parent::finalizeValue($value);
36+
37+
if (!in_array($value, $this->values, true)) {
38+
$ex = new InvalidConfigurationException(sprintf(
39+
'The value %s is not allowed for path "%s". Permissible values: %s',
40+
json_encode($value),
41+
$this->getPath(),
42+
implode(', ', array_map('json_encode', $this->values))));
43+
$ex->setPath($this->getPath());
44+
45+
throw $ex;
46+
}
47+
48+
return $value;
49+
}
50+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace Symfony\Component\Config\Tests\Definition\Builder;
4+
5+
use Symfony\Component\Config\Definition\Builder\EnumNodeDefinition;
6+
7+
class EnumNodeDefinitionTest extends \PHPUnit_Framework_TestCase
8+
{
9+
/**
10+
* @expectedException \InvalidArgumentException
11+
* @expectedExceptionMessage ->values() must be called with at least two distinct values.
12+
*/
13+
public function testNoDistinctValues()
14+
{
15+
$def = new EnumNodeDefinition('foo');
16+
$def->values(array('foo', 'foo'));
17+
}
18+
19+
/**
20+
* @expectedException \RuntimeException
21+
* @expectedExceptionMessage You must call ->values() on enum nodes.
22+
*/
23+
public function testNoValuesPassed()
24+
{
25+
$def = new EnumNodeDefinition('foo');
26+
$def->getNode();
27+
}
28+
29+
public function testGetNode()
30+
{
31+
$def = new EnumNodeDefinition('foo');
32+
$def->values(array('foo', 'bar'));
33+
34+
$node = $def->getNode();
35+
$this->assertEquals(array('foo', 'bar'), $node->getValues());
36+
}
37+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Config\Tests\Definition;
13+
14+
use Symfony\Component\Config\Definition\EnumNode;
15+
16+
class EnumNodeTest extends \PHPUnit_Framework_TestCase
17+
{
18+
public function testFinalizeValue()
19+
{
20+
$node = new EnumNode('foo', null, array('foo', 'bar'));
21+
$this->assertSame('foo', $node->finalize('foo'));
22+
}
23+
24+
/**
25+
* @expectedException \InvalidArgumentException
26+
*/
27+
public function testConstructionWithOneValue()
28+
{
29+
new EnumNode('foo', null, array('foo', 'foo'));
30+
}
31+
32+
/**
33+
* @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
34+
* @expectedExceptionMessage The value "foobar" is not allowed for path "foo". Permissible values: "foo", "bar"
35+
*/
36+
public function testFinalizeWithInvalidValue()
37+
{
38+
$node = new EnumNode('foo', null, array('foo', 'bar'));
39+
$node->finalize('foobar');
40+
}
41+
}

src/Symfony/Component/Config/Tests/Definition/FinalizationTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
class FinalizationTest extends \PHPUnit_Framework_TestCase
1919
{
20-
2120
public function testUnsetKeyWithDeepHierarchy()
2221
{
2322
$tb = new TreeBuilder();

0 commit comments

Comments
 (0)
0