1 <?php
2 
3 /**
4  * Hoa
5  *
6  *
7  * @license
8  *
9  * New BSD License
10  *
11  * Copyright © 2007-2017, Hoa community. All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  *     * Redistributions of source code must retain the above copyright
16  *       notice, this list of conditions and the following disclaimer.
17  *     * Redistributions in binary form must reproduce the above copyright
18  *       notice, this list of conditions and the following disclaimer in the
19  *       documentation and/or other materials provided with the distribution.
20  *     * Neither the name of the Hoa nor the names of its contributors may be
21  *       used to endorse or promote products derived from this software without
22  *       specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
28  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36 
37 namespace Hoa\Compiler\Test\Unit\Llk;
38 
39 use Hoa\Compiler\Llk\TreeNode as SUT;
40 use Hoa\Test;
41 use Hoa\Visitor;
42 
43 /**
44  * Class \Hoa\Compiler\Test\Unit\Llk\TreeNode.
45  *
46  * Test suite of the tree node.
47  *
48  * @copyright  Copyright © 2007-2017 Hoa community
49  * @license    New BSD License
50  */
51 class TreeNode extends Test\Unit\Suite
52 {
53     public function case_is_a_visitor()
54     {
55         $this
56             ->when($node = new SUT('foo'))
57             ->then
58                 ->object($node)
59                     ->isInstanceOf(Visitor\Element::class);
60     }
61 
62     public function case_constructor()
63     {
64         $this
65             ->given($id = 'foo')
66             ->when($node = new SUT($id))
67             ->then
68                 ->string($node->getId())
69                     ->isEqualTo($id)
70                 ->variable($node->getValue())
71                     ->isNull()
72                 ->integer($node->getChildrenNumber())
73                     ->isEqualTo(0)
74                 ->array($node->getChildren())
75                     ->isEmpty()
76                 ->variable($node->getParent())
77                     ->isNull();
78     }
79 
80     public function case_constructor_with_a_value()
81     {
82         $this
83             ->given(
84                 $id    = 'foo',
85                 $value = ['bar']
86             )
87             ->when($node = new SUT($id, $value))
88             ->then
89                 ->string($node->getId())
90                     ->isEqualTo($id)
91                 ->array($node->getValue())
92                     ->isEqualTo($value)
93                 ->integer($node->getChildrenNumber())
94                     ->isEqualTo(0)
95                 ->array($node->getChildren())
96                     ->isEmpty()
97                 ->variable($node->getParent())
98                     ->isNull();
99     }
100 
101     public function case_constructor_with_a_value_and_children()
102     {
103         $this
104             ->given(
105                 $id       = 'foo',
106                 $value    = ['bar'],
107                 $children = [new SUT('baz'), new SUT('qux')]
108             )
109             ->when($node = new SUT($id, $value, $children))
110             ->then
111                 ->string($node->getId())
112                     ->isEqualTo($id)
113                 ->array($node->getValue())
114                     ->isEqualTo($value)
115                 ->integer($node->getChildrenNumber())
116                     ->isEqualTo(2)
117                 ->array($node->getChildren())
118                     ->isEqualTo($children)
119                 ->variable($node->getParent())
120                     ->isNull();
121     }
122 
123     public function case_constructor_with_a_value_and_children_and_a_parent()
124     {
125         $this
126             ->given(
127                 $id       = 'foo',
128                 $value    = ['bar'],
129                 $children = [new SUT('baz'), new SUT('qux')],
130                 $parent   = new SUT('root')
131             )
132             ->when($node = new SUT($id, $value, $children, $parent))
133             ->then
134                 ->string($node->getId())
135                     ->isEqualTo($id)
136                 ->array($node->getValue())
137                     ->isEqualTo($value)
138                 ->integer($node->getChildrenNumber())
139                     ->isEqualTo(2)
140                 ->array($node->getChildren())
141                     ->isEqualTo($children)
142                 ->object($node->getParent())
143                     ->isIdenticalTo($parent);
144     }
145 
146     public function case_set_id()
147     {
148         $this
149             ->given($node = new SUT('foo'))
150             ->when($result = $node->setId('bar'))
151             ->then
152                 ->string($result)
153                     ->isEqualTo('foo');
154     }
155 
156     public function case_get_id()
157     {
158         $this
159             ->given(
160                 $node = new SUT('foo'),
161                 $node->setId('bar')
162             )
163             ->when($result = $node->getId())
164             ->then
165                 ->string($result)
166                     ->isEqualTo('bar');
167     }
168 
169     public function case_set_value()
170     {
171         $this
172             ->given($node = new SUT('foo', ['bar']))
173             ->when($result = $node->setValue(['baz']))
174             ->then
175                 ->array($result)
176                     ->isEqualTo(['bar']);
177     }
178 
179     public function case_get_value()
180     {
181         $this
182             ->given(
183                 $node = new SUT('foo', ['bar']),
184                 $node->setValue(['baz'])
185             )
186             ->when($result = $node->getValue())
187             ->then
188                 ->array($result)
189                     ->isEqualTo(['baz']);
190     }
191 
192     public function case_get_value_token()
193     {
194         $this
195             ->given($node = new SUT('foo', ['token' => 'bar']))
196             ->when($result = $node->getValueToken())
197             ->then
198                 ->string($result)
199                     ->isEqualTo('bar');
200     }
201 
202     public function case_get_value_token_undefined()
203     {
204         $this
205             ->given($node = new SUT('foo', ['bar']))
206             ->when($result = $node->getValueToken())
207             ->then
208                 ->variable($result)
209                     ->isNull();
210     }
211 
212     public function case_get_value_value()
213     {
214         $this
215             ->given($node = new SUT('foo', ['value' => 'bar']))
216             ->when($result = $node->getValueValue())
217             ->then
218                 ->string($result)
219                     ->isEqualTo('bar');
220     }
221 
222     public function case_get_value_value_undefined()
223     {
224         $this
225             ->given($node = new SUT('foo', ['bar']))
226             ->when($result = $node->getValueValue())
227             ->then
228                 ->variable($result)
229                     ->isNull();
230     }
231 
232     public function case_is_token()
233     {
234         $this
235             ->given($node = new SUT('foo', ['bar']))
236             ->when($result = $node->isToken())
237             ->then
238                 ->boolean($result)
239                     ->isTrue();
240     }
241 
242     public function case_is_not_token()
243     {
244         $this
245             ->given($node = new SUT('foo'))
246             ->when($result = $node->isToken())
247             ->then
248                 ->boolean($result)
249                     ->isFalse();
250     }
251 
252     public function case_prepend_child()
253     {
254         $this
255             ->given(
256                 $childA = new SUT('baz'),
257                 $childB = new SUT('qux'),
258                 $node   = new SUT('foo', ['bar'], [$childA])
259             )
260             ->when($result = $node->prependChild($childB))
261             ->then
262                 ->object($result)
263                     ->isIdenticalTo($node)
264                 ->integer($result->getChildrenNumber())
265                     ->isEqualTo(2)
266                 ->array($result->getChildren())
267                     ->isEqualTo([$childB, $childA]);
268     }
269 
270     public function case_append_child()
271     {
272         $this
273             ->given(
274                 $childA = new SUT('baz'),
275                 $childB = new SUT('qux'),
276                 $node   = new SUT('foo', ['bar'], [$childA])
277             )
278             ->when($result = $node->appendChild($childB))
279             ->then
280                 ->object($result)
281                     ->isIdenticalTo($node)
282                 ->integer($result->getChildrenNumber())
283                     ->isEqualTo(2)
284                 ->array($result->getChildren())
285                     ->isEqualTo([$childA, $childB]);
286     }
287 
288     public function case_set_children()
289     {
290         $this
291             ->given(
292                 $childA = new SUT('baz'),
293                 $childB = new SUT('qux'),
294                 $childC = new SUT('hello'),
295                 $node   = new SUT('foo', ['bar'], [$childA])
296             )
297             ->when($result = $node->setChildren([$childB, $childC]))
298             ->then
299                 ->array($result)
300                     ->isEqualTo([$childA])
301                 ->integer($node->getChildrenNumber())
302                     ->isEqualTo(2)
303                 ->array($node->getChildren())
304                     ->isEqualTo([$childB, $childC]);
305     }
306 
307     public function case_get_child()
308     {
309         $this
310             ->given(
311                 $childA = new SUT('baz'),
312                 $childB = new SUT('qux'),
313                 $node   = new SUT('foo', ['bar'], [$childA, $childB])
314             )
315             ->when($result = $node->getChild(0))
316             ->then
317                 ->object($result)
318                     ->isIdenticalTo($childA)
319 
320             ->when($result = $node->getChild(1))
321             ->then
322                 ->object($result)
323                     ->isIdenticalTo($childB);
324     }
325 
326     public function case_get_child_undefined()
327     {
328         $this
329             ->given(
330                 $node   = new SUT('foo', ['bar'])
331             )
332             ->when($result = $node->getChild(0))
333             ->then
334                 ->variable($result)
335                     ->isNull();
336     }
337 
338     public function case_get_children()
339     {
340         $this
341             ->given(
342                 $childA = new SUT('baz'),
343                 $childB = new SUT('qux'),
344                 $node   = new SUT('foo', ['bar'], [$childA, $childB])
345             )
346             ->when($result = $node->getChildren())
347             ->then
348                 ->array($result)
349                     ->isEqualTo([$childA, $childB]);
350     }
351 
352     public function case_get_children_number()
353     {
354         $this
355             ->given(
356                 $childA = new SUT('baz'),
357                 $childB = new SUT('qux'),
358                 $node   = new SUT('foo', ['bar'])
359             )
360             ->when($result = $node->getChildrenNumber())
361             ->then
362                 ->integer($result)
363                     ->isEqualTo(0)
364 
365             ->when(
366                 $node->setChildren([$childA, $childB]),
367                 $result = $node->getChildrenNumber()
368             )
369             ->then
370                 ->integer($result)
371                     ->isEqualTo(2);
372     }
373 
374     public function case_child_exists()
375     {
376         $this
377             ->given($node = new SUT('foo', ['bar'], [new SUT('baz')]))
378             ->when($result = $node->childExists(0))
379             ->then
380                 ->boolean($result)
381                     ->isTrue();
382     }
383 
384     public function case_child_does_not_exist()
385     {
386         $this
387             ->given($node = new SUT('foo', ['bar']))
388             ->when($result = $node->childExists(0))
389             ->then
390                 ->boolean($result)
391                     ->isFalse();
392     }
393 
394     public function case_set_parent()
395     {
396         $this
397             ->given(
398                 $parent = new SUT('baz'),
399                 $node   = new SUT('foo', ['bar'], [], $parent)
400             )
401             ->when($result = $node->setParent(new SUT('qux')))
402             ->then
403                 ->object($result)
404                     ->isIdenticalTo($parent);
405     }
406 
407     public function case_get_parent()
408     {
409         $this
410             ->given(
411                 $parent = new SUT('qux'),
412                 $node   = new SUT('foo', ['bar'], [], new SUT('baz')),
413                 $node->setParent($parent)
414             )
415             ->when($result = $node->getParent())
416             ->then
417                 ->object($result)
418                     ->isIdenticalTo($parent);
419     }
420 
421     public function case_get_data()
422     {
423         $this
424             ->given($node = new SUT('foo'))
425             ->when($result = $node->getData())
426             ->then
427                 ->array($result)
428                     ->isEmpty()
429 
430             ->when(
431                 $result[] = 'bar',
432                 $result[] = 'baz',
433                 $result   = $node->getData()
434             )
435             ->then
436                 ->array($result)
437                     ->isEmpty();
438     }
439 
440     public function case_get_data_by_reference()
441     {
442         $this
443             ->given($node = new SUT('foo'))
444             ->when($result = &$node->getData())
445             ->then
446                 ->array($result)
447                     ->isEmpty()
448 
449             ->when(
450                 $result[] = 'bar',
451                 $result[] = 'baz',
452                 $result   = $node->getData()
453             )
454             ->then
455                 ->array($result)
456                     ->isEqualTo(['bar', 'baz']);
457     }
458 }
459