packages/sql-faker/tests/Unit/PostgreSql/Generation/Rewrite/Name/ParserNameRuleTest.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\Token\ProductionOccurrence;
12use SqlFaker\Generation\Token\TerminalOccurrence;
13use SqlFaker\Generation\Token\TerminalSequence;
14use SqlFaker\PostgreSql\Generation\Rewrite\Name\ParserNameRule;
15
16#[CoversClass(ParserNameRule::class)]
17#[UsesClass(ProductionOccurrence::class)]
18#[UsesClass(TerminalOccurrence::class)]
19#[UsesClass(TerminalSequence::class)]
20final class ParserNameRuleTest extends TestCase
21{
22    #[DataProvider('providerNames')]
23    public function testRewriteRestrictsOnlyTheDirectParserNameChild(string $owner, string $child, string $expected): void
24    {
25        $terminals = [new TerminalOccurrence('IDENT', 10, [0, 1], [$owner, $child]), new TerminalOccurrence('IDENT', 11, [0, 2, 3], [$owner, 'nested', $child])];
26        $sequence = new TerminalSequence($terminals, $terminals, [], [new ProductionOccurrence(0, null, $owner, 0), new ProductionOccurrence(1, 0, $child, 0), new ProductionOccurrence(2, 0, 'nested', 0), new ProductionOccurrence(3, 2, $child, 0)]);
27        $rule = new ParserNameRule();
28        $result = $rule->rewrite($sequence);
29        self::assertSame([$expected, 'IDENT'], $result->names());
30        self::assertSame($sequence->original, $result->original);
31        self::assertSame($result, $rule->rewrite($result));
32    }
33
34    /**
35     * @return list<array{string, string, string}>
36     */
37    public static function providerNames(): array
38    {
39        return [['PartitionSpec', 'ColId', 'PARTITION_STRATEGY'], ['json_format_clause', 'name', 'JSON_ENCODING']];
40    }
41
42    #[DataProvider('providerRoles')]
43    public function testRewriteAllowsSpecialRoleReferencesOutsideLiteralRoleId(string $name): void
44    {
45        $terminals = [new TerminalOccurrence($name, 10, [0, 1], ['RoleId', 'RoleSpec']), new TerminalOccurrence($name, 11, [2], ['RoleSpec'])];
46        $rule = new ParserNameRule();
47        $result = $rule->rewrite(new TerminalSequence($terminals, $terminals));
48        self::assertSame(['IDENT', $name], $result->names());
49        self::assertSame($result, $rule->rewrite($result));
50    }
51
52    /**
53     * @return list<array{string}>
54     */
55    public static function providerRoles(): array
56    {
57        return [['CURRENT_ROLE'], ['CURRENT_USER'], ['SESSION_USER']];
58    }
59
60    public function testRewriteRetainsMissingAndEmptyNames(): void
61    {
62        $sequence = new TerminalSequence([], [], [], [new ProductionOccurrence(0, null, 'PartitionSpec', 0), new ProductionOccurrence(1, 0, 'ColId', 0), new ProductionOccurrence(2, null, 'json_format_clause', 0)]);
63        self::assertSame($sequence, (new ParserNameRule())->rewrite($sequence));
64    }
65}
66