1<?php declare(strict_types=1);
2
3namespace PhpParser;
4
5use PhpParser\Node\Name;
6use PhpParser\Node\Stmt\Use_;
7
8class NameContextTest extends \PHPUnit\Framework\TestCase {
9    /**
10     * @dataProvider provideTestGetPossibleNames
11     */
12    public function testGetPossibleNames($type, $name, $expectedPossibleNames): void {
13        $nameContext = new NameContext(new ErrorHandler\Throwing());
14        $nameContext->startNamespace(new Name('NS'));
15        $nameContext->addAlias(new Name('Foo'), 'Foo', Use_::TYPE_NORMAL);
16        $nameContext->addAlias(new Name('Foo\Bar'), 'Alias', Use_::TYPE_NORMAL);
17        $nameContext->addAlias(new Name('Foo\fn'), 'fn', Use_::TYPE_FUNCTION);
18        $nameContext->addAlias(new Name('Foo\CN'), 'CN', Use_::TYPE_CONSTANT);
19
20        $possibleNames = $nameContext->getPossibleNames($name, $type);
21        $possibleNames = array_map(function (Name $name) {
22            return $name->toCodeString();
23        }, $possibleNames);
24
25        $this->assertSame($expectedPossibleNames, $possibleNames);
26
27        // Here the last name is always the shortest one
28        $expectedShortName = $expectedPossibleNames[count($expectedPossibleNames) - 1];
29        $this->assertSame(
30            $expectedShortName,
31            $nameContext->getShortName($name, $type)->toCodeString()
32        );
33    }
34
35    public static function provideTestGetPossibleNames() {
36        return [
37            [Use_::TYPE_NORMAL, 'Test', ['\Test']],
38            [Use_::TYPE_NORMAL, 'Test\Namespaced', ['\Test\Namespaced']],
39            [Use_::TYPE_NORMAL, 'NS\Test', ['\NS\Test', 'Test']],
40            [Use_::TYPE_NORMAL, 'ns\Test', ['\ns\Test', 'Test']],
41            [Use_::TYPE_NORMAL, 'NS\Foo\Bar', ['\NS\Foo\Bar']],
42            [Use_::TYPE_NORMAL, 'ns\foo\Bar', ['\ns\foo\Bar']],
43            [Use_::TYPE_NORMAL, 'Foo', ['\Foo', 'Foo']],
44            [Use_::TYPE_NORMAL, 'Foo\Bar', ['\Foo\Bar', 'Foo\Bar', 'Alias']],
45            [Use_::TYPE_NORMAL, 'Foo\Bar\Baz', ['\Foo\Bar\Baz', 'Foo\Bar\Baz', 'Alias\Baz']],
46            [Use_::TYPE_NORMAL, 'Foo\fn\Bar', ['\Foo\fn\Bar', 'Foo\fn\Bar']],
47            [Use_::TYPE_FUNCTION, 'Foo\fn\bar', ['\Foo\fn\bar', 'Foo\fn\bar']],
48            [Use_::TYPE_FUNCTION, 'Foo\fn', ['\Foo\fn', 'Foo\fn', 'fn']],
49            [Use_::TYPE_FUNCTION, 'Foo\FN', ['\Foo\FN', 'Foo\FN', 'fn']],
50            [Use_::TYPE_CONSTANT, 'Foo\CN\BAR', ['\Foo\CN\BAR', 'Foo\CN\BAR']],
51            [Use_::TYPE_CONSTANT, 'Foo\CN', ['\Foo\CN', 'Foo\CN', 'CN']],
52            [Use_::TYPE_CONSTANT, 'foo\CN', ['\foo\CN', 'Foo\CN', 'CN']],
53            [Use_::TYPE_CONSTANT, 'foo\cn', ['\foo\cn', 'Foo\cn']],
54            // self/parent/static must not be fully qualified
55            [Use_::TYPE_NORMAL, 'self', ['self']],
56            [Use_::TYPE_NORMAL, 'parent', ['parent']],
57            [Use_::TYPE_NORMAL, 'static', ['static']],
58            // true/false/null do not need to be fully qualified, even in namespaces
59            [Use_::TYPE_CONSTANT, 'true', ['\true', 'true']],
60            [Use_::TYPE_CONSTANT, 'false', ['\false', 'false']],
61            [Use_::TYPE_CONSTANT, 'null', ['\null', 'null']],
62        ];
63    }
64}
65