1<?php declare(strict_types=1); 2 3namespace PhpParser\Node; 4 5use PhpParser\Modifiers; 6use PhpParser\Node\Expr\Assign; 7use PhpParser\Node\Expr\PropertyFetch; 8use PhpParser\Node\Expr\Variable; 9use PhpParser\Node\Scalar\Int_; 10use PhpParser\Node\Stmt\Expression; 11use PhpParser\Node\Stmt\Return_; 12use PhpParser\ParserFactory; 13use PhpParser\PrettyPrinter\Standard; 14 15class PropertyHookTest extends \PHPUnit\Framework\TestCase { 16 /** 17 * @dataProvider provideModifiers 18 */ 19 public function testModifiers($modifier): void { 20 $node = new PropertyHook( 21 'get', 22 null, 23 [ 24 'flags' => constant(Modifiers::class . '::' . strtoupper($modifier)), 25 ] 26 ); 27 28 $this->assertTrue($node->{'is' . $modifier}()); 29 } 30 31 public function testNoModifiers(): void { 32 $node = new PropertyHook('get', null); 33 34 $this->assertFalse($node->isFinal()); 35 } 36 37 public static function provideModifiers() { 38 return [ 39 ['final'], 40 ]; 41 } 42 43 public function testGetStmts(): void { 44 $expr = new Variable('test'); 45 $get = new PropertyHook('get', $expr); 46 $this->assertEquals([new Return_($expr)], $get->getStmts()); 47 48 $set = new PropertyHook('set', $expr, [], ['propertyName' => 'abc']); 49 $this->assertEquals([ 50 new Expression(new Assign(new PropertyFetch(new Variable('this'), 'abc'), $expr)) 51 ], $set->getStmts()); 52 } 53 54 public function testGetStmtsSetHookFromParser(): void { 55 $parser = (new ParserFactory())->createForNewestSupportedVersion(); 56 $prettyPrinter = new Standard(); 57 $stmts = $parser->parse(<<<'CODE' 58 <?php 59 class Test { 60 public $prop1 { set => 123; } 61 62 public function __construct(public $prop2 { set => 456; }) {} 63 } 64 CODE); 65 66 $hook1 = $stmts[0]->stmts[0]->hooks[0]; 67 $this->assertEquals('$this->prop1 = 123;', $prettyPrinter->prettyPrint($hook1->getStmts())); 68 69 $hook2 = $stmts[0]->stmts[1]->params[0]->hooks[0]; 70 $this->assertEquals('$this->prop2 = 456;', $prettyPrinter->prettyPrint($hook2->getStmts())); 71 } 72 73 public function testGetStmtsUnknownHook(): void { 74 $expr = new Variable('test'); 75 $hook = new PropertyHook('foobar', $expr); 76 77 $this->expectException(\LogicException::class); 78 $this->expectExceptionMessage('Unknown property hook "foobar"'); 79 $hook->getStmts(); 80 } 81 82 public function testGetStmtsSetHookWithoutPropertyName(): void { 83 $expr = new Variable('test'); 84 $set = new PropertyHook('set', $expr); 85 $this->expectException(\LogicException::class); 86 $this->expectExceptionMessage('Can only use getStmts() on a "set" hook if the "propertyName" attribute is set'); 87 $set->getStmts(); 88 } 89} 90