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