1<?php declare(strict_types=1); 2 3namespace PhpParser\Builder; 4 5use PhpParser\Comment; 6use PhpParser\Node; 7use PhpParser\Node\Arg; 8use PhpParser\Node\Attribute; 9use PhpParser\Node\AttributeGroup; 10use PhpParser\Node\Expr\Print_; 11use PhpParser\Node\Expr\Variable; 12use PhpParser\Node\Identifier; 13use PhpParser\Node\Name; 14use PhpParser\Node\Scalar\Int_; 15use PhpParser\Node\Scalar\String_; 16use PhpParser\Node\Stmt; 17 18class FunctionTest extends \PHPUnit\Framework\TestCase { 19 public function createFunctionBuilder($name) { 20 return new Function_($name); 21 } 22 23 public function testReturnByRef(): void { 24 $node = $this->createFunctionBuilder('test') 25 ->makeReturnByRef() 26 ->getNode() 27 ; 28 29 $this->assertEquals( 30 new Stmt\Function_('test', [ 31 'byRef' => true 32 ]), 33 $node 34 ); 35 } 36 37 public function testParams(): void { 38 $param1 = new Node\Param(new Variable('test1')); 39 $param2 = new Node\Param(new Variable('test2')); 40 $param3 = new Node\Param(new Variable('test3')); 41 42 $node = $this->createFunctionBuilder('test') 43 ->addParam($param1) 44 ->addParams([$param2, $param3]) 45 ->getNode() 46 ; 47 48 $this->assertEquals( 49 new Stmt\Function_('test', [ 50 'params' => [$param1, $param2, $param3] 51 ]), 52 $node 53 ); 54 } 55 56 public function testStmts(): void { 57 $stmt1 = new Print_(new String_('test1')); 58 $stmt2 = new Print_(new String_('test2')); 59 $stmt3 = new Print_(new String_('test3')); 60 61 $node = $this->createFunctionBuilder('test') 62 ->addStmt($stmt1) 63 ->addStmts([$stmt2, $stmt3]) 64 ->getNode() 65 ; 66 67 $this->assertEquals( 68 new Stmt\Function_('test', [ 69 'stmts' => [ 70 new Stmt\Expression($stmt1), 71 new Stmt\Expression($stmt2), 72 new Stmt\Expression($stmt3), 73 ] 74 ]), 75 $node 76 ); 77 } 78 79 public function testDocComment(): void { 80 $node = $this->createFunctionBuilder('test') 81 ->setDocComment('/** Test */') 82 ->getNode(); 83 84 $this->assertEquals(new Stmt\Function_('test', [], [ 85 'comments' => [new Comment\Doc('/** Test */')] 86 ]), $node); 87 } 88 89 public function testAddAttribute(): void { 90 $attribute = new Attribute( 91 new Name('Attr'), 92 [new Arg(new Int_(1), false, false, [], new Identifier('name'))] 93 ); 94 $attributeGroup = new AttributeGroup([$attribute]); 95 96 $node = $this->createFunctionBuilder('attrGroup') 97 ->addAttribute($attributeGroup) 98 ->getNode(); 99 100 $this->assertEquals(new Stmt\Function_('attrGroup', [ 101 'attrGroups' => [$attributeGroup], 102 ], []), $node); 103 } 104 105 public function testReturnType(): void { 106 $node = $this->createFunctionBuilder('test') 107 ->setReturnType('void') 108 ->getNode(); 109 110 $this->assertEquals(new Stmt\Function_('test', [ 111 'returnType' => new Identifier('void'), 112 ], []), $node); 113 } 114 115 public function testInvalidNullableVoidType(): void { 116 $this->expectException(\LogicException::class); 117 $this->expectExceptionMessage('void type cannot be nullable'); 118 $this->createFunctionBuilder('test')->setReturnType('?void'); 119 } 120 121 public function testInvalidParamError(): void { 122 $this->expectException(\LogicException::class); 123 $this->expectExceptionMessage('Expected parameter node, got "Name"'); 124 $this->createFunctionBuilder('test') 125 ->addParam(new Node\Name('foo')) 126 ; 127 } 128 129 public function testAddNonStmt(): void { 130 $this->expectException(\LogicException::class); 131 $this->expectExceptionMessage('Expected statement or expression node'); 132 $this->createFunctionBuilder('test') 133 ->addStmt(new Node\Name('Test')); 134 } 135} 136