Skip to content

Commit d54d451

Browse files
feature #58428 [Config] Add StringNode (raffaelecarelle)
This PR was squashed before being merged into the 7.2 branch. Discussion ---------- [Config] Add `StringNode` | Q | A | ------------- | --- | Branch? | 7.2 | Bug fix? | no | New feature? | yes | Deprecations? | no | Issues | Fix #57660 | License | MIT Introduce the `StringNode` class to handle string values within the configuration tree. Added validation for incorrect types and complemented it with unit tests to verify both valid and invalid scenarios. Introduce the `StringNode` class to handle string values within the configuration tree. Commits ------- 88b53a0fa05 [Config] Add `StringNode`
2 parents 7d1c2fc + 0cd83b2 commit d54d451

8 files changed

+155
-0
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ CHANGELOG
88
* Generate a meta file in JSON format for resource tracking
99
* Add `SkippingResourceChecker`
1010
* Add support for `defaultNull()` on `BooleanNode`
11+
* Add `StringNode` and `StringNodeDefinition`
12+
* Add `ArrayNodeDefinition::stringPrototype()` method
13+
* Add `NodeBuilder::stringNode()` method
1114

1215
7.1
1316
---

Definition/Builder/ArrayNodeDefinition.php

+5
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ public function scalarPrototype(): ScalarNodeDefinition
7373
return $this->prototype('scalar');
7474
}
7575

76+
public function stringPrototype(): StringNodeDefinition
77+
{
78+
return $this->prototype('string');
79+
}
80+
7681
public function booleanPrototype(): BooleanNodeDefinition
7782
{
7883
return $this->prototype('boolean');

Definition/Builder/NodeBuilder.php

+9
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public function __construct()
3131
'float' => FloatNodeDefinition::class,
3232
'array' => ArrayNodeDefinition::class,
3333
'enum' => EnumNodeDefinition::class,
34+
'string' => StringNodeDefinition::class,
3435
];
3536
}
3637

@@ -102,6 +103,14 @@ public function variableNode(string $name): VariableNodeDefinition
102103
return $this->node($name, 'variable');
103104
}
104105

106+
/**
107+
* Creates a child string node.
108+
*/
109+
public function stringNode(string $name): StringNodeDefinition
110+
{
111+
return $this->node($name, 'string');
112+
}
113+
105114
/**
106115
* Returns the parent node.
107116
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Definition\Builder;
13+
14+
use Symfony\Component\Config\Definition\StringNode;
15+
16+
/**
17+
* This class provides a fluent interface for defining a node.
18+
*
19+
* @author Raffaele Carelle <[email protected]>
20+
*/
21+
class StringNodeDefinition extends ScalarNodeDefinition
22+
{
23+
public function __construct(?string $name, ?NodeParentInterface $parent = null)
24+
{
25+
parent::__construct($name, $parent);
26+
27+
$this->nullEquivalent = '';
28+
}
29+
30+
protected function instantiateNode(): StringNode
31+
{
32+
return new StringNode($this->name, $this->parent, $this->pathSeparator);
33+
}
34+
}

Definition/StringNode.php

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Definition;
13+
14+
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
15+
16+
/**
17+
* This node represents a String value in the config tree.
18+
*
19+
* @author Raffaele Carelle <[email protected]>
20+
*/
21+
class StringNode extends ScalarNode
22+
{
23+
protected function validateType(mixed $value): void
24+
{
25+
if (!\is_string($value)) {
26+
$ex = new InvalidTypeException(\sprintf('Invalid type for path "%s". Expected "string", but got "%s".', $this->getPath(), get_debug_type($value)));
27+
if ($hint = $this->getInfo()) {
28+
$ex->addHint($hint);
29+
}
30+
$ex->setPath($this->getPath());
31+
32+
throw $ex;
33+
}
34+
}
35+
36+
protected function getValidPlaceholderTypes(): array
37+
{
38+
return ['string'];
39+
}
40+
}

Tests/Definition/Builder/ArrayNodeDefinitionTest.php

+6
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,12 @@ public function testPrototypeBoolean()
267267
$this->assertEquals($node->prototype('boolean'), $node->booleanPrototype());
268268
}
269269

270+
public function testPrototypeString()
271+
{
272+
$node = new ArrayNodeDefinition('root');
273+
$this->assertEquals($node->prototype('string'), $node->stringPrototype());
274+
}
275+
270276
public function testPrototypeInteger()
271277
{
272278
$node = new ArrayNodeDefinition('root');

Tests/Definition/Builder/NodeBuilderTest.php

+9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\Config\Definition\Builder\FloatNodeDefinition;
1616
use Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition;
1717
use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder;
18+
use Symfony\Component\Config\Definition\Builder\StringNodeDefinition;
1819
use Symfony\Component\Config\Definition\Builder\VariableNodeDefinition as BaseVariableNodeDefinition;
1920

2021
class NodeBuilderTest extends TestCase
@@ -86,6 +87,14 @@ public function testNumericNodeCreation()
8687
$node = $builder->floatNode('bar')->min(3.0)->max(5.0);
8788
$this->assertInstanceOf(FloatNodeDefinition::class, $node);
8889
}
90+
91+
public function testStringNodeCreation()
92+
{
93+
$builder = new BaseNodeBuilder();
94+
95+
$node = $builder->stringNode('foo bar');
96+
$this->assertInstanceOf(StringNodeDefinition::class, $node);
97+
}
8998
}
9099

91100
class SomeNodeDefinition extends BaseVariableNodeDefinition

Tests/Definition/StringNodeTest.php

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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 PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
16+
use Symfony\Component\Config\Definition\StringNode;
17+
18+
class StringNodeTest extends TestCase
19+
{
20+
/**
21+
* @testWith [""]
22+
* ["valid string"]
23+
*/
24+
public function testNormalize(string $value)
25+
{
26+
$node = new StringNode('test');
27+
$this->assertSame($value, $node->normalize($value));
28+
}
29+
30+
/**
31+
* @testWith [null]
32+
* [false]
33+
* [true]
34+
* [0]
35+
* [1]
36+
* [0.0]
37+
* [0.1]
38+
* [{}]
39+
* [{"foo": "bar"}]
40+
*/
41+
public function testNormalizeThrowsExceptionOnInvalidValues($value)
42+
{
43+
$node = new StringNode('test');
44+
45+
$this->expectException(InvalidTypeException::class);
46+
47+
$node->normalize($value);
48+
}
49+
}

0 commit comments

Comments
 (0)