1<?php declare(strict_types=1);
2
3namespace PhpParser\Builder;
4
5use PhpParser\Modifiers;
6use PhpParser\Node\Name;
7use PhpParser\Node\Stmt;
8use PhpParser\Node\Stmt\Class_;
9
10class TraitUseAdaptationTest extends \PHPUnit\Framework\TestCase {
11    protected function createTraitUseAdaptationBuilder($trait, $method) {
12        return new TraitUseAdaptation($trait, $method);
13    }
14
15    public function testAsMake(): void {
16        $builder = $this->createTraitUseAdaptationBuilder(null, 'foo');
17
18        $this->assertEquals(
19            new Stmt\TraitUseAdaptation\Alias(null, 'foo', null, 'bar'),
20            (clone $builder)->as('bar')->getNode()
21        );
22
23        $this->assertEquals(
24            new Stmt\TraitUseAdaptation\Alias(null, 'foo', Modifiers::PUBLIC, null),
25            (clone $builder)->makePublic()->getNode()
26        );
27
28        $this->assertEquals(
29            new Stmt\TraitUseAdaptation\Alias(null, 'foo', Modifiers::PROTECTED, null),
30            (clone $builder)->makeProtected()->getNode()
31        );
32
33        $this->assertEquals(
34            new Stmt\TraitUseAdaptation\Alias(null, 'foo', Modifiers::PRIVATE, null),
35            (clone $builder)->makePrivate()->getNode()
36        );
37    }
38
39    public function testInsteadof(): void {
40        $node = $this->createTraitUseAdaptationBuilder('SomeTrait', 'foo')
41            ->insteadof('AnotherTrait')
42            ->getNode()
43        ;
44
45        $this->assertEquals(
46            new Stmt\TraitUseAdaptation\Precedence(
47                new Name('SomeTrait'),
48                'foo',
49                [new Name('AnotherTrait')]
50            ),
51            $node
52        );
53    }
54
55    public function testAsOnNotAlias(): void {
56        $this->expectException(\LogicException::class);
57        $this->expectExceptionMessage('Cannot set alias for not alias adaptation buider');
58        $this->createTraitUseAdaptationBuilder('Test', 'foo')
59            ->insteadof('AnotherTrait')
60            ->as('bar')
61        ;
62    }
63
64    public function testInsteadofOnNotPrecedence(): void {
65        $this->expectException(\LogicException::class);
66        $this->expectExceptionMessage('Cannot add overwritten traits for not precedence adaptation buider');
67        $this->createTraitUseAdaptationBuilder('Test', 'foo')
68            ->as('bar')
69            ->insteadof('AnotherTrait')
70        ;
71    }
72
73    public function testInsteadofWithoutTrait(): void {
74        $this->expectException(\LogicException::class);
75        $this->expectExceptionMessage('Precedence adaptation must have trait');
76        $this->createTraitUseAdaptationBuilder(null, 'foo')
77            ->insteadof('AnotherTrait')
78        ;
79    }
80
81    public function testMakeOnNotAlias(): void {
82        $this->expectException(\LogicException::class);
83        $this->expectExceptionMessage('Cannot set access modifier for not alias adaptation buider');
84        $this->createTraitUseAdaptationBuilder('Test', 'foo')
85            ->insteadof('AnotherTrait')
86            ->makePublic()
87        ;
88    }
89
90    public function testMultipleMake(): void {
91        $this->expectException(\LogicException::class);
92        $this->expectExceptionMessage('Multiple access type modifiers are not allowed');
93        $this->createTraitUseAdaptationBuilder(null, 'foo')
94            ->makePrivate()
95            ->makePublic()
96        ;
97    }
98
99    public function testUndefinedType(): void {
100        $this->expectException(\LogicException::class);
101        $this->expectExceptionMessage('Type of adaptation is not defined');
102        $this->createTraitUseAdaptationBuilder(null, 'foo')
103            ->getNode()
104        ;
105    }
106}
107