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