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\Expr;
12use PhpParser\Node\Identifier;
13use PhpParser\Node\Name;
14use PhpParser\Node\Scalar;
15use PhpParser\Node\Scalar\Int_;
16use PhpParser\Node\Stmt;
17
18class ClassConstTest extends \PHPUnit\Framework\TestCase {
19    public function createClassConstBuilder($name, $value) {
20        return new ClassConst($name, $value);
21    }
22
23    public function testModifiers(): void {
24        $node = $this->createClassConstBuilder("TEST", 1)
25            ->makePrivate()
26            ->getNode()
27        ;
28
29        $this->assertEquals(
30            new Stmt\ClassConst(
31                [
32                    new Const_("TEST", new Int_(1))
33                ],
34                Modifiers::PRIVATE
35            ),
36            $node
37        );
38
39        $node = $this->createClassConstBuilder("TEST", 1)
40            ->makeProtected()
41            ->getNode()
42        ;
43
44        $this->assertEquals(
45            new Stmt\ClassConst(
46                [
47                    new Const_("TEST", new Int_(1))
48                ],
49                Modifiers::PROTECTED
50            ),
51            $node
52        );
53
54        $node = $this->createClassConstBuilder("TEST", 1)
55            ->makePublic()
56            ->getNode()
57        ;
58
59        $this->assertEquals(
60            new Stmt\ClassConst(
61                [
62                    new Const_("TEST", new Int_(1))
63                ],
64                Modifiers::PUBLIC
65            ),
66            $node
67        );
68
69        $node = $this->createClassConstBuilder("TEST", 1)
70            ->makeFinal()
71            ->getNode()
72        ;
73
74        $this->assertEquals(
75            new Stmt\ClassConst(
76                [
77                    new Const_("TEST", new Int_(1))
78                ],
79                Modifiers::FINAL
80            ),
81            $node
82        );
83    }
84
85    public function testDocComment(): void {
86        $node = $this->createClassConstBuilder('TEST', 1)
87            ->setDocComment('/** Test */')
88            ->makePublic()
89            ->getNode();
90
91        $this->assertEquals(
92            new Stmt\ClassConst(
93                [
94                    new Const_("TEST", new Int_(1))
95                ],
96                Modifiers::PUBLIC,
97                [
98                    'comments' => [new Comment\Doc('/** Test */')]
99                ]
100            ),
101            $node
102        );
103    }
104
105    public function testAddConst(): void {
106        $node = $this->createClassConstBuilder('FIRST_TEST', 1)
107            ->addConst("SECOND_TEST", 2)
108            ->getNode();
109
110        $this->assertEquals(
111            new Stmt\ClassConst(
112                [
113                    new Const_("FIRST_TEST", new Int_(1)),
114                    new Const_("SECOND_TEST", new Int_(2))
115                ]
116            ),
117            $node
118        );
119    }
120
121    public function testAddAttribute(): void {
122        $attribute = new Attribute(
123            new Name('Attr'),
124            [new Arg(new Int_(1), false, false, [], new Identifier('name'))]
125        );
126        $attributeGroup = new AttributeGroup([$attribute]);
127
128        $node = $this->createClassConstBuilder('ATTR_GROUP', 1)
129            ->addAttribute($attributeGroup)
130            ->getNode();
131
132        $this->assertEquals(
133            new Stmt\ClassConst(
134                [
135                    new Const_("ATTR_GROUP", new Int_(1))
136                ],
137                0,
138                [],
139                [$attributeGroup]
140            ),
141            $node
142        );
143    }
144
145    public function testType(): void {
146        $node = $this->createClassConstBuilder('TYPE', 1)
147            ->setType('int')
148            ->getNode();
149        $this->assertEquals(
150            new Stmt\ClassConst(
151                [new Const_('TYPE', new Int_(1))],
152                0, [], [], new Identifier('int')),
153            $node
154        );
155    }
156
157    /**
158     * @dataProvider provideTestDefaultValues
159     */
160    public function testValues($value, $expectedValueNode): void {
161        $node = $this->createClassConstBuilder('TEST', $value)
162            ->getNode()
163        ;
164
165        $this->assertEquals($expectedValueNode, $node->consts[0]->value);
166    }
167
168    public static function provideTestDefaultValues() {
169        return [
170            [
171                null,
172                new Expr\ConstFetch(new Name('null'))
173            ],
174            [
175                true,
176                new Expr\ConstFetch(new Name('true'))
177            ],
178            [
179                false,
180                new Expr\ConstFetch(new Name('false'))
181            ],
182            [
183                31415,
184                new Scalar\Int_(31415)
185            ],
186            [
187                3.1415,
188                new Scalar\Float_(3.1415)
189            ],
190            [
191                'Hallo World',
192                new Scalar\String_('Hallo World')
193            ],
194            [
195                [1, 2, 3],
196                new Expr\Array_([
197                    new \PhpParser\Node\ArrayItem(new Scalar\Int_(1)),
198                    new \PhpParser\Node\ArrayItem(new Scalar\Int_(2)),
199                    new \PhpParser\Node\ArrayItem(new Scalar\Int_(3)),
200                ])
201            ],
202            [
203                ['foo' => 'bar', 'bar' => 'foo'],
204                new Expr\Array_([
205                    new \PhpParser\Node\ArrayItem(
206                        new Scalar\String_('bar'),
207                        new Scalar\String_('foo')
208                    ),
209                    new \PhpParser\Node\ArrayItem(
210                        new Scalar\String_('foo'),
211                        new Scalar\String_('bar')
212                    ),
213                ])
214            ],
215            [
216                new Scalar\MagicConst\Dir(),
217                new Scalar\MagicConst\Dir()
218            ]
219        ];
220    }
221}
222