1<?php declare(strict_types=1);
2
3namespace PhpParser\Builder;
4
5use PhpParser\Comment;
6use PhpParser\Modifiers;
7use PhpParser\Node\Arg;
8use PhpParser\Node\Attribute;
9use PhpParser\Node\AttributeGroup;
10use PhpParser\Node\Const_;
11use PhpParser\Node\Identifier;
12use PhpParser\Node\Name;
13use PhpParser\Node\Scalar\Int_;
14use PhpParser\Node\Stmt;
15use PhpParser\Node\Stmt\ClassConst;
16use PhpParser\Node\Stmt\ClassMethod;
17use PhpParser\Node\Stmt\Property;
18use PhpParser\Node\PropertyItem;
19use PhpParser\Node\Stmt\TraitUse;
20
21class TraitTest extends \PHPUnit\Framework\TestCase {
22    protected function createTraitBuilder($class) {
23        return new Trait_($class);
24    }
25
26    public function testStmtAddition(): void {
27        $method1 = new Stmt\ClassMethod('test1');
28        $method2 = new Stmt\ClassMethod('test2');
29        $method3 = new Stmt\ClassMethod('test3');
30        $prop = new Stmt\Property(Modifiers::PUBLIC, [
31            new PropertyItem('test')
32        ]);
33        $const = new ClassConst([new Const_('FOO', new Int_(0))]);
34        $use = new Stmt\TraitUse([new Name('OtherTrait')]);
35        $trait = $this->createTraitBuilder('TestTrait')
36            ->setDocComment('/** Nice trait */')
37            ->addStmt($method1)
38            ->addStmts([$method2, $method3])
39            ->addStmt($prop)
40            ->addStmt($use)
41            ->addStmt($const)
42            ->getNode();
43        $this->assertEquals(new Stmt\Trait_('TestTrait', [
44            'stmts' => [$use, $const, $prop, $method1, $method2, $method3]
45        ], [
46            'comments' => [
47                new Comment\Doc('/** Nice trait */')
48            ]
49        ]), $trait);
50    }
51
52    public function testInvalidStmtError(): void {
53        $this->expectException(\LogicException::class);
54        $this->expectExceptionMessage('Unexpected node of type "Stmt_Echo"');
55        $this->createTraitBuilder('Test')
56            ->addStmt(new Stmt\Echo_([]))
57        ;
58    }
59
60    public function testGetMethods(): void {
61        $methods = [
62            new ClassMethod('foo'),
63            new ClassMethod('bar'),
64            new ClassMethod('fooBar'),
65        ];
66        $trait = new Stmt\Trait_('Foo', [
67            'stmts' => [
68                new TraitUse([]),
69                $methods[0],
70                new ClassConst([]),
71                $methods[1],
72                new Property(0, []),
73                $methods[2],
74            ]
75        ]);
76
77        $this->assertSame($methods, $trait->getMethods());
78    }
79
80    public function testGetProperties(): void {
81        $properties = [
82            new Property(Modifiers::PUBLIC, [new PropertyItem('foo')]),
83            new Property(Modifiers::PUBLIC, [new PropertyItem('bar')]),
84        ];
85        $trait = new Stmt\Trait_('Foo', [
86            'stmts' => [
87                new TraitUse([]),
88                $properties[0],
89                new ClassConst([]),
90                $properties[1],
91                new ClassMethod('fooBar'),
92            ]
93        ]);
94
95        $this->assertSame($properties, $trait->getProperties());
96    }
97
98    public function testAddAttribute(): void {
99        $attribute = new Attribute(
100            new Name('Attr'),
101            [new Arg(new Int_(1), false, false, [], new Identifier('name'))]
102        );
103        $attributeGroup = new AttributeGroup([$attribute]);
104
105        $node = $this->createTraitBuilder('AttributeGroup')
106            ->addAttribute($attributeGroup)
107            ->getNode()
108        ;
109
110        $this->assertEquals(
111            new Stmt\Trait_(
112                'AttributeGroup',
113                [
114                    'attrGroups' => [$attributeGroup],
115                ]
116            ),
117            $node
118        );
119    }
120}
121