packages/sql-catalog/tests/Unit/Core/Php/SourceParserTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Core\Php;
6
7use PhpParser\Node\Stmt\Class_;
8use PhpParser\Node\Stmt\Namespace_;
9use PhpParser\Node\Stmt\Nop;
10use PHPUnit\Framework\Attributes\CoversClass;
11use PHPUnit\Framework\Attributes\UsesClass;
12use PHPUnit\Framework\TestCase;
13use SqlCatalog\Core\Php\ParsedFile;
14use SqlCatalog\Core\Php\SourceParser;
15use SqlCatalog\Core\Php\SyntaxException;
16
17#[CoversClass(SourceParser::class)]
18#[UsesClass(ParsedFile::class)]
19#[UsesClass(SyntaxException::class)]
20final class SourceParserTest extends TestCase
21{
22    public function testParseReturnsTheStatementsOfTheFile(): void
23    {
24        $file = (new SourceParser())->parse('a.php', '<?php $a = 1;');
25        self::assertSame('a.php', $file->path);
26        self::assertCount(1, $file->statements);
27    }
28
29    public function testParseResolvesNamesToTheirFullyQualifiedForm(): void
30    {
31        $file = (new SourceParser())->parse('a.php', '<?php namespace App; class User {}');
32        $namespace = $file->statements[0];
33        self::assertInstanceOf(Namespace_::class, $namespace);
34        $class = $namespace->stmts[0];
35        self::assertInstanceOf(Class_::class, $class);
36        self::assertSame('App\\User', $class->namespacedName?->toString());
37    }
38
39    public function testParseReportsTheFileASyntaxErrorCameFrom(): void
40    {
41        $this->expectException(SyntaxException::class);
42        $this->expectExceptionMessage('Cannot parse "broken.php"');
43        (new SourceParser())->parse('broken.php', '<?php function {');
44    }
45
46    public function testResolveNamesKeepsOnlyStatements(): void
47    {
48        self::assertCount(1, (new SourceParser())->resolveNames([new Nop()]));
49    }
50
51    public function testResolveNamesConnectsFileScopeSiblingsForWriteAnalysis(): void
52    {
53        $file = (new SourceParser())->parse('a.php', '<?php $a =& $b; $b = 1;');
54        self::assertSame($file->statements, $file->statements[1]->getAttribute('fileStatements'));
55    }
56
57}
58