packages/sql-faker/tests/Unit/Generation/Candidate/MatchingLexemeGeneratorTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\Generation\Candidate;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlFaker\Generation\Candidate\FixedLexemeGenerator;
11use SqlFaker\Generation\Candidate\MatchingLexemeGenerator;
12use SqlFaker\Generation\Candidate\ValueLexemeGenerator;
13use SqlFaker\Generation\Lexeme\LexemeGenerator;
14use SqlFaker\Generation\Lexeme\LexemeInput;
15use SqlFaker\Generation\Lexeme\ResolvedOutput;
16use SqlFaker\Generation\Token\TerminalSequence;
17
18#[CoversClass(MatchingLexemeGenerator::class)]
19#[UsesClass(FixedLexemeGenerator::class)]
20#[UsesClass(LexemeGenerator::class)]
21#[UsesClass(LexemeInput::class)]
22#[UsesClass(ValueLexemeGenerator::class)]
23#[UsesClass(ResolvedOutput::class)]
24#[UsesClass(TerminalSequence::class)]
25#[UsesClass(\SqlFaker\Generation\Lexeme\Lexeme::class)]
26#[UsesClass(\SqlFaker\Generation\Lexeme\LexemeCandidates::class)]
27#[UsesClass(\SqlFaker\Generation\Lexeme\LexemeSequence::class)]
28#[UsesClass(\SqlFaker\Generation\Token\TerminalOccurrence::class)]
29#[UsesClass(\SqlFaker\Generation\Lexeme\SpacingConstraint::class)]
30#[UsesClass(\SqlFaker\Generation\Token\ProductionOccurrence::class)]
31#[UsesClass(\SqlFaker\Generation\Value\WordDomain::class)]
32final class MatchingLexemeGeneratorTest extends TestCase
33{
34    public function testGenerateDistinguishesNonApplicabilityFromAMatchedEmptyCandidateSet(): void
35    {
36        $input = new LexemeInput(TerminalSequence::fromNames(['NAME']), 0, new ResolvedOutput(), 'y');
37        $child = new ValueLexemeGenerator('NAME', new \SqlFaker\Generation\Value\WordDomain(['x']), ['x'], 'identifier', 'test');
38        self::assertNull((new MatchingLexemeGenerator('OTHER', $child))->generate($input));
39        $result = (new MatchingLexemeGenerator('NAME', $child))->generate($input);
40        self::assertNotNull($result);
41        self::assertSame([], [...$result->sequences()]);
42    }
43
44    public function testGenerateMakesTheCompleteStructuralInputAvailableToPredicates(): void
45    {
46        $input = new LexemeInput(TerminalSequence::fromNames(['@', 'NAME']), 1, new ResolvedOutput());
47        $generator = new MatchingLexemeGenerator(
48            static fn (LexemeInput $context): bool => $context->terminals->nameAt($context->index - 1) === '@',
49            new FixedLexemeGenerator('user', 'hostname', 'scanner'),
50        );
51        $result = $generator->generate($input);
52        self::assertNotNull($result);
53        self::assertSame('user', [...$result->sequences()][0]->lexemes[0]->text);
54    }
55}
56