9dd20a109dfca6c9ce511e3952685d2663e57d30
[yaffs-website] / vendor / nikic / php-parser / test / PhpParser / BuilderFactoryTest.php
1 <?php declare(strict_types=1);
2
3 namespace PhpParser;
4
5 use PhpParser\Builder;
6 use PhpParser\Node\Arg;
7 use PhpParser\Node\Expr;
8 use PhpParser\Node\Expr\BinaryOp\Concat;
9 use PhpParser\Node\Identifier;
10 use PhpParser\Node\Name;
11 use PhpParser\Node\Scalar\LNumber;
12 use PhpParser\Node\Scalar\String_;
13 use PHPUnit\Framework\TestCase;
14 use Symfony\Component\Yaml\Tests\A;
15
16 class BuilderFactoryTest extends TestCase
17 {
18     /**
19      * @dataProvider provideTestFactory
20      */
21     public function testFactory($methodName, $className) {
22         $factory = new BuilderFactory;
23         $this->assertInstanceOf($className, $factory->$methodName('test'));
24     }
25
26     public function provideTestFactory() {
27         return [
28             ['namespace',   Builder\Namespace_::class],
29             ['class',       Builder\Class_::class],
30             ['interface',   Builder\Interface_::class],
31             ['trait',       Builder\Trait_::class],
32             ['method',      Builder\Method::class],
33             ['function',    Builder\Function_::class],
34             ['property',    Builder\Property::class],
35             ['param',       Builder\Param::class],
36             ['use',         Builder\Use_::class],
37             ['useFunction', Builder\Use_::class],
38             ['useConst',    Builder\Use_::class],
39         ];
40     }
41
42     public function testVal() {
43         // This method is a wrapper around BuilderHelpers::normalizeValue(),
44         // which is already tested elsewhere
45         $factory = new BuilderFactory();
46         $this->assertEquals(
47             new String_("foo"),
48             $factory->val("foo")
49         );
50     }
51
52     public function testConcat() {
53         $factory = new BuilderFactory();
54         $varA = new Expr\Variable('a');
55         $varB = new Expr\Variable('b');
56         $varC = new Expr\Variable('c');
57
58         $this->assertEquals(
59             new Concat($varA, $varB),
60             $factory->concat($varA, $varB)
61         );
62         $this->assertEquals(
63             new Concat(new Concat($varA, $varB), $varC),
64             $factory->concat($varA, $varB, $varC)
65         );
66         $this->assertEquals(
67             new Concat(new Concat(new String_("a"), $varB), new String_("c")),
68             $factory->concat("a", $varB, "c")
69         );
70     }
71
72     public function testConcatOneError() {
73         $this->expectException(\LogicException::class);
74         $this->expectExceptionMessage('Expected at least two expressions');
75         (new BuilderFactory())->concat("a");
76     }
77
78     public function testConcatInvalidExpr() {
79         $this->expectException(\LogicException::class);
80         $this->expectExceptionMessage('Expected string or Expr');
81         (new BuilderFactory())->concat("a", 42);
82     }
83
84     public function testArgs() {
85         $factory = new BuilderFactory();
86         $unpack = new Arg(new Expr\Variable('c'), false, true);
87         $this->assertEquals(
88             [
89                 new Arg(new Expr\Variable('a')),
90                 new Arg(new String_('b')),
91                 $unpack
92             ],
93             $factory->args([new Expr\Variable('a'), 'b', $unpack])
94         );
95     }
96
97     public function testCalls() {
98         $factory = new BuilderFactory();
99
100         // Simple function call
101         $this->assertEquals(
102             new Expr\FuncCall(
103                 new Name('var_dump'),
104                 [new Arg(new String_('str'))]
105             ),
106             $factory->funcCall('var_dump', ['str'])
107         );
108         // Dynamic function call
109         $this->assertEquals(
110             new Expr\FuncCall(new Expr\Variable('fn')),
111             $factory->funcCall(new Expr\Variable('fn'))
112         );
113
114         // Simple method call
115         $this->assertEquals(
116             new Expr\MethodCall(
117                 new Expr\Variable('obj'),
118                 new Identifier('method'),
119                 [new Arg(new LNumber(42))]
120             ),
121             $factory->methodCall(new Expr\Variable('obj'), 'method', [42])
122         );
123         // Explicitly pass Identifier node
124         $this->assertEquals(
125             new Expr\MethodCall(
126                 new Expr\Variable('obj'),
127                 new Identifier('method')
128             ),
129             $factory->methodCall(new Expr\Variable('obj'), new Identifier('method'))
130         );
131         // Dynamic method call
132         $this->assertEquals(
133             new Expr\MethodCall(
134                 new Expr\Variable('obj'),
135                 new Expr\Variable('method')
136             ),
137             $factory->methodCall(new Expr\Variable('obj'), new Expr\Variable('method'))
138         );
139
140         // Simple static method call
141         $this->assertEquals(
142             new Expr\StaticCall(
143                 new Name\FullyQualified('Foo'),
144                 new Identifier('bar'),
145                 [new Arg(new Expr\Variable('baz'))]
146             ),
147             $factory->staticCall('\Foo', 'bar', [new Expr\Variable('baz')])
148         );
149         // Dynamic static method call
150         $this->assertEquals(
151             new Expr\StaticCall(
152                 new Expr\Variable('foo'),
153                 new Expr\Variable('bar')
154             ),
155             $factory->staticCall(new Expr\Variable('foo'), new Expr\Variable('bar'))
156         );
157
158         // Simple new call
159         $this->assertEquals(
160             new Expr\New_(new Name\FullyQualified('stdClass')),
161             $factory->new('\stdClass')
162         );
163         // Dynamic new call
164         $this->assertEquals(
165             new Expr\New_(
166                 new Expr\Variable('foo'),
167                 [new Arg(new String_('bar'))]
168             ),
169             $factory->new(new Expr\Variable('foo'), ['bar'])
170         );
171     }
172
173     public function testConstFetches() {
174         $factory = new BuilderFactory();
175         $this->assertEquals(
176             new Expr\ConstFetch(new Name('FOO')),
177             $factory->constFetch('FOO')
178         );
179         $this->assertEquals(
180             new Expr\ClassConstFetch(new Name('Foo'), new Identifier('BAR')),
181             $factory->classConstFetch('Foo', 'BAR')
182         );
183         $this->assertEquals(
184             new Expr\ClassConstFetch(new Expr\Variable('foo'), new Identifier('BAR')),
185             $factory->classConstFetch(new Expr\Variable('foo'), 'BAR')
186         );
187     }
188
189     public function testVar() {
190         $factory = new BuilderFactory();
191         $this->assertEquals(
192             new Expr\Variable("foo"),
193             $factory->var("foo")
194         );
195         $this->assertEquals(
196             new Expr\Variable(new Expr\Variable("foo")),
197             $factory->var($factory->var("foo"))
198         );
199     }
200
201     public function testPropertyFetch() {
202         $f = new BuilderFactory();
203         $this->assertEquals(
204             new Expr\PropertyFetch(new Expr\Variable('foo'), 'bar'),
205             $f->propertyFetch($f->var('foo'), 'bar')
206         );
207         $this->assertEquals(
208             new Expr\PropertyFetch(new Expr\Variable('foo'), 'bar'),
209             $f->propertyFetch($f->var('foo'), new Identifier('bar'))
210         );
211         $this->assertEquals(
212             new Expr\PropertyFetch(new Expr\Variable('foo'), new Expr\Variable('bar')),
213             $f->propertyFetch($f->var('foo'), $f->var('bar'))
214         );
215     }
216
217     public function testInvalidIdentifier() {
218         $this->expectException(\LogicException::class);
219         $this->expectExceptionMessage('Expected string or instance of Node\Identifier');
220         (new BuilderFactory())->classConstFetch('Foo', new Expr\Variable('foo'));
221     }
222
223     public function testInvalidIdentifierOrExpr() {
224         $this->expectException(\LogicException::class);
225         $this->expectExceptionMessage('Expected string or instance of Node\Identifier or Node\Expr');
226         (new BuilderFactory())->staticCall('Foo', new Name('bar'));
227     }
228
229     public function testInvalidNameOrExpr() {
230         $this->expectException(\LogicException::class);
231         $this->expectExceptionMessage('Name must be a string or an instance of Node\Name or Node\Expr');
232         (new BuilderFactory())->funcCall(new Node\Stmt\Return_());
233     }
234
235     public function testInvalidVar() {
236         $this->expectException(\LogicException::class);
237         $this->expectExceptionMessage('Variable name must be string or Expr');
238         (new BuilderFactory())->var(new Node\Stmt\Return_());
239     }
240
241     public function testIntegration() {
242         $factory = new BuilderFactory;
243         $node = $factory->namespace('Name\Space')
244             ->addStmt($factory->use('Foo\Bar\SomeOtherClass'))
245             ->addStmt($factory->use('Foo\Bar')->as('A'))
246             ->addStmt($factory->useFunction('strlen'))
247             ->addStmt($factory->useConst('PHP_VERSION'))
248             ->addStmt($factory
249                 ->class('SomeClass')
250                 ->extend('SomeOtherClass')
251                 ->implement('A\Few', '\Interfaces')
252                 ->makeAbstract()
253
254                 ->addStmt($factory->useTrait('FirstTrait'))
255
256                 ->addStmt($factory->useTrait('SecondTrait', 'ThirdTrait')
257                     ->and('AnotherTrait')
258                     ->with($factory->traitUseAdaptation('foo')->as('bar'))
259                     ->with($factory->traitUseAdaptation('AnotherTrait', 'baz')->as('test'))
260                     ->with($factory->traitUseAdaptation('AnotherTrait', 'func')->insteadof('SecondTrait')))
261
262                 ->addStmt($factory->method('firstMethod'))
263
264                 ->addStmt($factory->method('someMethod')
265                     ->makePublic()
266                     ->makeAbstract()
267                     ->addParam($factory->param('someParam')->setType('SomeClass'))
268                     ->setDocComment('/**
269                                       * This method does something.
270                                       *
271                                       * @param SomeClass And takes a parameter
272                                       */'))
273
274                 ->addStmt($factory->method('anotherMethod')
275                     ->makeProtected()
276                     ->addParam($factory->param('someParam')->setDefault('test'))
277                     ->addStmt(new Expr\Print_(new Expr\Variable('someParam'))))
278
279                 ->addStmt($factory->property('someProperty')->makeProtected())
280                 ->addStmt($factory->property('anotherProperty')
281                     ->makePrivate()
282                     ->setDefault([1, 2, 3])))
283             ->getNode()
284         ;
285
286         $expected = <<<'EOC'
287 <?php
288
289 namespace Name\Space;
290
291 use Foo\Bar\SomeOtherClass;
292 use Foo\Bar as A;
293 use function strlen;
294 use const PHP_VERSION;
295 abstract class SomeClass extends SomeOtherClass implements A\Few, \Interfaces
296 {
297     use FirstTrait;
298     use SecondTrait, ThirdTrait, AnotherTrait {
299         foo as bar;
300         AnotherTrait::baz as test;
301         AnotherTrait::func insteadof SecondTrait;
302     }
303     protected $someProperty;
304     private $anotherProperty = array(1, 2, 3);
305     function firstMethod()
306     {
307     }
308     /**
309      * This method does something.
310      *
311      * @param SomeClass And takes a parameter
312      */
313     public abstract function someMethod(SomeClass $someParam);
314     protected function anotherMethod($someParam = 'test')
315     {
316         print $someParam;
317     }
318 }
319 EOC;
320
321         $stmts = [$node];
322         $prettyPrinter = new PrettyPrinter\Standard();
323         $generated = $prettyPrinter->prettyPrintFile($stmts);
324
325         $this->assertEquals(
326             str_replace("\r\n", "\n", $expected),
327             str_replace("\r\n", "\n", $generated)
328         );
329     }
330 }