0fd4af976784a169eed5a188553c52bf8e4903a1
[yaffs-website] / vendor / symfony / config / Tests / Definition / Builder / ArrayNodeDefinitionTest.php
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\Builder;
13
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
16 use Symfony\Component\Config\Definition\Processor;
17 use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
18 use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
19
20 class ArrayNodeDefinitionTest extends TestCase
21 {
22     public function testAppendingSomeNode()
23     {
24         $parent = new ArrayNodeDefinition('root');
25         $child = new ScalarNodeDefinition('child');
26
27         $parent
28             ->children()
29                 ->scalarNode('foo')->end()
30                 ->scalarNode('bar')->end()
31             ->end()
32             ->append($child);
33
34         $this->assertCount(3, $this->getField($parent, 'children'));
35         $this->assertContains($child, $this->getField($parent, 'children'));
36     }
37
38     /**
39      * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
40      * @dataProvider providePrototypeNodeSpecificCalls
41      */
42     public function testPrototypeNodeSpecificOption($method, $args)
43     {
44         $node = new ArrayNodeDefinition('root');
45
46         call_user_func_array(array($node, $method), $args);
47
48         $node->getNode();
49     }
50
51     public function providePrototypeNodeSpecificCalls()
52     {
53         return array(
54             array('defaultValue', array(array())),
55             array('addDefaultChildrenIfNoneSet', array()),
56             array('requiresAtLeastOneElement', array()),
57             array('useAttributeAsKey', array('foo')),
58         );
59     }
60
61     /**
62      * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
63      */
64     public function testConcreteNodeSpecificOption()
65     {
66         $node = new ArrayNodeDefinition('root');
67         $node
68             ->addDefaultsIfNotSet()
69             ->prototype('array')
70         ;
71         $node->getNode();
72     }
73
74     /**
75      * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
76      */
77     public function testPrototypeNodesCantHaveADefaultValueWhenUsingDefaultChildren()
78     {
79         $node = new ArrayNodeDefinition('root');
80         $node
81             ->defaultValue(array())
82             ->addDefaultChildrenIfNoneSet('foo')
83             ->prototype('array')
84         ;
85         $node->getNode();
86     }
87
88     public function testPrototypedArrayNodeDefaultWhenUsingDefaultChildren()
89     {
90         $node = new ArrayNodeDefinition('root');
91         $node
92             ->addDefaultChildrenIfNoneSet()
93             ->prototype('array')
94         ;
95         $tree = $node->getNode();
96         $this->assertEquals(array(array()), $tree->getDefaultValue());
97     }
98
99     /**
100      * @dataProvider providePrototypedArrayNodeDefaults
101      */
102     public function testPrototypedArrayNodeDefault($args, $shouldThrowWhenUsingAttrAsKey, $shouldThrowWhenNotUsingAttrAsKey, $defaults)
103     {
104         $node = new ArrayNodeDefinition('root');
105         $node
106             ->addDefaultChildrenIfNoneSet($args)
107             ->prototype('array')
108         ;
109
110         try {
111             $tree = $node->getNode();
112             $this->assertFalse($shouldThrowWhenNotUsingAttrAsKey);
113             $this->assertEquals($defaults, $tree->getDefaultValue());
114         } catch (InvalidDefinitionException $e) {
115             $this->assertTrue($shouldThrowWhenNotUsingAttrAsKey);
116         }
117
118         $node = new ArrayNodeDefinition('root');
119         $node
120             ->useAttributeAsKey('attr')
121             ->addDefaultChildrenIfNoneSet($args)
122             ->prototype('array')
123         ;
124
125         try {
126             $tree = $node->getNode();
127             $this->assertFalse($shouldThrowWhenUsingAttrAsKey);
128             $this->assertEquals($defaults, $tree->getDefaultValue());
129         } catch (InvalidDefinitionException $e) {
130             $this->assertTrue($shouldThrowWhenUsingAttrAsKey);
131         }
132     }
133
134     public function providePrototypedArrayNodeDefaults()
135     {
136         return array(
137             array(null, true, false, array(array())),
138             array(2, true, false, array(array(), array())),
139             array('2', false, true, array('2' => array())),
140             array('foo', false, true, array('foo' => array())),
141             array(array('foo'), false, true, array('foo' => array())),
142             array(array('foo', 'bar'), false, true, array('foo' => array(), 'bar' => array())),
143         );
144     }
145
146     public function testNestedPrototypedArrayNodes()
147     {
148         $nodeDefinition = new ArrayNodeDefinition('root');
149         $nodeDefinition
150             ->addDefaultChildrenIfNoneSet()
151             ->prototype('array')
152                   ->prototype('array')
153         ;
154         $node = $nodeDefinition->getNode();
155
156         $this->assertInstanceOf('Symfony\Component\Config\Definition\PrototypedArrayNode', $node);
157         $this->assertInstanceOf('Symfony\Component\Config\Definition\PrototypedArrayNode', $node->getPrototype());
158     }
159
160     public function testEnabledNodeDefaults()
161     {
162         $node = new ArrayNodeDefinition('root');
163         $node
164             ->canBeEnabled()
165             ->children()
166                 ->scalarNode('foo')->defaultValue('bar')->end()
167         ;
168
169         $this->assertEquals(array('enabled' => false, 'foo' => 'bar'), $node->getNode()->getDefaultValue());
170     }
171
172     /**
173      * @dataProvider getEnableableNodeFixtures
174      */
175     public function testTrueEnableEnabledNode($expected, $config, $message)
176     {
177         $processor = new Processor();
178         $node = new ArrayNodeDefinition('root');
179         $node
180             ->canBeEnabled()
181             ->children()
182                 ->scalarNode('foo')->defaultValue('bar')->end()
183         ;
184
185         $this->assertEquals(
186             $expected,
187             $processor->process($node->getNode(), $config),
188             $message
189         );
190     }
191
192     public function testCanBeDisabled()
193     {
194         $node = new ArrayNodeDefinition('root');
195         $node->canBeDisabled();
196
197         $this->assertTrue($this->getField($node, 'addDefaults'));
198         $this->assertEquals(array('enabled' => false), $this->getField($node, 'falseEquivalent'));
199         $this->assertEquals(array('enabled' => true), $this->getField($node, 'trueEquivalent'));
200         $this->assertEquals(array('enabled' => true), $this->getField($node, 'nullEquivalent'));
201
202         $nodeChildren = $this->getField($node, 'children');
203         $this->assertArrayHasKey('enabled', $nodeChildren);
204
205         $enabledNode = $nodeChildren['enabled'];
206         $this->assertTrue($this->getField($enabledNode, 'default'));
207         $this->assertTrue($this->getField($enabledNode, 'defaultValue'));
208     }
209
210     public function testIgnoreExtraKeys()
211     {
212         $node = new ArrayNodeDefinition('root');
213
214         $this->assertFalse($this->getField($node, 'ignoreExtraKeys'));
215
216         $result = $node->ignoreExtraKeys();
217
218         $this->assertEquals($node, $result);
219         $this->assertTrue($this->getField($node, 'ignoreExtraKeys'));
220     }
221
222     public function testNormalizeKeys()
223     {
224         $node = new ArrayNodeDefinition('root');
225
226         $this->assertTrue($this->getField($node, 'normalizeKeys'));
227
228         $result = $node->normalizeKeys(false);
229
230         $this->assertEquals($node, $result);
231         $this->assertFalse($this->getField($node, 'normalizeKeys'));
232     }
233
234     public function testPrototypeVariable()
235     {
236         $node = new ArrayNodeDefinition('root');
237         $this->assertEquals($node->prototype('variable'), $node->variablePrototype());
238     }
239
240     public function testPrototypeScalar()
241     {
242         $node = new ArrayNodeDefinition('root');
243         $this->assertEquals($node->prototype('scalar'), $node->scalarPrototype());
244     }
245
246     public function testPrototypeBoolean()
247     {
248         $node = new ArrayNodeDefinition('root');
249         $this->assertEquals($node->prototype('boolean'), $node->booleanPrototype());
250     }
251
252     public function testPrototypeInteger()
253     {
254         $node = new ArrayNodeDefinition('root');
255         $this->assertEquals($node->prototype('integer'), $node->integerPrototype());
256     }
257
258     public function testPrototypeFloat()
259     {
260         $node = new ArrayNodeDefinition('root');
261         $this->assertEquals($node->prototype('float'), $node->floatPrototype());
262     }
263
264     public function testPrototypeArray()
265     {
266         $node = new ArrayNodeDefinition('root');
267         $this->assertEquals($node->prototype('array'), $node->arrayPrototype());
268     }
269
270     public function testPrototypeEnum()
271     {
272         $node = new ArrayNodeDefinition('root');
273         $this->assertEquals($node->prototype('enum'), $node->enumPrototype());
274     }
275
276     public function getEnableableNodeFixtures()
277     {
278         return array(
279             array(array('enabled' => true, 'foo' => 'bar'), array(true), 'true enables an enableable node'),
280             array(array('enabled' => true, 'foo' => 'bar'), array(null), 'null enables an enableable node'),
281             array(array('enabled' => true, 'foo' => 'bar'), array(array('enabled' => true)), 'An enableable node can be enabled'),
282             array(array('enabled' => true, 'foo' => 'baz'), array(array('foo' => 'baz')), 'any configuration enables an enableable node'),
283             array(array('enabled' => false, 'foo' => 'baz'), array(array('foo' => 'baz', 'enabled' => false)), 'An enableable node can be disabled'),
284             array(array('enabled' => false, 'foo' => 'bar'), array(false), 'false disables an enableable node'),
285         );
286     }
287
288     public function testRequiresAtLeastOneElement()
289     {
290         $node = new ArrayNodeDefinition('root');
291         $node
292             ->requiresAtLeastOneElement()
293             ->integerPrototype();
294
295         $node->getNode()->finalize(array(1));
296
297         $this->addToAssertionCount(1);
298     }
299
300     /**
301      * @group legacy
302      * @expectedDeprecation Using Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition::cannotBeEmpty() at path "root" has no effect, consider requiresAtLeastOneElement() instead. In 4.0 both methods will behave the same.
303      */
304     public function testCannotBeEmpty()
305     {
306         $node = new ArrayNodeDefinition('root');
307         $node
308             ->cannotBeEmpty()
309             ->integerPrototype();
310
311         $node->getNode()->finalize(array());
312     }
313
314     public function testSetDeprecated()
315     {
316         $node = new ArrayNodeDefinition('root');
317         $node
318             ->children()
319                 ->arrayNode('foo')->setDeprecated('The "%path%" node is deprecated.')->end()
320             ->end()
321         ;
322         $deprecatedNode = $node->getNode()->getChildren()['foo'];
323
324         $this->assertTrue($deprecatedNode->isDeprecated());
325         $this->assertSame('The "root.foo" node is deprecated.', $deprecatedNode->getDeprecationMessage($deprecatedNode->getName(), $deprecatedNode->getPath()));
326     }
327
328     /**
329      * @group legacy
330      * @expectedDeprecation ->cannotBeEmpty() is not applicable to concrete nodes at path "root". In 4.0 it will throw an exception.
331      */
332     public function testCannotBeEmptyOnConcreteNode()
333     {
334         $node = new ArrayNodeDefinition('root');
335         $node->cannotBeEmpty();
336
337         $node->getNode()->finalize(array());
338     }
339
340     protected function getField($object, $field)
341     {
342         $reflection = new \ReflectionProperty($object, $field);
343         $reflection->setAccessible(true);
344
345         return $reflection->getValue($object);
346     }
347 }