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