packages/sql-faker/tests/Unit/Sqlite/Generation/Rewrite/TableOptionRuleTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\Sqlite\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\ProductionOccurrence;
12use SqlFaker\Generation\Token\TerminalOccurrence;
13use SqlFaker\Generation\Token\TerminalSequence;
14use SqlFaker\Grammar\Model\NonTerminal;
15use SqlFaker\Grammar\Model\Production;
16use SqlFaker\Grammar\Model\Terminal;
17use SqlFaker\Sqlite\Generation\Rewrite\TableOptionRule;
18
19#[CoversClass(TableOptionRule::class)]
20#[UsesClass(DerivationTrace::class)]
21#[UsesClass(NonTerminal::class)]
22#[UsesClass(Production::class)]
23#[UsesClass(ProductionOccurrence::class)]
24#[UsesClass(Terminal::class)]
25#[UsesClass(TerminalOccurrence::class)]
26#[UsesClass(TerminalSequence::class)]
27final class TableOptionRuleTest extends TestCase
28{
29    public function testRewriteConstrainsOnlyTheTwoTableOptionPositions(): void
30    {
31        $trace = new DerivationTrace('table');
32        $trace->expand(0, new Production([new Terminal('ID'), new NonTerminal('table_option'), new NonTerminal('table_option')]), 0);
33        $trace->expand(1, new Production([new Terminal('ID')]), 0);
34        $trace->expand(2, new Production([new Terminal('WITHOUT'), new Terminal('ID')]), 1);
35        $input = $trace->terminals();
36        $result = (new TableOptionRule())->rewrite($input);
37        self::assertSame(['ID', 'STRICT_TABLE_OPTION', 'WITHOUT', 'ROWID_TABLE_OPTION'], $result->names());
38        self::assertSame($input->original, $result->original);
39        self::assertCount(count($result->terminals), array_unique(array_map(static fn ($terminal): int => $terminal->id, $result->terminals)));
40        self::assertSame($input->productions, $result->productions);
41    }
42
43    public function testRewriteLeavesUnrelatedAndEmptyScopesUntouched(): void
44    {
45        $input = new TerminalSequence([new TerminalOccurrence('ID', 0)], [], [], [new ProductionOccurrence(1, null, 'table_option', 0)]);
46        self::assertSame($input, (new TableOptionRule())->rewrite($input));
47    }
48}
49