packages/sql-faker/tests/Unit/Sqlite/Generation/Lexeme/JoinLexemeGeneratorTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\Sqlite\Generation\Lexeme;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlFaker\Generation\Lexeme\Lexeme;
11use SqlFaker\Generation\Lexeme\LexemeGenerator;
12use SqlFaker\Generation\Lexeme\LexemeInput;
13use SqlFaker\Generation\Lexeme\OutputPart;
14use SqlFaker\Generation\Lexeme\ResolvedOutput;
15use SqlFaker\Generation\Token\ProductionOccurrence;
16use SqlFaker\Generation\Token\TerminalOccurrence;
17use SqlFaker\Generation\Token\TerminalSequence;
18use SqlFaker\Sqlite\Generation\Lexeme\JoinLexemeGenerator;
19
20#[CoversClass(JoinLexemeGenerator::class)]
21#[UsesClass(Lexeme::class)]
22#[UsesClass(LexemeGenerator::class)]
23#[UsesClass(LexemeInput::class)]
24#[UsesClass(OutputPart::class)]
25#[UsesClass(ProductionOccurrence::class)]
26#[UsesClass(ResolvedOutput::class)]
27#[UsesClass(TerminalOccurrence::class)]
28#[UsesClass(TerminalSequence::class)]
29#[UsesClass(\SqlFaker\Generation\Lexeme\LexemeCandidates::class)]
30#[UsesClass(\SqlFaker\Generation\Lexeme\LexemeSequence::class)]
31#[UsesClass(\SqlFaker\Sqlite\Generation\Lexeme\JoinModifiers::class)]
32#[UsesClass(\SqlFaker\Generation\Lexeme\SpacingConstraint::class)]
33#[UsesClass(\SqlFaker\Generation\Exception\LexicalException::class)]
34final class JoinLexemeGeneratorTest extends TestCase
35{
36 public function testGenerateKeepsOnlyModifiersCompatibleWithTheSelectedSuffix(): void
37 {
38 $first = new TerminalOccurrence('JOIN_KW', 2, [0, 1], ['seltablist', 'joinop']);
39 $second = new TerminalOccurrence('JOIN_MODIFIER', 3, [0, 1], ['seltablist', 'joinop']);
40 $sequence = new TerminalSequence([$first, $second]);
41 $right = new ResolvedOutput([new OutputPart(new Lexeme('OUTER', 'join-modifier', $second, 'source'), ' ', 'outer')]);
42 $generator = new JoinLexemeGenerator(['INNER', 'LEFT', 'RIGHT', 'FULL', 'OUTER']);
43 $result = $generator->generate(new LexemeInput($sequence, 0, $right));
44 self::assertNotNull($result);
45 self::assertSame(['LEFT', 'RIGHT', 'FULL'], array_map(static fn ($candidate): string => $candidate->lexemes[0]->text, [...$result->sequences()]));
46 self::assertNull($generator->generate(new LexemeInput(TerminalSequence::fromNames(['JOIN_KW']), 0, new ResolvedOutput())));
47 }
48
49 public function testHasConditionReadsOnlyTheSameSourceList(): void
50 {
51 $modifier = new TerminalOccurrence('JOIN_KW', 2, [0, 1], ['seltablist', 'joinop']);
52 $condition = new TerminalOccurrence('ON', 4, [0, 3], ['seltablist', 'on_using']);
53 $sequence = new TerminalSequence([$modifier, $condition], [], [], [new ProductionOccurrence(3, 0, 'on_using', 1)]);
54 self::assertTrue((new JoinLexemeGenerator([]))->hasCondition(new LexemeInput($sequence, 0, new ResolvedOutput())));
55 $empty = new TerminalSequence([$modifier], [], [], [new ProductionOccurrence(3, 0, 'on_using', 0)]);
56 self::assertFalse((new JoinLexemeGenerator([]))->hasCondition(new LexemeInput($empty, 0, new ResolvedOutput())));
57 }
58}
59