packages/sql-faker/tests/Unit/Sqlite/Generation/Rewrite/StrictTableRuleTest.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\Grammar\Model\NonTerminal;
12use SqlFaker\Grammar\Model\Production;
13use SqlFaker\Grammar\Model\Terminal;
14use SqlFaker\Sqlite\Generation\Rewrite\StrictTableRule;
15
16#[CoversClass(StrictTableRule::class)]
17#[UsesClass(DerivationTrace::class)]
18#[UsesClass(NonTerminal::class)]
19#[UsesClass(Production::class)]
20#[UsesClass(Terminal::class)]
21#[UsesClass(\SqlFaker\Generation\Token\ProductionOccurrence::class)]
22#[UsesClass(\SqlFaker\Generation\Token\TerminalOccurrence::class)]
23#[UsesClass(\SqlFaker\Generation\Token\TerminalSequence::class)]
24final class StrictTableRuleTest extends TestCase
25{
26 public function testRewriteFillsAnEmptyTypeOnlyInTheSameStrictTable(): void
27 {
28 $trace = new DerivationTrace('root');
29 $trace->expand(0, new Production([new NonTerminal('create_table_args'), new NonTerminal('create_table_args')]), 0);
30 $trace->expand(0, new Production([new NonTerminal('columnname'), new Terminal('STRICT_TABLE_OPTION')]), 0);
31 $trace->expand(0, new Production([new Terminal('ID'), new NonTerminal('typetoken')]), 0);
32 $trace->expand(1, new Production([]), 0);
33 $trace->expand(2, new Production([new NonTerminal('columnname')]), 0);
34 $trace->expand(2, new Production([new Terminal('ID'), new NonTerminal('typetoken')]), 0);
35 $trace->expand(3, new Production([]), 0);
36 $input = $trace->terminals();
37 $result = (new StrictTableRule())->rewrite($input);
38 self::assertSame(['ID', 'STRICT_COLUMN_TYPE', 'STRICT_TABLE_OPTION', 'ID'], $result->names());
39 self::assertSame(['root', 'create_table_args', 'columnname', 'typetoken'], $result->terminals[1]->rules);
40 self::assertSame($input->original, $result->original);
41 self::assertCount(count($result->terminals), array_unique(array_map(static fn ($terminal): int => $terminal->id, $result->terminals)));
42 self::assertSame($input->productions, $result->productions);
43 }
44
45 public function testRewriteReplacesTheWholeTypeIncludingItsSizeModifiers(): void
46 {
47 $trace = new DerivationTrace('create_table_args');
48 $trace->expand(0, new Production([new NonTerminal('columnname'), new Terminal('STRICT_TABLE_OPTION')]), 0);
49 $trace->expand(0, new Production([new Terminal('ID'), new NonTerminal('typetoken')]), 0);
50 $trace->expand(1, new Production([new Terminal('ID'), new Terminal('LP'), new Terminal('INTEGER'), new Terminal('RP')]), 2);
51 self::assertSame(['ID', 'STRICT_COLUMN_TYPE', 'STRICT_TABLE_OPTION'], (new StrictTableRule())->rewrite($trace->terminals())->names());
52 }
53}
54