packages/sql-faker/tests/Unit/MySql/Generation/Lexeme/CharsetValueLexemeGeneratorTest.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\CharsetValueLexemeGenerator;
15
16#[CoversClass(CharsetValueLexemeGenerator::class)]
17#[UsesClass(LexemeInput::class)]
18#[UsesClass(ResolvedOutput::class)]
19#[UsesClass(TerminalSequence::class)]
20#[UsesClass(\SqlFaker\Generation\Candidate\ChoiceLexemeGenerator::class)]
21#[UsesClass(\SqlFaker\Generation\Candidate\IntegerLexemeGenerator::class)]
22#[UsesClass(\SqlFaker\Generation\Lexeme\Lexeme::class)]
23#[UsesClass(\SqlFaker\Generation\Lexeme\LexemeCandidates::class)]
24#[UsesClass(\SqlFaker\Generation\Lexeme\LexemeSequence::class)]
25#[UsesClass(\SqlFaker\Generation\Candidate\ValueLexemeGenerator::class)]
26#[UsesClass(\SqlFaker\Generation\Token\TerminalOccurrence::class)]
27#[UsesClass(\SqlFaker\Generation\Lexeme\SpacingConstraint::class)]
28#[UsesClass(\SqlFaker\Generation\Token\ProductionOccurrence::class)]
29#[UsesClass(\SqlFaker\Generation\Value\CharacterDomain::class)]
30#[UsesClass(\SqlFaker\Generation\Value\ChoiceDomain::class)]
31#[UsesClass(\SqlFaker\Generation\Value\IntegerDomain::class)]
32#[UsesClass(\SqlFaker\Generation\Value\SequenceDomain::class)]
33#[UsesClass(\SqlFaker\MySql\Generation\Value\DollarQuotedDomain::class)]
34#[UsesClass(\SqlFaker\Generation\Lexeme\OutputPart::class)]
35#[UsesClass(\SqlFaker\Generation\Value\ValueChoices::class)]
36#[UsesClass(\SqlFaker\MySql\Generation\Lexeme\CharsetLexemeGenerator::class)]
37#[UsesClass(\SqlFaker\MySql\Generation\Value\RadixDomain::class)]
38#[UsesClass(\SqlFaker\Generation\Value\Utf8::class)]
39#[UsesClass(\SqlFaker\Generation\Value\WordDomain::class)]
40#[UsesClass(\SqlFaker\MySql\Generation\Lexeme\DefinitionFactory::class)]
41#[UsesClass(\SqlFaker\MySql\Generation\Value\IdentifierDomain::class)]
42#[UsesClass(\SqlFaker\MySql\Generation\Value\QuotedDomain::class)]
43#[UsesClass(\SqlFaker\MySql\Generation\Lexeme\LexicalDefinition::class)]
44#[UsesClass(\SqlFaker\Generation\Output\SqlSerializer::class)]
45#[UsesClass(\SqlFaker\Generation\Plan\GenerationPlan::class)]
46#[UsesClass(\SqlFaker\Generation\Plan\ProductionPattern::class)]
47#[UsesClass(\SqlFaker\Generation\Candidate\FixedLexemeGenerator::class)]
48#[UsesClass(\SqlFaker\Generation\Candidate\MatchingLexemeGenerator::class)]
49#[UsesClass(\SqlFaker\Generation\Candidate\SequenceLexemeGenerator::class)]
50#[UsesClass(\SqlFaker\Generation\Output\BoundaryCompletion::class)]
51#[UsesClass(\SqlFaker\Generation\Output\CandidateResolver::class)]
52#[UsesClass(\SqlFaker\Generation\Output\ReverseLexemeGenerator::class)]
53#[UsesClass(\SqlFaker\Generation\Output\CombinedSpacingRule::class)]
54#[UsesClass(\SqlFaker\MySql\Generation\Spacing\KeywordPhraseSpacingRule::class)]
55#[UsesClass(\SqlFaker\Generation\Lexeme\LexemeBoundary::class)]
56#[UsesClass(\SqlFaker\Generation\Candidate\VersionCase::class)]
57#[UsesClass(\SqlFaker\Generation\Candidate\VersionedLexemeGenerator::class)]
58#[UsesClass(\SqlFaker\Generation\Exception\LexicalException::class)]
59#[UsesClass(\SqlFaker\MySql\Generation\Lexeme\BoundedIntegerLexemeGenerator::class)]
60#[UsesClass(\SqlFaker\MySql\Generation\Lexeme\FactorLexemeGenerator::class)]
61#[UsesClass(\SqlFaker\MySql\Generation\Lexeme\KeywordLexemeGenerator::class)]
62#[UsesClass(\SqlFaker\MySql\Generation\Lexeme\PrecisionLexemeGenerator::class)]
63#[UsesClass(\SqlFaker\MySql\Generation\Lexeme\ReplicationTablePatternLexemeGenerator::class)]
64#[UsesClass(\SqlFaker\MySql\Generation\Lexeme\SizeNumberLexemeGenerator::class)]
65#[UsesClass(\SqlFaker\MySql\Generation\Spacing\CloneAddressSpacingRule::class)]
66#[UsesClass(\SqlFaker\MySql\Generation\Spacing\FunctionSpacingRule::class)]
67#[UsesClass(\SqlFaker\MySql\Generation\Spacing\QualifiedNameSpacingRule::class)]
68#[UsesClass(\SqlFaker\MySql\Generation\Spacing\VariableSpacingRule::class)]
69#[UsesClass(\SqlFaker\Grammar\Resource\SqlVersionRegistry::class)]
70#[UsesClass(\SqlFaker\Grammar\Resource\SqlVersion::class)]
71final class CharsetValueLexemeGeneratorTest extends TestCase
72{
73    #[DataProvider('providerBinaryTokens')]
74    public function testGenerateSamplesCharsetCompatibleBytesWithoutRestrictingOrdinaryBinaryValues(string $terminal): void
75    {
76        $generator = (new \SqlFaker\MySql\Generation\Lexeme\DefinitionFactory())->create('mysql-8.4.7')->lexemes;
77        $ordinary = TerminalSequence::fromNames([$terminal]);
78        $introduced = TerminalSequence::fromNames(['UNDERSCORE_CHARSET', $terminal]);
79        $unrestricted = $generator->generate(new LexemeInput($ordinary, 0, new ResolvedOutput(), values: new \SqlFaker\Generation\Value\ValueChoices(static fn (int $count): int => $count - 1)));
80        $character = $generator->generate(new LexemeInput($introduced, 1, new ResolvedOutput(), values: new \SqlFaker\Generation\Value\ValueChoices(static fn (int $count): int => $count - 1)));
81        self::assertNotNull($unrestricted);
82        self::assertNotNull($character);
83        $charset = new \SqlFaker\MySql\Generation\Lexeme\CharsetLexemeGenerator();
84        self::assertFalse($charset->accepts('_utf8mb4', $charset->bytes([...$unrestricted->sequences()][0]->lexemes[0]->text)));
85        self::assertTrue($charset->accepts('_ascii', $charset->bytes([...$character->sequences()][0]->lexemes[0]->text)));
86    }
87
88    /**
89     * @return list<array{string}>
90     */
91    public static function providerBinaryTokens(): array
92    {
93        return [['HEX_NUM'], ['BIN_NUM']];
94    }
95
96}
97