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