packages/sql-faker/tests/Unit/PostgreSql/Generation/Rewrite/Name/AnyRelationNameRuleTest.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\AnyRelationNameRule;
15
16#[CoversClass(AnyRelationNameRule::class)]
17#[UsesClass(ProductionOccurrence::class)]
18#[UsesClass(TerminalOccurrence::class)]
19#[UsesClass(TerminalSequence::class)]
20final class AnyRelationNameRuleTest extends TestCase
21{
22 /**
23 * @param list<string> $expected
24 */
25 #[DataProvider('providerNames')]
26 public function testRewriteLimitsOnlyNamesConvertedToRelations(TerminalSequence $input, array $expected): void
27 {
28 $rule = new AnyRelationNameRule();
29 $result = $rule->rewrite($input);
30 self::assertSame($expected, $result->names());
31 self::assertSame($input->original, $result->original);
32 self::assertCount(count($result->terminals), array_unique(array_map(static fn ($terminal): int => $terminal->id, $result->terminals)));
33 self::assertSame($result, $rule->rewrite($result));
34 }
35
36 /**
37 * @return iterable<string, array{TerminalSequence, list<string>}>
38 */
39 public static function providerNames(): iterable
40 {
41 foreach (['AlterCompositeTypeStmt', 'DefineStmt', 'RenameStmt', 'DropStmt', 'CreateDomainStmt'] as $scope) {
42 $names = [new TerminalOccurrence('IDENT', 100, [0, 1], [$scope, 'any_name'])];
43 $productions = [new ProductionOccurrence(0, null, $scope, 0), new ProductionOccurrence(1, 0, 'any_name', 0)];
44 foreach (range(2, 4) as $id) {
45 $names[] = new TerminalOccurrence('.', 100 + count($names), [0, 1], [$scope, 'any_name']);
46 $names[] = new TerminalOccurrence('IDENT', 100 + count($names), [0, 1, $id], [$scope, 'any_name', 'attr_name']);
47 $productions[] = new ProductionOccurrence($id, 1, 'attr_name', 0);
48 }
49 $suffix = [];
50 if ($scope === 'DefineStmt') {
51 $productions[] = new ProductionOccurrence(9, 0, 'OptTableFuncElementList', 0);
52 }
53 if ($scope === 'RenameStmt') {
54 $suffix = ['RENAME', 'ATTRIBUTE'];
55 $names[] = new TerminalOccurrence('RENAME', 110, [0], [$scope]);
56 $names[] = new TerminalOccurrence('ATTRIBUTE', 111, [0], [$scope]);
57 }
58 $expected = ['IDENT', '.', 'IDENT', '.', 'IDENT'];
59 if (in_array($scope, ['DropStmt', 'CreateDomainStmt'], true)) {
60 array_push($expected, '.', 'IDENT');
61 }
62 yield $scope => [new TerminalSequence($names, $names, [], $productions), [...$expected, ...$suffix]];
63 }
64 }
65}
66