packages/sql-faker/tests/Unit/PostgreSql/Generation/Rewrite/Name/RelationNameRuleTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\PostgreSql\Generation\Rewrite\Name;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlFaker\Generation\Token\ProductionOccurrence;
11use SqlFaker\Generation\Token\TerminalOccurrence;
12use SqlFaker\Generation\Token\TerminalSequence;
13use SqlFaker\PostgreSql\Generation\Rewrite\Name\RelationNameRule;
14
15#[CoversClass(RelationNameRule::class)]
16#[UsesClass(ProductionOccurrence::class)]
17#[UsesClass(TerminalOccurrence::class)]
18#[UsesClass(TerminalSequence::class)]
19final class RelationNameRuleTest extends TestCase
20{
21    public function testRewriteRemovesRelationStarsButPreservesExpressionIndirection(): void
22    {
23        $star = new TerminalOccurrence('.', 3, [0, 1, 2], ['qualified_name', 'indirection', 'indirection_el']);
24        $suffix = new TerminalOccurrence('*', 4, [0, 1, 2], ['qualified_name', 'indirection', 'indirection_el']);
25        $expression = new TerminalOccurrence('[', 9, [5, 6, 7, 8], ['qualified_name', 'expression', 'indirection', 'indirection_el']);
26        $input = new TerminalSequence([$star, $suffix, $expression], [], [], [
27            new ProductionOccurrence(2, 1, 'indirection_el', 1), new ProductionOccurrence(8, 7, 'indirection_el', 2),
28        ]);
29        self::assertSame([$expression], (new RelationNameRule())->rewrite($input)->terminals);
30    }
31    public function testRewriteLimitsRelationNamesToCatalogSchemaAndTable(): void
32    {
33        $scope = 'qualified_name';
34        $base = new TerminalOccurrence('IDENT', 10, [0], [$scope]);
35        $first = new TerminalOccurrence('.', 11, [0, 1, 2], [$scope, 'indirection', 'indirection_el']);
36        $firstName = new TerminalOccurrence('IDENT', 12, [0, 1, 2], [$scope, 'indirection', 'indirection_el']);
37        $second = new TerminalOccurrence('.', 13, [0, 1, 3], [$scope, 'indirection', 'indirection_el']);
38        $secondName = new TerminalOccurrence('IDENT', 14, [0, 1, 3], [$scope, 'indirection', 'indirection_el']);
39        $third = new TerminalOccurrence('.', 15, [0, 1, 4], [$scope, 'indirection', 'indirection_el']);
40        $thirdName = new TerminalOccurrence('IDENT', 16, [0, 1, 4], [$scope, 'indirection', 'indirection_el']);
41        $terminals = [$base, $first, $firstName, $second, $secondName, $third, $thirdName];
42        $input = new TerminalSequence($terminals, $terminals, [], [
43            new ProductionOccurrence(0, null, $scope, 0), new ProductionOccurrence(1, 0, 'indirection', 0),
44            new ProductionOccurrence(2, 1, 'indirection_el', 0), new ProductionOccurrence(3, 1, 'indirection_el', 0),
45            new ProductionOccurrence(4, 1, 'indirection_el', 0),
46        ]);
47        $rule = new RelationNameRule();
48        $result = $rule->rewrite($input);
49        self::assertSame([$base, $first, $firstName, $second, $secondName], $result->terminals);
50        self::assertSame($input->original, $result->original);
51        self::assertCount(count($result->terminals), array_unique(array_map(static fn ($terminal): int => $terminal->id, $result->terminals)));
52        self::assertSame($input->productions, $result->productions);
53        self::assertSame($result, $rule->rewrite($result));
54    }
55
56}
57