packages/sql-faker/tests/Unit/Compiler/Lemon/LemonDirectivesTest.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\LemonDirectives;
11use SqlFaker\Compiler\Lemon\LemonSymbols;
12
13#[CoversClass(LemonDirectives::class)]
14#[UsesClass(LemonSymbols::class)]
15final class LemonDirectivesTest extends TestCase
16{
17 public function testDeclareIntoReadsTheTokensNamedOutright(): void
18 {
19 $symbols = new LemonSymbols();
20 (new LemonDirectives())->declareInto("%token SELECT INSERT.\n", $symbols);
21
22 self::assertTrue($symbols->isTerminal('INSERT'));
23 }
24
25 public function testDeclareIntoReadsTheTokensNamedWhileGivingThemAPrecedence(): void
26 {
27 $symbols = new LemonSymbols();
28 (new LemonDirectives())->declareInto("%left OR.\n%right NOT.\n%nonassoc LT.\n", $symbols);
29
30 self::assertTrue($symbols->isTerminal('OR'));
31 self::assertTrue($symbols->isTerminal('NOT'));
32 self::assertTrue($symbols->isTerminal('LT'));
33 }
34
35 public function testDeclareIntoReadsTheTokensNamedAsAFallback(): void
36 {
37 $symbols = new LemonSymbols();
38 (new LemonDirectives())->declareInto("%fallback ID ABORT ACTION.\n", $symbols);
39
40 self::assertTrue($symbols->isTerminal('ACTION'));
41 }
42
43 public function testDeclareIntoReadsAClassAndTheTokensItStandsFor(): void
44 {
45 $symbols = new LemonSymbols();
46 (new LemonDirectives())->declareInto("%token_class anytype INTEGER|TEXT|BLOB.\n", $symbols);
47
48 self::assertFalse($symbols->isTerminal('anytype'));
49 self::assertSame(['anytype' => ['INT', 'REAL']], (new LemonDirectives())->tokenClasses('%token_class anytype INT|REAL.'));
50 self::assertTrue($symbols->isTerminal('BLOB'));
51 }
52
53 public function testDeclareIntoReadsTheWildcardToken(): void
54 {
55 $symbols = new LemonSymbols();
56 (new LemonDirectives())->declareInto("%wildcard ANY.\n", $symbols);
57
58 self::assertTrue($symbols->isTerminal('ANY'));
59 }
60
61 public function testTokenClassesRetainsEveryAlternativeAcrossLines(): void
62 {
63 self::assertSame(['id' => ['ID', 'INDEXED'], 'number' => ['INTEGER', 'FLOAT']], (new LemonDirectives())->tokenClasses("%token_class id ID|INDEXED.\n%token_class number INTEGER\n FLOAT."));
64 }
65
66}
67