packages/sql-faker/tests/Unit/PostgreSql/Generation/Rewrite/Routine/WithinGroupRuleTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\PostgreSql\Generation\Rewrite\Routine;
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\Routine\WithinGroupRule;
15
16#[CoversClass(WithinGroupRule::class)]
17#[UsesClass(ProductionOccurrence::class)]
18#[UsesClass(TerminalOccurrence::class)]
19#[UsesClass(TerminalSequence::class)]
20final class WithinGroupRuleTest extends TestCase
21{
22 #[DataProvider('providerClauses')]
23 public function testRewriteRetainsWithinGroupAndNestedFunctions(bool $within): void
24 {
25 $productions = [new ProductionOccurrence(0, null, 'func_expr', 0), new ProductionOccurrence(1, 0, 'func_application', 1), new ProductionOccurrence(2, 1, 'opt_sort_clause', 0), new ProductionOccurrence(3, 0, 'within_group_clause', 0), new ProductionOccurrence(4, 1, 'func_application', 2), new ProductionOccurrence(9, null, 'func_expr', 1)];
26 $tokens = [
27 new TerminalOccurrence('F', 10, [0, 1], ['func_expr', 'func_application']),
28 new TerminalOccurrence('DISTINCT', 11, [0, 1], ['func_expr', 'func_application']),
29 new TerminalOccurrence('VARIADIC', 12, [0, 1], ['func_expr', 'func_application']),
30 new TerminalOccurrence('DISTINCT', 13, [0, 1, 4], ['func_expr', 'func_application', 'func_application']),
31 new TerminalOccurrence('ORDER', 14, [0, 1, 2], ['func_expr', 'func_application', 'opt_sort_clause']),
32 ];
33 $clause = new TerminalOccurrence('WITHIN', 15, [0, 3], ['func_expr', 'within_group_clause']);
34 $tokens = [...$tokens, ...($within ? [$clause] : [])];
35 $input = new TerminalSequence($tokens, $tokens, [], $productions);
36 $rule = new WithinGroupRule();
37 $result = $rule->rewrite($input);
38 self::assertSame($within ? [$tokens[0], $tokens[3], $clause] : $tokens, $result->terminals);
39 self::assertSame($input->original, $result->original);
40 self::assertSame($input->productions, $result->productions);
41 self::assertSame($result->terminals, $rule->rewrite($result)->terminals);
42 }
43
44 /**
45 * @return list<array{bool}>
46 */
47 public static function providerClauses(): array
48 {
49 return [[true], [false]];
50 }
51
52 public function testRewriteKeepsFunctionsWithoutWithinGroupMetadata(): void
53 {
54 $input = TerminalSequence::fromNames(['DISTINCT', 'VARIADIC', 'ORDER']);
55 self::assertSame($input, (new WithinGroupRule())->rewrite($input));
56 }
57}
58