packages/sql-faker/tests/Unit/PostgreSql/Generation/Rewrite/OperatorArgumentsRuleTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\PostgreSql\Generation\Rewrite;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlFaker\Generation\Derivation\DerivationTrace;
11use SqlFaker\Generation\Token\TerminalSequence;
12use SqlFaker\Grammar\Model\Production;
13use SqlFaker\Grammar\Model\Terminal;
14use SqlFaker\PostgreSql\Generation\Rewrite\OperatorArgumentsRule;
15
16#[CoversClass(OperatorArgumentsRule::class)]
17#[UsesClass(DerivationTrace::class)]
18#[UsesClass(Production::class)]
19#[UsesClass(Terminal::class)]
20#[UsesClass(TerminalSequence::class)]
21#[UsesClass(\SqlFaker\Generation\Token\TerminalOccurrence::class)]
22#[UsesClass(\SqlFaker\Generation\Token\ProductionOccurrence::class)]
23#[UsesClass(\SqlFaker\Grammar\Model\NonTerminal::class)]
24final class OperatorArgumentsRuleTest extends TestCase
25{
26 public function testRewriteCompletesOnlyAUnaryOperatorSignature(): void
27 {
28 $trace = new DerivationTrace('oper_argtypes');
29 $trace->expand(0, new Production([new Terminal('('), new Terminal('NUMERIC'), new Terminal('('), new Terminal('ICONST'), new Terminal(','), new Terminal('ICONST'), new Terminal(')'), new Terminal(')')]), 0);
30 $input = $trace->terminals();
31 $result = (new OperatorArgumentsRule())->rewrite($input);
32 self::assertSame(['(', 'NONE', ',', 'NUMERIC', '(', 'ICONST', ',', 'ICONST', ')', ')'], $result->names());
33 self::assertSame($input->original, $result->original);
34 self::assertCount(count($result->terminals), array_unique(array_map(static fn ($terminal): int => $terminal->id, $result->terminals)));
35 self::assertSame($result, (new OperatorArgumentsRule())->rewrite($result));
36 }
37
38 public function testHasArgumentSeparatorDistinguishesNestedTypeModifiers(): void
39 {
40 $rule = new OperatorArgumentsRule();
41 $nested = TerminalSequence::fromNames(['(', 'NUMERIC', '(', 'ICONST', ',', 'ICONST', ')', ')']);
42 self::assertFalse($rule->hasArgumentSeparator($nested, 0, 8));
43 $binary = TerminalSequence::fromNames(['(', 'NONE', ',', 'INT', ')']);
44 self::assertTrue($rule->hasArgumentSeparator($binary, 0, 5));
45 }
46}
47