packages/sql-faker/tests/Unit/Generation/Lexeme/LexemeCandidatesTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\Generation\Lexeme;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlFaker\Generation\Lexeme\LexemeCandidates;
11use SqlFaker\Generation\Lexeme\LexemeSequence;
12
13#[CoversClass(LexemeCandidates::class)]
14#[UsesClass(LexemeSequence::class)]
15#[UsesClass(\SqlFaker\Generation\Lexeme\Lexeme::class)]
16#[UsesClass(\SqlFaker\Generation\Lexeme\SpacingConstraint::class)]
17#[UsesClass(\SqlFaker\Generation\Token\TerminalOccurrence::class)]
18final class LexemeCandidatesTest extends TestCase
19{
20    public function testOfDistinguishesNoCandidatesFromOneEmptyOutputCandidate(): void
21    {
22        self::assertSame([], [...LexemeCandidates::of()->sequences()]);
23        $empty = new LexemeSequence([], 'eof');
24        self::assertSame([$empty], [...LexemeCandidates::of($empty)->sequences()]);
25    }
26
27    public function testSequencesDefersEvaluationAndCanBeTraversedRepeatedly(): void
28    {
29        $evaluations = 0;
30        $sequence = new LexemeSequence([], 'marker');
31        $candidates = new LexemeCandidates(static function () use (&$evaluations, $sequence): iterable {
32            ++$evaluations;
33            yield $sequence;
34        });
35        self::assertSame(0, $evaluations);
36        self::assertSame([$sequence], [...$candidates->sequences()]);
37        self::assertSame([$sequence], [...$candidates->sequences()]);
38        self::assertSame(2, $evaluations);
39    }
40}
41