c8c785db6591de28f773ee1af50550310fb01799
[yaffs-website] / vendor / nikic / php-parser / test / PhpParser / NodeAbstractTest.php
1 <?php declare(strict_types=1);
2
3 namespace PhpParser;
4
5 use PHPUnit\Framework\TestCase;
6
7 class DummyNode extends NodeAbstract
8 {
9     public $subNode1;
10     public $subNode2;
11
12     public function __construct($subNode1, $subNode2, $attributes) {
13         parent::__construct($attributes);
14         $this->subNode1 = $subNode1;
15         $this->subNode2 = $subNode2;
16     }
17
18     public function getSubNodeNames() : array {
19         return ['subNode1', 'subNode2'];
20     }
21
22     // This method is only overwritten because the node is located in an unusual namespace
23     public function getType() : string {
24         return 'Dummy';
25     }
26 }
27
28 class NodeAbstractTest extends TestCase
29 {
30     public function provideNodes() {
31         $attributes = [
32             'startLine' => 10,
33             'endLine' => 11,
34             'startTokenPos' => 12,
35             'endTokenPos' => 13,
36             'startFilePos' => 14,
37             'endFilePos' => 15,
38             'comments'  => [
39                 new Comment('// Comment' . "\n"),
40                 new Comment\Doc('/** doc comment */'),
41             ],
42         ];
43
44         $node = new DummyNode('value1', 'value2', $attributes);
45         $node->notSubNode = 'value3';
46
47         return [
48             [$attributes, $node],
49         ];
50     }
51
52     /**
53      * @dataProvider provideNodes
54      */
55     public function testConstruct(array $attributes, Node $node) {
56         $this->assertSame('Dummy', $node->getType());
57         $this->assertSame(['subNode1', 'subNode2'], $node->getSubNodeNames());
58         $this->assertSame(10, $node->getLine());
59         $this->assertSame(10, $node->getStartLine());
60         $this->assertSame(11, $node->getEndLine());
61         $this->assertSame(12, $node->getStartTokenPos());
62         $this->assertSame(13, $node->getEndTokenPos());
63         $this->assertSame(14, $node->getStartFilePos());
64         $this->assertSame(15, $node->getEndFilePos());
65         $this->assertSame('/** doc comment */', $node->getDocComment()->getText());
66         $this->assertSame('value1', $node->subNode1);
67         $this->assertSame('value2', $node->subNode2);
68         $this->assertObjectHasAttribute('subNode1', $node);
69         $this->assertObjectHasAttribute('subNode2', $node);
70         $this->assertObjectNotHasAttribute('subNode3', $node);
71         $this->assertSame($attributes, $node->getAttributes());
72         $this->assertSame($attributes['comments'], $node->getComments());
73
74         return $node;
75     }
76
77     /**
78      * @dataProvider provideNodes
79      */
80     public function testGetDocComment(array $attributes, Node $node) {
81         $this->assertSame('/** doc comment */', $node->getDocComment()->getText());
82         $comments = $node->getComments();
83
84         array_pop($comments); // remove doc comment
85         $node->setAttribute('comments', $comments);
86         $this->assertNull($node->getDocComment());
87
88         array_pop($comments); // remove comment
89         $node->setAttribute('comments', $comments);
90         $this->assertNull($node->getDocComment());
91     }
92
93     public function testSetDocComment() {
94         $node = new DummyNode(null, null, []);
95
96         // Add doc comment to node without comments
97         $docComment = new Comment\Doc('/** doc */');
98         $node->setDocComment($docComment);
99         $this->assertSame($docComment, $node->getDocComment());
100
101         // Replace it
102         $docComment = new Comment\Doc('/** doc 2 */');
103         $node->setDocComment($docComment);
104         $this->assertSame($docComment, $node->getDocComment());
105
106         // Add docmment to node with other comments
107         $c1 = new Comment('/* foo */');
108         $c2 = new Comment('/* bar */');
109         $docComment = new Comment\Doc('/** baz */');
110         $node->setAttribute('comments', [$c1, $c2]);
111         $node->setDocComment($docComment);
112         $this->assertSame([$c1, $c2, $docComment], $node->getAttribute('comments'));
113     }
114
115     /**
116      * @dataProvider provideNodes
117      */
118     public function testChange(array $attributes, Node $node) {
119         // direct modification
120         $node->subNode = 'newValue';
121         $this->assertSame('newValue', $node->subNode);
122
123         // indirect modification
124         $subNode =& $node->subNode;
125         $subNode = 'newNewValue';
126         $this->assertSame('newNewValue', $node->subNode);
127
128         // removal
129         unset($node->subNode);
130         $this->assertObjectNotHasAttribute('subNode', $node);
131     }
132
133     /**
134      * @dataProvider provideNodes
135      */
136     public function testIteration(array $attributes, Node $node) {
137         // Iteration is simple object iteration over properties,
138         // not over subnodes
139         $i = 0;
140         foreach ($node as $key => $value) {
141             if ($i === 0) {
142                 $this->assertSame('subNode1', $key);
143                 $this->assertSame('value1', $value);
144             } elseif ($i === 1) {
145                 $this->assertSame('subNode2', $key);
146                 $this->assertSame('value2', $value);
147             } elseif ($i === 2) {
148                 $this->assertSame('notSubNode', $key);
149                 $this->assertSame('value3', $value);
150             } else {
151                 throw new \Exception;
152             }
153             $i++;
154         }
155         $this->assertSame(3, $i);
156     }
157
158     public function testAttributes() {
159         /** @var $node Node */
160         $node = $this->getMockForAbstractClass(NodeAbstract::class);
161
162         $this->assertEmpty($node->getAttributes());
163
164         $node->setAttribute('key', 'value');
165         $this->assertTrue($node->hasAttribute('key'));
166         $this->assertSame('value', $node->getAttribute('key'));
167
168         $this->assertFalse($node->hasAttribute('doesNotExist'));
169         $this->assertNull($node->getAttribute('doesNotExist'));
170         $this->assertSame('default', $node->getAttribute('doesNotExist', 'default'));
171
172         $node->setAttribute('null', null);
173         $this->assertTrue($node->hasAttribute('null'));
174         $this->assertNull($node->getAttribute('null'));
175         $this->assertNull($node->getAttribute('null', 'default'));
176
177         $this->assertSame(
178             [
179                 'key'  => 'value',
180                 'null' => null,
181             ],
182             $node->getAttributes()
183         );
184
185         $node->setAttributes(
186             [
187                 'a' => 'b',
188                 'c' => null,
189             ]
190         );
191         $this->assertSame(
192             [
193                 'a' => 'b',
194                 'c' => null,
195             ],
196             $node->getAttributes()
197         );
198     }
199
200     public function testJsonSerialization() {
201         $code = <<<'PHP'
202 <?php
203 // comment
204 /** doc comment */
205 function functionName(&$a = 0, $b = 1.0) {
206     echo 'Foo';
207 }
208 PHP;
209         $expected = <<<'JSON'
210 [
211     {
212         "nodeType": "Stmt_Function",
213         "byRef": false,
214         "name": {
215             "nodeType": "Identifier",
216             "name": "functionName",
217             "attributes": {
218                 "startLine": 4,
219                 "endLine": 4
220             }
221         },
222         "params": [
223             {
224                 "nodeType": "Param",
225                 "type": null,
226                 "byRef": true,
227                 "variadic": false,
228                 "var": {
229                     "nodeType": "Expr_Variable",
230                     "name": "a",
231                     "attributes": {
232                         "startLine": 4,
233                         "endLine": 4
234                     }
235                 },
236                 "default": {
237                     "nodeType": "Scalar_LNumber",
238                     "value": 0,
239                     "attributes": {
240                         "startLine": 4,
241                         "endLine": 4,
242                         "kind": 10
243                     }
244                 },
245                 "attributes": {
246                     "startLine": 4,
247                     "endLine": 4
248                 }
249             },
250             {
251                 "nodeType": "Param",
252                 "type": null,
253                 "byRef": false,
254                 "variadic": false,
255                 "var": {
256                     "nodeType": "Expr_Variable",
257                     "name": "b",
258                     "attributes": {
259                         "startLine": 4,
260                         "endLine": 4
261                     }
262                 },
263                 "default": {
264                     "nodeType": "Scalar_DNumber",
265                     "value": 1,
266                     "attributes": {
267                         "startLine": 4,
268                         "endLine": 4
269                     }
270                 },
271                 "attributes": {
272                     "startLine": 4,
273                     "endLine": 4
274                 }
275             }
276         ],
277         "returnType": null,
278         "stmts": [
279             {
280                 "nodeType": "Stmt_Echo",
281                 "exprs": [
282                     {
283                         "nodeType": "Scalar_String",
284                         "value": "Foo",
285                         "attributes": {
286                             "startLine": 5,
287                             "endLine": 5,
288                             "kind": 1
289                         }
290                     }
291                 ],
292                 "attributes": {
293                     "startLine": 5,
294                     "endLine": 5
295                 }
296             }
297         ],
298         "attributes": {
299             "startLine": 4,
300             "comments": [
301                 {
302                     "nodeType": "Comment",
303                     "text": "\/\/ comment\n",
304                     "line": 2,
305                     "filePos": 6,
306                     "tokenPos": 1
307                 },
308                 {
309                     "nodeType": "Comment_Doc",
310                     "text": "\/** doc comment *\/",
311                     "line": 3,
312                     "filePos": 17,
313                     "tokenPos": 2
314                 }
315             ],
316             "endLine": 6
317         }
318     }
319 ]
320 JSON;
321
322         $parser = new Parser\Php7(new Lexer());
323         $stmts = $parser->parse(canonicalize($code));
324         $json = json_encode($stmts, JSON_PRETTY_PRINT);
325         $this->assertEquals(canonicalize($expected), canonicalize($json));
326     }
327 }