Yaffs site version 1.1
[yaffs-website] / vendor / symfony / config / Tests / Definition / PrototypedArrayNodeTest.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;
13
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\Config\Definition\PrototypedArrayNode;
16 use Symfony\Component\Config\Definition\ArrayNode;
17 use Symfony\Component\Config\Definition\ScalarNode;
18 use Symfony\Component\Config\Definition\VariableNode;
19
20 class PrototypedArrayNodeTest extends TestCase
21 {
22     public function testGetDefaultValueReturnsAnEmptyArrayForPrototypes()
23     {
24         $node = new PrototypedArrayNode('root');
25         $prototype = new ArrayNode(null, $node);
26         $node->setPrototype($prototype);
27         $this->assertEmpty($node->getDefaultValue());
28     }
29
30     public function testGetDefaultValueReturnsDefaultValueForPrototypes()
31     {
32         $node = new PrototypedArrayNode('root');
33         $prototype = new ArrayNode(null, $node);
34         $node->setPrototype($prototype);
35         $node->setDefaultValue(array('test'));
36         $this->assertEquals(array('test'), $node->getDefaultValue());
37     }
38
39     // a remapped key (e.g. "mapping" -> "mappings") should be unset after being used
40     public function testRemappedKeysAreUnset()
41     {
42         $node = new ArrayNode('root');
43         $mappingsNode = new PrototypedArrayNode('mappings');
44         $node->addChild($mappingsNode);
45
46         // each item under mappings is just a scalar
47         $prototype = new ScalarNode(null, $mappingsNode);
48         $mappingsNode->setPrototype($prototype);
49
50         $remappings = array();
51         $remappings[] = array('mapping', 'mappings');
52         $node->setXmlRemappings($remappings);
53
54         $normalized = $node->normalize(array('mapping' => array('foo', 'bar')));
55         $this->assertEquals(array('mappings' => array('foo', 'bar')), $normalized);
56     }
57
58     /**
59      * Tests that when a key attribute is mapped, that key is removed from the array.
60      *
61      *     <things>
62      *         <option id="option1" value="foo">
63      *         <option id="option2" value="bar">
64      *     </things>
65      *
66      * The above should finally be mapped to an array that looks like this
67      * (because "id" is the key attribute).
68      *
69      *     array(
70      *         'things' => array(
71      *             'option1' => 'foo',
72      *             'option2' => 'bar',
73      *         )
74      *     )
75      */
76     public function testMappedAttributeKeyIsRemoved()
77     {
78         $node = new PrototypedArrayNode('root');
79         $node->setKeyAttribute('id', true);
80
81         // each item under the root is an array, with one scalar item
82         $prototype = new ArrayNode(null, $node);
83         $prototype->addChild(new ScalarNode('foo'));
84         $node->setPrototype($prototype);
85
86         $children = array();
87         $children[] = array('id' => 'item_name', 'foo' => 'bar');
88         $normalized = $node->normalize($children);
89
90         $expected = array();
91         $expected['item_name'] = array('foo' => 'bar');
92         $this->assertEquals($expected, $normalized);
93     }
94
95     /**
96      * Tests the opposite of the testMappedAttributeKeyIsRemoved because
97      * the removal can be toggled with an option.
98      */
99     public function testMappedAttributeKeyNotRemoved()
100     {
101         $node = new PrototypedArrayNode('root');
102         $node->setKeyAttribute('id', false);
103
104         // each item under the root is an array, with two scalar items
105         $prototype = new ArrayNode(null, $node);
106         $prototype->addChild(new ScalarNode('foo'));
107         $prototype->addChild(new ScalarNode('id')); // the key attribute will remain
108         $node->setPrototype($prototype);
109
110         $children = array();
111         $children[] = array('id' => 'item_name', 'foo' => 'bar');
112         $normalized = $node->normalize($children);
113
114         $expected = array();
115         $expected['item_name'] = array('id' => 'item_name', 'foo' => 'bar');
116         $this->assertEquals($expected, $normalized);
117     }
118
119     public function testAddDefaultChildren()
120     {
121         $node = $this->getPrototypeNodeWithDefaultChildren();
122         $node->setAddChildrenIfNoneSet();
123         $this->assertTrue($node->hasDefaultValue());
124         $this->assertEquals(array(array('foo' => 'bar')), $node->getDefaultValue());
125
126         $node = $this->getPrototypeNodeWithDefaultChildren();
127         $node->setKeyAttribute('foobar');
128         $node->setAddChildrenIfNoneSet();
129         $this->assertTrue($node->hasDefaultValue());
130         $this->assertEquals(array('defaults' => array('foo' => 'bar')), $node->getDefaultValue());
131
132         $node = $this->getPrototypeNodeWithDefaultChildren();
133         $node->setKeyAttribute('foobar');
134         $node->setAddChildrenIfNoneSet('defaultkey');
135         $this->assertTrue($node->hasDefaultValue());
136         $this->assertEquals(array('defaultkey' => array('foo' => 'bar')), $node->getDefaultValue());
137
138         $node = $this->getPrototypeNodeWithDefaultChildren();
139         $node->setKeyAttribute('foobar');
140         $node->setAddChildrenIfNoneSet(array('defaultkey'));
141         $this->assertTrue($node->hasDefaultValue());
142         $this->assertEquals(array('defaultkey' => array('foo' => 'bar')), $node->getDefaultValue());
143
144         $node = $this->getPrototypeNodeWithDefaultChildren();
145         $node->setKeyAttribute('foobar');
146         $node->setAddChildrenIfNoneSet(array('dk1', 'dk2'));
147         $this->assertTrue($node->hasDefaultValue());
148         $this->assertEquals(array('dk1' => array('foo' => 'bar'), 'dk2' => array('foo' => 'bar')), $node->getDefaultValue());
149
150         $node = $this->getPrototypeNodeWithDefaultChildren();
151         $node->setAddChildrenIfNoneSet(array(5, 6));
152         $this->assertTrue($node->hasDefaultValue());
153         $this->assertEquals(array(0 => array('foo' => 'bar'), 1 => array('foo' => 'bar')), $node->getDefaultValue());
154
155         $node = $this->getPrototypeNodeWithDefaultChildren();
156         $node->setAddChildrenIfNoneSet(2);
157         $this->assertTrue($node->hasDefaultValue());
158         $this->assertEquals(array(array('foo' => 'bar'), array('foo' => 'bar')), $node->getDefaultValue());
159     }
160
161     public function testDefaultChildrenWinsOverDefaultValue()
162     {
163         $node = $this->getPrototypeNodeWithDefaultChildren();
164         $node->setAddChildrenIfNoneSet();
165         $node->setDefaultValue(array('bar' => 'foo'));
166         $this->assertTrue($node->hasDefaultValue());
167         $this->assertEquals(array(array('foo' => 'bar')), $node->getDefaultValue());
168     }
169
170     protected function getPrototypeNodeWithDefaultChildren()
171     {
172         $node = new PrototypedArrayNode('root');
173         $prototype = new ArrayNode(null, $node);
174         $child = new ScalarNode('foo');
175         $child->setDefaultValue('bar');
176         $prototype->addChild($child);
177         $prototype->setAddIfNotSet(true);
178         $node->setPrototype($prototype);
179
180         return $node;
181     }
182
183     /**
184      * Tests that when a key attribute is mapped, that key is removed from the array.
185      * And if only 'value' element is left in the array, it will replace its wrapper array.
186      *
187      *     <things>
188      *         <option id="option1" value="value1">
189      *     </things>
190      *
191      * The above should finally be mapped to an array that looks like this
192      * (because "id" is the key attribute).
193      *
194      *     array(
195      *         'things' => array(
196      *             'option1' => 'value1'
197      *         )
198      *     )
199      *
200      * It's also possible to mix 'value-only' and 'non-value-only' elements in the array.
201      *
202      * <things>
203      *     <option id="option1" value="value1">
204      *     <option id="option2" value="value2" foo="foo2">
205      * </things>
206      *
207      * The above should finally be mapped to an array as follows
208      *
209      * array(
210      *     'things' => array(
211      *         'option1' => 'value1',
212      *         'option2' => array(
213      *             'value' => 'value2',
214      *             'foo' => 'foo2'
215      *         )
216      *     )
217      * )
218      *
219      * The 'value' element can also be ArrayNode:
220      *
221      * <things>
222      *     <option id="option1">
223      *         <value>
224      *            <foo>foo1</foo>
225      *            <bar>bar1</bar>
226      *         </value>
227      *     </option>
228      * </things>
229      *
230      * The above should be finally be mapped to an array as follows
231      *
232      * array(
233      *     'things' => array(
234      *         'option1' => array(
235      *             'foo' => 'foo1',
236      *             'bar' => 'bar1'
237      *         )
238      *     )
239      * )
240      *
241      * If using VariableNode for value node, it's also possible to mix different types of value nodes:
242      *
243      * <things>
244      *     <option id="option1">
245      *         <value>
246      *            <foo>foo1</foo>
247      *            <bar>bar1</bar>
248      *         </value>
249      *     </option>
250      *     <option id="option2" value="value2">
251      * </things>
252      *
253      * The above should be finally mapped to an array as follows
254      *
255      * array(
256      *     'things' => array(
257      *         'option1' => array(
258      *             'foo' => 'foo1',
259      *             'bar' => 'bar1'
260      *         ),
261      *         'option2' => 'value2'
262      *     )
263      * )
264      *
265      *
266      * @dataProvider getDataForKeyRemovedLeftValueOnly
267      */
268     public function testMappedAttributeKeyIsRemovedLeftValueOnly($value, $children, $expected)
269     {
270         $node = new PrototypedArrayNode('root');
271         $node->setKeyAttribute('id', true);
272
273         // each item under the root is an array, with one scalar item
274         $prototype = new ArrayNode(null, $node);
275         $prototype->addChild(new ScalarNode('id'));
276         $prototype->addChild(new ScalarNode('foo'));
277         $prototype->addChild($value);
278         $node->setPrototype($prototype);
279
280         $normalized = $node->normalize($children);
281         $this->assertEquals($expected, $normalized);
282     }
283
284     public function getDataForKeyRemovedLeftValueOnly()
285     {
286         $scalarValue = new ScalarNode('value');
287
288         $arrayValue = new ArrayNode('value');
289         $arrayValue->addChild(new ScalarNode('foo'));
290         $arrayValue->addChild(new ScalarNode('bar'));
291
292         $variableValue = new VariableNode('value');
293
294         return array(
295            array(
296                $scalarValue,
297                array(
298                    array('id' => 'option1', 'value' => 'value1'),
299                ),
300                array('option1' => 'value1'),
301            ),
302
303            array(
304                $scalarValue,
305                array(
306                    array('id' => 'option1', 'value' => 'value1'),
307                    array('id' => 'option2', 'value' => 'value2', 'foo' => 'foo2'),
308                ),
309                array(
310                    'option1' => 'value1',
311                    'option2' => array('value' => 'value2', 'foo' => 'foo2'),
312                ),
313            ),
314
315            array(
316                $arrayValue,
317                array(
318                    array(
319                        'id' => 'option1',
320                        'value' => array('foo' => 'foo1', 'bar' => 'bar1'),
321                    ),
322                ),
323                array(
324                    'option1' => array('foo' => 'foo1', 'bar' => 'bar1'),
325                ),
326            ),
327
328            array($variableValue,
329                array(
330                    array(
331                        'id' => 'option1', 'value' => array('foo' => 'foo1', 'bar' => 'bar1'),
332                    ),
333                    array('id' => 'option2', 'value' => 'value2'),
334                ),
335                array(
336                    'option1' => array('foo' => 'foo1', 'bar' => 'bar1'),
337                    'option2' => 'value2',
338                ),
339            ),
340         );
341     }
342 }