1<?php declare(strict_types=1); 2 3namespace PhpParser\Builder; 4 5use PhpParser\Comment; 6use PhpParser\Error; 7use PhpParser\Modifiers; 8use PhpParser\Node\Arg; 9use PhpParser\Node\Attribute; 10use PhpParser\Node\AttributeGroup; 11use PhpParser\Node\Expr; 12use PhpParser\Node\Identifier; 13use PhpParser\Node\Name; 14use PhpParser\Node\PropertyHook; 15use PhpParser\Node\PropertyItem; 16use PhpParser\Node\Scalar; 17use PhpParser\Node\Scalar\Int_; 18use PhpParser\Node\Stmt; 19 20class PropertyTest extends \PHPUnit\Framework\TestCase { 21 public function createPropertyBuilder($name) { 22 return new Property($name); 23 } 24 25 public function testModifiers(): void { 26 $node = $this->createPropertyBuilder('test') 27 ->makePrivate() 28 ->makeStatic() 29 ->getNode() 30 ; 31 32 $this->assertEquals( 33 new Stmt\Property( 34 Modifiers::PRIVATE | Modifiers::STATIC, 35 [new PropertyItem('test')] 36 ), 37 $node 38 ); 39 40 $node = $this->createPropertyBuilder('test') 41 ->makeProtected() 42 ->getNode() 43 ; 44 45 $this->assertEquals( 46 new Stmt\Property( 47 Modifiers::PROTECTED, 48 [new PropertyItem('test')] 49 ), 50 $node 51 ); 52 53 $node = $this->createPropertyBuilder('test') 54 ->makePublic() 55 ->getNode() 56 ; 57 58 $this->assertEquals( 59 new Stmt\Property( 60 Modifiers::PUBLIC, 61 [new PropertyItem('test')] 62 ), 63 $node 64 ); 65 66 $node = $this->createPropertyBuilder('test') 67 ->makeReadonly() 68 ->getNode() 69 ; 70 71 $this->assertEquals( 72 new Stmt\Property( 73 Modifiers::READONLY, 74 [new PropertyItem('test')] 75 ), 76 $node 77 ); 78 79 $node = $this->createPropertyBuilder('test') 80 ->makeFinal() 81 ->getNode(); 82 $this->assertEquals( 83 new Stmt\Property(Modifiers::FINAL, [new PropertyItem('test')]), 84 $node); 85 86 $node = $this->createPropertyBuilder('test') 87 ->makePrivateSet() 88 ->getNode(); 89 $this->assertEquals( 90 new Stmt\Property(Modifiers::PRIVATE_SET, [new PropertyItem('test')]), 91 $node); 92 93 $node = $this->createPropertyBuilder('test') 94 ->makeProtectedSet() 95 ->getNode(); 96 $this->assertEquals( 97 new Stmt\Property(Modifiers::PROTECTED_SET, [new PropertyItem('test')]), 98 $node); 99 } 100 101 public function testAbstractWithoutHook() { 102 $this->expectException(Error::class); 103 $this->expectExceptionMessage('Only hooked properties may be declared abstract'); 104 $this->createPropertyBuilder('test')->makeAbstract()->getNode(); 105 } 106 107 public function testDocComment(): void { 108 $node = $this->createPropertyBuilder('test') 109 ->setDocComment('/** Test */') 110 ->getNode(); 111 112 $this->assertEquals(new Stmt\Property( 113 Modifiers::PUBLIC, 114 [ 115 new \PhpParser\Node\PropertyItem('test') 116 ], 117 [ 118 'comments' => [new Comment\Doc('/** Test */')] 119 ] 120 ), $node); 121 } 122 123 /** 124 * @dataProvider provideTestDefaultValues 125 */ 126 public function testDefaultValues($value, $expectedValueNode): void { 127 $node = $this->createPropertyBuilder('test') 128 ->setDefault($value) 129 ->getNode() 130 ; 131 132 $this->assertEquals($expectedValueNode, $node->props[0]->default); 133 } 134 135 public function testAddAttribute(): void { 136 $attribute = new Attribute( 137 new Name('Attr'), 138 [new Arg(new Int_(1), false, false, [], new Identifier('name'))] 139 ); 140 $attributeGroup = new AttributeGroup([$attribute]); 141 142 $node = $this->createPropertyBuilder('test') 143 ->addAttribute($attributeGroup) 144 ->getNode() 145 ; 146 147 $this->assertEquals( 148 new Stmt\Property( 149 Modifiers::PUBLIC, 150 [ 151 new \PhpParser\Node\PropertyItem('test') 152 ], 153 [], 154 null, 155 [$attributeGroup] 156 ), 157 $node 158 ); 159 } 160 161 public function testAddHook(): void { 162 $get = new PropertyHook('get', null); 163 $set = new PropertyHook('set', null); 164 $node = $this->createPropertyBuilder('test') 165 ->addHook($get) 166 ->addHook($set) 167 ->makeAbstract() 168 ->getNode(); 169 $this->assertEquals( 170 new Stmt\Property( 171 Modifiers::ABSTRACT, 172 [new PropertyItem('test')], 173 [], null, [], 174 [$get, $set]), 175 $node); 176 } 177 178 public static function provideTestDefaultValues() { 179 return [ 180 [ 181 null, 182 new Expr\ConstFetch(new Name('null')) 183 ], 184 [ 185 true, 186 new Expr\ConstFetch(new Name('true')) 187 ], 188 [ 189 false, 190 new Expr\ConstFetch(new Name('false')) 191 ], 192 [ 193 31415, 194 new Scalar\Int_(31415) 195 ], 196 [ 197 3.1415, 198 new Scalar\Float_(3.1415) 199 ], 200 [ 201 'Hallo World', 202 new Scalar\String_('Hallo World') 203 ], 204 [ 205 [1, 2, 3], 206 new Expr\Array_([ 207 new \PhpParser\Node\ArrayItem(new Scalar\Int_(1)), 208 new \PhpParser\Node\ArrayItem(new Scalar\Int_(2)), 209 new \PhpParser\Node\ArrayItem(new Scalar\Int_(3)), 210 ]) 211 ], 212 [ 213 ['foo' => 'bar', 'bar' => 'foo'], 214 new Expr\Array_([ 215 new \PhpParser\Node\ArrayItem( 216 new Scalar\String_('bar'), 217 new Scalar\String_('foo') 218 ), 219 new \PhpParser\Node\ArrayItem( 220 new Scalar\String_('foo'), 221 new Scalar\String_('bar') 222 ), 223 ]) 224 ], 225 [ 226 new Scalar\MagicConst\Dir(), 227 new Scalar\MagicConst\Dir() 228 ] 229 ]; 230 } 231} 232