packages/sql-faker/tests/Unit/MySql/Generation/Lexeme/SizeNumberLexemeGeneratorTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\MySql\Generation\Lexeme;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\DataProvider;
9use PHPUnit\Framework\Attributes\UsesClass;
10use PHPUnit\Framework\TestCase;
11use SqlFaker\Generation\Lexeme\LexemeInput;
12use SqlFaker\Generation\Lexeme\ResolvedOutput;
13use SqlFaker\Generation\Token\TerminalSequence;
14use SqlFaker\MySql\Generation\Lexeme\SizeNumberLexemeGenerator;
15
16#[CoversClass(SizeNumberLexemeGenerator::class)]
17#[UsesClass(\SqlFaker\Generation\Candidate\IntegerLexemeGenerator::class)]
18#[UsesClass(\SqlFaker\Generation\Lexeme\Lexeme::class)]
19#[UsesClass(\SqlFaker\Generation\Lexeme\LexemeCandidates::class)]
20#[UsesClass(LexemeInput::class)]
21#[UsesClass(\SqlFaker\Generation\Lexeme\LexemeSequence::class)]
22#[UsesClass(ResolvedOutput::class)]
23#[UsesClass(\SqlFaker\Generation\Lexeme\SpacingConstraint::class)]
24#[UsesClass(\SqlFaker\Generation\Token\ProductionOccurrence::class)]
25#[UsesClass(\SqlFaker\Generation\Token\TerminalOccurrence::class)]
26#[UsesClass(TerminalSequence::class)]
27#[UsesClass(\SqlFaker\Generation\Value\IntegerDomain::class)]
28#[UsesClass(\SqlFaker\Generation\Value\SequenceDomain::class)]
29#[UsesClass(\SqlFaker\Generation\Value\WordDomain::class)]
30final class SizeNumberLexemeGeneratorTest extends TestCase
31{
32    #[DataProvider('providerSizes')]
33    public function testGeneratePreservesOnlyValidSizeSpellings(string $spelling, bool $valid): void
34    {
35        $sequence = TerminalSequence::fromNames(['SIZE_NUMBER']);
36        $result = (new SizeNumberLexemeGenerator())->generate(new LexemeInput($sequence, 0, new ResolvedOutput(), $spelling));
37        self::assertNotNull($result);
38        $candidates = [...$result->sequences()];
39        self::assertSame($valid ? [$spelling] : [], array_map(static fn ($candidate): string => $candidate->lexemes[0]->text, $candidates));
40        self::assertSame($valid ? [$sequence->terminals[0]] : [], array_map(static fn ($candidate) => $candidate->lexemes[0]->origin, $candidates));
41    }
42
43    /**
44     * @return list<array{string, bool}>
45     */
46    public static function providerSizes(): array
47    {
48        return [['0K', true], ['1m', true], ['2147483647G', true], ['0001k', true], ['`10M`', true], ['2147483648K', false], ['18446744073709551616G', false], ['-1M', false], ['10T', false], ['1.5M', false], ['10MB', false], ['`10M', false], ['10M`', false], ['name', false], ['', false]];
49    }
50
51    public function testGenerateProvidesEveryScaleAndLeavesOtherTerminalsUnclaimed(): void
52    {
53        $generator = new SizeNumberLexemeGenerator();
54        $result = $generator->generate(new LexemeInput(TerminalSequence::fromNames(['SIZE_NUMBER']), 0, new ResolvedOutput()));
55        self::assertNotNull($result);
56        self::assertSame(['1K', '1M', '1G'], array_map(static fn ($candidate): string => $candidate->lexemes[0]->text, [...$result->sequences()]));
57        self::assertNull($generator->generate(new LexemeInput(TerminalSequence::fromNames(['IDENT']), 0, new ResolvedOutput())));
58    }
59}
60