packages/sql-parser/tests/Unit/Table/ParseTableTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Table;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\Small;
9use PHPUnit\Framework\Attributes\UsesClass;
10use PHPUnit\Framework\TestCase;
11use SqlParser\Grammar\SymbolTable;
12use SqlParser\Table\ActionCode;
13use SqlParser\Table\ArrayRows;
14use SqlParser\Table\ParseTable;
15use SqlParser\Table\TableRule;
16
17#[CoversClass(ParseTable::class)]
18#[UsesClass(ActionCode::class)]
19#[UsesClass(ArrayRows::class)]
20#[UsesClass(SymbolTable::class)]
21#[UsesClass(TableRule::class)]
22#[Small]
23final class ParseTableTest extends TestCase
24{
25    public function testActionPrefersTheExplicitEntry(): void
26    {
27        $table = new ParseTable(new SymbolTable(['$end', 'ID', 'ABORT', 'ANY'], ['$accept', 's']), [new TableRule(4, 2, 0)], [ActionCode::reduce(0)], new ArrayRows([[1 => 7, 4 => 9]]));
28
29        self::assertSame(7, $table->action(0, 1));
30        self::assertSame(9, $table->action(0, 4));
31    }
32
33    public function testActionFallsBackThenUsesTheWildcardThenTheDefault(): void
34    {
35        $symbols = new SymbolTable(['$end', 'ID', 'ABORT', 'ANY', 'X'], ['$accept', 's']);
36        $table = new ParseTable($symbols, [new TableRule(5, 1, 0)], [ActionCode::reduce(0), ActionCode::ERROR], new ArrayRows([[1 => 7, 3 => 8], []]), [2 => 1], 3);
37
38        self::assertSame(7, $table->action(0, 2));
39        self::assertSame(8, $table->action(0, 4));
40        self::assertSame(ActionCode::reduce(0), $table->action(0, 0));
41        self::assertSame(ActionCode::ERROR, $table->action(1, 4));
42        self::assertSame(ActionCode::ERROR, $table->action(5, 4));
43    }
44
45    public function testExpectedTerminals(): void
46    {
47        $symbols = new SymbolTable(['$end', 'ID', 'ABORT'], ['$accept', 's']);
48        $table = new ParseTable($symbols, [], [ActionCode::ERROR], new ArrayRows([[2 => 4, 1 => ActionCode::ERROR, 4 => 3]]));
49
50        self::assertSame([2], $table->expectedTerminals(0));
51    }
52
53    public function testStateCount(): void
54    {
55        $table = new ParseTable(new SymbolTable(['$end'], ['$accept']), [], [ActionCode::ERROR, ActionCode::ERROR], new ArrayRows([[], []]));
56
57        self::assertSame(2, $table->stateCount());
58    }
59}
60