packages/sql-faker/tests/Unit/Compiler/Lemon/LemonRulesTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\Compiler\Lemon;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlFaker\Compiler\Lemon\LemonRules;
11use SqlFaker\Compiler\Lemon\LemonSymbols;
12use SqlFaker\Compiler\Lemon\LemonText;
13
14#[CoversClass(LemonRules::class)]
15#[UsesClass(LemonSymbols::class)]
16#[UsesClass(LemonText::class)]
17final class LemonRulesTest extends TestCase
18{
19 public function testReadFromGathersTheAlternativesOfOneRuleWrittenOnSeveralLines(): void
20 {
21 self::assertSame(
22 ['cmd' => [['SELECT'], ['INSERT']]],
23 (new LemonRules())->readFrom("cmd ::= SELECT.\ncmd ::= INSERT.\n", new LemonSymbols()),
24 );
25 }
26
27 public function testReadFromReadsARuleThatWritesNothing(): void
28 {
29 self::assertSame(['opt' => [[]]], (new LemonRules())->readFrom("opt ::= .\n", new LemonSymbols()));
30 }
31
32 public function testReadFromDropsTheAliasASymbolCarries(): void
33 {
34 self::assertSame(
35 ['cmd' => [['expr']]],
36 (new LemonRules())->readFrom("cmd(A) ::= expr(X).\n", new LemonSymbols()),
37 );
38 }
39
40 public function testReadFromTellsTheSymbolTableWhatEachNameTurnedOutToBe(): void
41 {
42 $symbols = new LemonSymbols();
43 (new LemonRules())->readFrom("cmd ::= SELECT expr.\n", $symbols);
44
45 self::assertTrue($symbols->isTerminal('SELECT'));
46 self::assertFalse($symbols->isTerminal('cmd'));
47 }
48
49 public function testAlternativesMultipliesOutEachAlternationPosition(): void
50 {
51 self::assertSame(
52 [['A', 'C'], ['A', 'D'], ['B', 'C'], ['B', 'D']],
53 (new LemonRules())->alternatives('A|B C|D', new LemonSymbols()),
54 );
55 }
56
57 public function testAlternativesIgnoresAPositionThatConfiguresTheParser(): void
58 {
59 self::assertSame([['expr']], (new LemonRules())->alternatives('expr %prec', new LemonSymbols()));
60 }
61
62 public function testWithoutAliasDropsWhatTheParserNamesTheValue(): void
63 {
64 self::assertSame('expr', (new LemonRules())->withoutAlias('expr(A)'));
65 }
66
67 public function testWithoutAliasLeavesASymbolWithNoAliasAlone(): void
68 {
69 self::assertSame('expr', (new LemonRules())->withoutAlias('expr'));
70 }
71}
72