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