packages/sql-faker/tests/Unit/PostgreSql/Generation/Rewrite/Routine/AggregateArgumentRuleTest.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\AggregateArgumentRule;
15
16#[CoversClass(AggregateArgumentRule::class)]
17#[UsesClass(ProductionOccurrence::class)]
18#[UsesClass(TerminalOccurrence::class)]
19#[UsesClass(TerminalSequence::class)]
20final class AggregateArgumentRuleTest extends TestCase
21{
22 #[DataProvider('providerModes')]
23 public function testRewriteKeepsOrdinaryFunctionModesAndNormalizesAggregateInputModes(string $scope, string $mode, bool $ordered, bool $kept): void
24 {
25 $words = explode(' ', $mode);
26 $modes = array_map(static fn (int $index, string $name): TerminalOccurrence =>
27 new TerminalOccurrence($name, $index + 10, [0, 1, 2], ['aggr_args', $scope, 'arg_class']), array_keys($words), $words);
28 $order = new TerminalOccurrence('ORDER', 20, [0], ['aggr_args']);
29 $terminals = [...$modes, ...($ordered ? [$order] : [])];
30 $input = new TerminalSequence($terminals, $terminals, [], [
31 new ProductionOccurrence(0, null, 'aggr_args', 0), new ProductionOccurrence(1, 0, $scope, 0),
32 new ProductionOccurrence(2, 1, 'arg_class', 0),
33 ]);
34 $rule = new AggregateArgumentRule();
35 $result = $rule->rewrite($input);
36 self::assertSame([...($kept ? $words : ['IN_P']), ...($ordered ? ['ORDER'] : [])], $result->names());
37 self::assertSame($input->original, $result->original);
38 self::assertSame($result, $rule->rewrite($result));
39 }
40
41 /**
42 * @return iterable<array{string, string, bool, bool}>
43 */
44 public static function providerModes(): iterable
45 {
46 yield ['aggr_arg', 'OUT_P', false, false];
47 yield ['aggr_arg', 'INOUT', false, false];
48 yield ['aggr_arg', 'IN_P OUT_P', false, false];
49 yield ['aggr_arg', 'IN_P', true, true];
50 yield ['aggr_arg', 'VARIADIC', false, true];
51 yield ['aggr_arg', 'VARIADIC', true, false];
52 yield ['func_arg', 'OUT_P', false, true];
53 }
54}
55