packages/sql-faker/tests/Unit/Generation/Derivation/Completion/PatternProductionsTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Generation\Derivation\Completion;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlFaker\Generation\Derivation\Completion\PatternProductions;
11use SqlFaker\Generation\Plan\ProductionPattern;
12use SqlFaker\Grammar\Model\Grammar;
13use SqlFaker\Grammar\Model\NonTerminal;
14use SqlFaker\Grammar\Model\Production;
15use SqlFaker\Grammar\Model\ProductionRule;
16use SqlFaker\Grammar\Model\Terminal;
17
18#[CoversClass(PatternProductions::class)]
19#[UsesClass(ProductionPattern::class)]
20#[UsesClass(Grammar::class)]
21#[UsesClass(Production::class)]
22#[UsesClass(ProductionRule::class)]
23#[UsesClass(Terminal::class)]
24#[UsesClass(NonTerminal::class)]
25final class PatternProductionsTest extends TestCase
26{
27 public function testMatchingSeparatesPatternsAndRuleScopesWhenReusingItsCache(): void
28 {
29 $empty = new Production([]);
30 $output = new Production([new Terminal('T')]);
31 $grammar = new Grammar('root', ['root' => new ProductionRule('root', [$empty, $output]), 'other' => new ProductionRule('other', [$output])]);
32 $choices = new PatternProductions($grammar);
33 self::assertSame([$output], $choices->matching('root', ProductionPattern::at(1)));
34 self::assertSame([$output], $choices->matching('root', ProductionPattern::at(1)));
35 self::assertSame([$empty], $choices->matching('root', ProductionPattern::exactly()));
36 self::assertSame([$empty, $output], $choices->matching('root', null));
37 self::assertSame([], $choices->matching('other', ProductionPattern::at(1)));
38 self::assertSame([], $choices->matching('missing', null));
39 }
40
41 public function testSourceRuleAndMatchingUseOriginalNamesAndOrdinals(): void
42 {
43 $production = new Production([new Terminal('T')], 4);
44 $grammar = new Grammar('@plan0', ['@plan0' => new ProductionRule('@plan0', [$production])], ['@plan0' => 'root']);
45 $choices = new PatternProductions($grammar);
46 self::assertSame('root', $choices->sourceRule('@plan0'));
47 self::assertSame([$production], $choices->matching('@plan0', ProductionPattern::at(4)));
48 self::assertSame([], $choices->matching('@plan0', ProductionPattern::at(0)));
49 }
50
51
52 public function testMatchingUsesSourceSymbolNamesInSpecializedProductions(): void
53 {
54 $production = new Production([new Terminal('SELECT'), new NonTerminal('special')], 3);
55 $grammar = new Grammar('root', [
56 'root' => new ProductionRule('root', [$production]),
57 'special' => new ProductionRule('special', [new Production([new Terminal('ID')])]),
58 ], ['special' => 'name']);
59 $choices = new PatternProductions($grammar);
60 self::assertSame([$production], $choices->matching('root', ProductionPattern::exactly('SELECT', 'name')));
61 self::assertSame([], $choices->matching('root', ProductionPattern::exactly('SELECT', 'special')));
62 }
63
64}
65