packages/sql-faker/tests/Unit/Compiler/Bison/Rule/BisonAlternativeDraftTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\Compiler\Bison\Rule;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlFaker\Compiler\Bison\Ast\BisonAlternativeNode;
11use SqlFaker\Compiler\Bison\Ast\BisonSymbolForm;
12use SqlFaker\Compiler\Bison\Ast\BisonSymbolNode;
13use SqlFaker\Compiler\Bison\Rule\BisonAlternativeDraft;
14
15#[CoversClass(BisonAlternativeDraft::class)]
16#[UsesClass(BisonAlternativeNode::class)]
17#[UsesClass(BisonSymbolNode::class)]
18#[UsesClass(BisonSymbolForm::class)]
19final class BisonAlternativeDraftTest extends TestCase
20{
21    public function testCompleteYieldsAnEmptyAlternativeWhenNothingWasRead(): void
22    {
23        $alternative = (new BisonAlternativeDraft())->complete();
24
25        self::assertSame([], $alternative->symbols);
26        self::assertNull($alternative->action);
27        self::assertNull($alternative->prec);
28        self::assertNull($alternative->dprec);
29        self::assertNull($alternative->merge);
30    }
31
32    public function testAddSymbolKeepsTheOrderTheSymbolsWereRead(): void
33    {
34        $draft = new BisonAlternativeDraft();
35        $first = new BisonSymbolNode(BisonSymbolForm::Identifier, 'expr');
36        $second = new BisonSymbolNode(BisonSymbolForm::CharLiteral, '+');
37
38        $draft->addSymbol($first);
39        $draft->addSymbol($second);
40
41        self::assertSame([$first, $second], $draft->complete()->symbols);
42    }
43
44    public function testSetActionAttachesTheCodeThatRunsOnReduction(): void
45    {
46        $draft = new BisonAlternativeDraft();
47
48        $draft->setAction('$$ = $1;');
49
50        self::assertSame('$$ = $1;', $draft->complete()->action);
51    }
52
53    public function testSetPrecedenceSymbolRecordsTheBorrowedTerminal(): void
54    {
55        $draft = new BisonAlternativeDraft();
56
57        $draft->setPrecedenceSymbol('UMINUS');
58
59        self::assertSame('UMINUS', $draft->complete()->prec);
60    }
61
62    public function testSetDynamicPrecedenceRecordsTheRank(): void
63    {
64        $draft = new BisonAlternativeDraft();
65
66        $draft->setDynamicPrecedence(2);
67
68        self::assertSame(2, $draft->complete()->dprec);
69    }
70
71    public function testSetMergeFunctionRecordsTheFunctionName(): void
72    {
73        $draft = new BisonAlternativeDraft();
74
75        $draft->setMergeFunction('merge');
76
77        self::assertSame('merge', $draft->complete()->merge);
78    }
79
80    public function testCompleteStartsANewAlternativeSoNothingCarriesOver(): void
81    {
82        $draft = new BisonAlternativeDraft();
83        $draft->addSymbol(new BisonSymbolNode(BisonSymbolForm::Identifier, 'expr'));
84        $draft->setAction('$$ = $1;');
85        $draft->setPrecedenceSymbol('UMINUS');
86        $draft->setDynamicPrecedence(2);
87        $draft->setMergeFunction('merge');
88
89        $draft->complete();
90        $second = $draft->complete();
91
92        self::assertSame([], $second->symbols);
93        self::assertNull($second->action);
94        self::assertNull($second->prec);
95        self::assertNull($second->dprec);
96        self::assertNull($second->merge);
97    }
98}
99