packages/sql-faker/tests/Unit/PostgreSql/Generation/Rewrite/Name/AliasRuleTest.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\DataProvider;
9use PHPUnit\Framework\Attributes\UsesClass;
10use PHPUnit\Framework\TestCase;
11use SqlFaker\Generation\Derivation\DerivationTrace;
12use SqlFaker\Generation\Token\ProductionOccurrence;
13use SqlFaker\Generation\Token\TerminalOccurrence;
14use SqlFaker\Generation\Token\TerminalSequence;
15use SqlFaker\Grammar\Model\NonTerminal;
16use SqlFaker\Grammar\Model\Production;
17use SqlFaker\Grammar\Model\Terminal;
18use SqlFaker\PostgreSql\Generation\Rewrite\Name\AliasRule;
19
20#[CoversClass(AliasRule::class)]
21#[UsesClass(DerivationTrace::class)]
22#[UsesClass(ProductionOccurrence::class)]
23#[UsesClass(TerminalOccurrence::class)]
24#[UsesClass(TerminalSequence::class)]
25#[UsesClass(NonTerminal::class)]
26#[UsesClass(Production::class)]
27#[UsesClass(Terminal::class)]
28final class AliasRuleTest extends TestCase
29{
30    #[DataProvider('providerAliases')]
31    public function testRewriteMakesAliasesExplicitAndRetainsOriginalSubtrees(string $name, bool $explicit): void
32    {
33        $trace = new DerivationTrace('relation_expr_opt_alias');
34        $trace->expand(0, new Production([new Terminal('RELATION'), ...($explicit ? [new Terminal('AS')] : []), new NonTerminal('ColId')]), 0);
35        $trace->expand($explicit ? 2 : 1, new Production([new Terminal($name)]), 0);
36        $input = $trace->terminals();
37        $result = (new AliasRule())->rewrite($input);
38        self::assertSame(['RELATION', 'AS', $name], $result->names());
39        self::assertSame($input->original, $result->original);
40        self::assertSame($input->productions, $result->productions);
41        self::assertSame($input->terminals[count($input->terminals) - 1], $result->terminals[2]);
42        self::assertSame($result, (new AliasRule())->rewrite($result));
43    }
44
45    /**
46     * @return list<array{string, bool}>
47     */
48    public static function providerAliases(): array
49    {
50        return [['SET', false], ['SET', true], ['IDENT', false], ['IDENT', true]];
51    }
52
53    #[DataProvider('providerUnaliasedRoots')]
54    public function testRewritePreservesRelationsWithoutAnAliasAndUnrelatedNames(string $root): void
55    {
56        $trace = new DerivationTrace($root);
57        $trace->expand(0, new Production([new Terminal('SET')]), 0);
58        $input = $trace->terminals();
59        self::assertSame($input, (new AliasRule())->rewrite($input));
60    }
61
62    /**
63     * @return list<array{string}>
64     */
65    public static function providerUnaliasedRoots(): array
66    {
67        return [['relation_expr_opt_alias'], ['ordinary']];
68    }
69}
70