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\Identifier; 11use PhpParser\Node\Name; 12use PhpParser\Node\Scalar\Float_; 13use PhpParser\Node\Scalar\Int_; 14use PhpParser\Node\Stmt; 15 16class InterfaceTest extends \PHPUnit\Framework\TestCase { 17 protected function createInterfaceBuilder() { 18 return new Interface_('Contract'); 19 } 20 21 private function dump($node) { 22 $pp = new \PhpParser\PrettyPrinter\Standard(); 23 return $pp->prettyPrint([$node]); 24 } 25 26 public function testEmpty(): void { 27 $contract = $this->createInterfaceBuilder()->getNode(); 28 $this->assertInstanceOf(Stmt\Interface_::class, $contract); 29 $this->assertEquals(new Node\Identifier('Contract'), $contract->name); 30 } 31 32 public function testExtending(): void { 33 $contract = $this->createInterfaceBuilder() 34 ->extend('Space\Root1', 'Root2')->getNode(); 35 $this->assertEquals( 36 new Stmt\Interface_('Contract', [ 37 'extends' => [ 38 new Node\Name('Space\Root1'), 39 new Node\Name('Root2') 40 ], 41 ]), $contract 42 ); 43 } 44 45 public function testAddMethod(): void { 46 $method = new Stmt\ClassMethod('doSomething'); 47 $contract = $this->createInterfaceBuilder()->addStmt($method)->getNode(); 48 $this->assertSame([$method], $contract->stmts); 49 } 50 51 public function testAddConst(): void { 52 $const = new Stmt\ClassConst([ 53 new Node\Const_('SPEED_OF_LIGHT', new Float_(299792458.0)) 54 ]); 55 $contract = $this->createInterfaceBuilder()->addStmt($const)->getNode(); 56 $this->assertSame(299792458.0, $contract->stmts[0]->consts[0]->value->value); 57 } 58 59 public function testOrder(): void { 60 $const = new Stmt\ClassConst([ 61 new Node\Const_('SPEED_OF_LIGHT', new Float_(299792458)) 62 ]); 63 $method = new Stmt\ClassMethod('doSomething'); 64 $contract = $this->createInterfaceBuilder() 65 ->addStmt($method) 66 ->addStmt($const) 67 ->getNode() 68 ; 69 70 $this->assertInstanceOf(Stmt\ClassConst::class, $contract->stmts[0]); 71 $this->assertInstanceOf(Stmt\ClassMethod::class, $contract->stmts[1]); 72 } 73 74 public function testDocComment(): void { 75 $node = $this->createInterfaceBuilder() 76 ->setDocComment('/** Test */') 77 ->getNode(); 78 79 $this->assertEquals(new Stmt\Interface_('Contract', [], [ 80 'comments' => [new Comment\Doc('/** Test */')] 81 ]), $node); 82 } 83 84 public function testAddAttribute(): void { 85 $attribute = new Attribute( 86 new Name('Attr'), 87 [new Arg(new Int_(1), false, false, [], new Identifier('name'))] 88 ); 89 $attributeGroup = new AttributeGroup([$attribute]); 90 91 $node = $this->createInterfaceBuilder() 92 ->addAttribute($attributeGroup) 93 ->getNode(); 94 95 $this->assertEquals(new Stmt\Interface_('Contract', [ 96 'attrGroups' => [$attributeGroup], 97 ], []), $node); 98 } 99 100 public function testInvalidStmtError(): void { 101 $this->expectException(\LogicException::class); 102 $this->expectExceptionMessage('Unexpected node of type "PropertyItem"'); 103 $this->createInterfaceBuilder()->addStmt(new Node\PropertyItem('invalid')); 104 } 105 106 public function testFullFunctional(): void { 107 $const = new Stmt\ClassConst([ 108 new Node\Const_('SPEED_OF_LIGHT', new Float_(299792458)) 109 ]); 110 $method = new Stmt\ClassMethod('doSomething'); 111 $contract = $this->createInterfaceBuilder() 112 ->addStmt($method) 113 ->addStmt($const) 114 ->getNode() 115 ; 116 117 eval($this->dump($contract)); 118 119 $this->assertTrue(interface_exists('Contract', false)); 120 } 121} 122