packages/sql-faker/tests/Unit/MySql/Generation/Rewrite/RequiredAliasRuleTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\MySql\Generation\Rewrite;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlFaker\Generation\Derivation\DerivationTrace;
11use SqlFaker\Grammar\Model\NonTerminal;
12use SqlFaker\Grammar\Model\Production;
13use SqlFaker\Grammar\Model\Terminal;
14use SqlFaker\MySql\Generation\Rewrite\RequiredAliasRule;
15
16#[CoversClass(RequiredAliasRule::class)]
17#[UsesClass(DerivationTrace::class)]
18#[UsesClass(NonTerminal::class)]
19#[UsesClass(Production::class)]
20#[UsesClass(Terminal::class)]
21#[UsesClass(\SqlFaker\Generation\Token\ProductionOccurrence::class)]
22#[UsesClass(\SqlFaker\Generation\Token\TerminalOccurrence::class)]
23#[UsesClass(\SqlFaker\Generation\Token\TerminalSequence::class)]
24final class RequiredAliasRuleTest extends TestCase
25{
26 public function testRewriteInsertsAnAliasBeforeTheDerivedColumnList(): void
27 {
28 $trace = new DerivationTrace('derived_table');
29 $trace->expand(0, new Production([new Terminal('QUERY'), new NonTerminal('opt_table_alias'), new NonTerminal('opt_derived_column_list')]), 0);
30 $trace->expand(1, new Production([]), 0);
31 $trace->expand(1, new Production([new Terminal('('), new Terminal('IDENT'), new Terminal(')')]), 1);
32 $input = $trace->terminals();
33 $result = (new RequiredAliasRule())->rewrite($input);
34 self::assertSame(['QUERY', 'AS', 'IDENT_QUOTED', '(', 'IDENT', ')'], $result->names());
35 self::assertSame(['derived_table', 'opt_table_alias'], $result->terminals[1]->rules);
36 self::assertSame($input->original, $result->original);
37 self::assertCount(count($result->terminals), array_unique(array_map(static fn ($terminal): int => $terminal->id, $result->terminals)));
38 }
39
40 public function testRewriteKeepsTheCallerSelectedAlias(): void
41 {
42 $trace = new DerivationTrace('table_function');
43 $trace->expand(0, new Production([new Terminal('JSON_TABLE_SYM'), new NonTerminal('opt_table_alias')]), 0);
44 $trace->expand(1, new Production([new Terminal('AS'), new Terminal('IDENT')]), 1);
45 $input = $trace->terminals();
46 self::assertSame($input, (new RequiredAliasRule())->rewrite($input));
47 }
48}
49