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\Int_; 13use PhpParser\Node\Stmt; 14 15class EnumTest extends \PHPUnit\Framework\TestCase { 16 protected function createEnumBuilder($class) { 17 return new Enum_($class); 18 } 19 20 public function testImplements(): void { 21 $node = $this->createEnumBuilder('SomeEnum') 22 ->implement('Namespaced\SomeInterface', new Name('OtherInterface')) 23 ->getNode() 24 ; 25 26 $this->assertEquals( 27 new Stmt\Enum_('SomeEnum', [ 28 'implements' => [ 29 new Name('Namespaced\SomeInterface'), 30 new Name('OtherInterface'), 31 ], 32 ]), 33 $node 34 ); 35 } 36 37 public function testSetScalarType(): void { 38 $node = $this->createEnumBuilder('Test') 39 ->setScalarType('int') 40 ->getNode() 41 ; 42 43 $this->assertEquals( 44 new Stmt\Enum_('Test', [ 45 'scalarType' => new Identifier('int'), 46 ]), 47 $node 48 ); 49 } 50 51 public function testStatementOrder(): void { 52 $method = new Stmt\ClassMethod('testMethod'); 53 $enumCase = new Stmt\EnumCase( 54 'TEST_ENUM_CASE' 55 ); 56 $const = new Stmt\ClassConst([ 57 new Node\Const_('TEST_CONST', new Node\Scalar\String_('ABC')) 58 ]); 59 $use = new Stmt\TraitUse([new Name('SomeTrait')]); 60 61 $node = $this->createEnumBuilder('Test') 62 ->addStmt($method) 63 ->addStmt($enumCase) 64 ->addStmts([$const, $use]) 65 ->getNode() 66 ; 67 68 $this->assertEquals( 69 new Stmt\Enum_('Test', [ 70 'stmts' => [$use, $enumCase, $const, $method] 71 ]), 72 $node 73 ); 74 } 75 76 public function testDocComment(): void { 77 $docComment = <<<'DOC' 78/** 79 * Test 80 */ 81DOC; 82 $enum = $this->createEnumBuilder('Test') 83 ->setDocComment($docComment) 84 ->getNode(); 85 86 $this->assertEquals( 87 new Stmt\Enum_('Test', [], [ 88 'comments' => [ 89 new Comment\Doc($docComment) 90 ] 91 ]), 92 $enum 93 ); 94 95 $enum = $this->createEnumBuilder('Test') 96 ->setDocComment(new Comment\Doc($docComment)) 97 ->getNode(); 98 99 $this->assertEquals( 100 new Stmt\Enum_('Test', [], [ 101 'comments' => [ 102 new Comment\Doc($docComment) 103 ] 104 ]), 105 $enum 106 ); 107 } 108 109 public function testAddAttribute(): void { 110 $attribute = new Attribute( 111 new Name('Attr'), 112 [new Arg(new Int_(1), false, false, [], new Identifier('name'))] 113 ); 114 $attributeGroup = new AttributeGroup([$attribute]); 115 116 $enum = $this->createEnumBuilder('ATTR_GROUP') 117 ->addAttribute($attributeGroup) 118 ->getNode(); 119 120 $this->assertEquals( 121 new Stmt\Enum_('ATTR_GROUP', [ 122 'attrGroups' => [ 123 $attributeGroup, 124 ] 125 ], []), 126 $enum 127 ); 128 } 129 130 public function testInvalidStmtError(): void { 131 $this->expectException(\LogicException::class); 132 $this->expectExceptionMessage('Unexpected node of type "PropertyItem"'); 133 $this->createEnumBuilder('Test') 134 ->addStmt(new Node\PropertyItem('property')) 135 ; 136 } 137 138 public function testInvalidDocComment(): void { 139 $this->expectException(\LogicException::class); 140 $this->expectExceptionMessage('Doc comment must be a string or an instance of PhpParser\Comment\Doc'); 141 $this->createEnumBuilder('Test') 142 ->setDocComment(new Comment('Test')); 143 } 144 145 public function testEmptyName(): void { 146 $this->expectException(\LogicException::class); 147 $this->expectExceptionMessage('Name cannot be empty'); 148 $this->createEnumBuilder('Test') 149 ->implement(''); 150 } 151 152 public function testInvalidName(): void { 153 $this->expectException(\LogicException::class); 154 $this->expectExceptionMessage('Name must be a string or an instance of Node\Name'); 155 $this->createEnumBuilder('Test') 156 ->implement(['Foo']); 157 } 158} 159