packages/sql-faker/tests/Unit/MySql/Generation/Lexeme/FactorLexemeGeneratorTest.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\Lexeme;
12use SqlFaker\Generation\Lexeme\LexemeInput;
13use SqlFaker\Generation\Lexeme\OutputPart;
14use SqlFaker\Generation\Lexeme\ResolvedOutput;
15use SqlFaker\Generation\Token\TerminalOccurrence;
16use SqlFaker\Generation\Token\TerminalSequence;
17use SqlFaker\MySql\Generation\Lexeme\FactorLexemeGenerator;
18
19#[CoversClass(FactorLexemeGenerator::class)]
20#[UsesClass(Lexeme::class)]
21#[UsesClass(LexemeInput::class)]
22#[UsesClass(OutputPart::class)]
23#[UsesClass(ResolvedOutput::class)]
24#[UsesClass(TerminalOccurrence::class)]
25#[UsesClass(TerminalSequence::class)]
26#[UsesClass(\SqlFaker\Generation\Lexeme\LexemeCandidates::class)]
27#[UsesClass(\SqlFaker\Generation\Lexeme\LexemeSequence::class)]
28#[UsesClass(\SqlFaker\Generation\Lexeme\SpacingConstraint::class)]
29#[UsesClass(\SqlFaker\Generation\Candidate\ValueLexemeGenerator::class)]
30#[UsesClass(\SqlFaker\Generation\Value\WordDomain::class)]
31final class FactorLexemeGeneratorTest extends TestCase
32{
33 /**
34 * @param list<string> $expected
35 */
36 #[DataProvider('providerFactors')]
37 public function testGenerateKeepsFactorPairsDistinctWithinTheirUser(string $action, bool $prior, ?string $rightValue, bool $sameUser, array $expected): void
38 {
39 $terminals = $prior ? [new TerminalOccurrence('AUTH_FACTOR_NUMBER', 10, [0, 1], ['alter_user', 'factor'])] : [];
40 $terminals[] = new TerminalOccurrence($action, 11, [0], ['alter_user']);
41 $origin = new TerminalOccurrence('AUTH_FACTOR_NUMBER', 12, [0, 2], ['alter_user', 'factor']);
42 $terminals[] = $origin;
43 $rightOrigin = new TerminalOccurrence('AUTH_FACTOR_NUMBER', 13, [$sameUser ? 0 : 9, 3], ['alter_user', 'factor']);
44 $right = new ResolvedOutput($rightValue === null ? [] : [new OutputPart(new Lexeme($rightValue, 'number', $rightOrigin, 'source'), '', 'candidate')]);
45 $input = new LexemeInput(new TerminalSequence($terminals), count($terminals) - 1, $right);
46 $result = (new FactorLexemeGenerator())->generate($input);
47 self::assertNotNull($result);
48 $candidates = [...$result->sequences()];
49 self::assertSame($expected, array_map(static fn ($candidate): string => $candidate->lexemes[0]->text, $candidates));
50 self::assertSame(array_fill(0, count($expected), $origin), array_map(static fn ($candidate) => $candidate->lexemes[0]->origin, $candidates));
51 }
52
53 /**
54 * @return list<array{string, bool, string|null, bool, list<string>}>
55 */
56 public static function providerFactors(): array
57 {
58 return [['DROP', false, null, true, ['2', '3']], ['DROP', false, '2', true, ['3']], ['DROP', false, '3', true, ['2']], ['ADD', true, null, true, ['3']], ['ADD', false, '3', true, ['2']], ['MODIFY_SYM', true, null, true, ['2', '3']], ['DROP', false, '2', false, ['2', '3']]];
59 }
60
61 #[DataProvider('providerSpellings')]
62 public function testGenerateAcceptsOnlyExactFactorSpellings(string $spelling, bool $valid): void
63 {
64 $input = new LexemeInput(TerminalSequence::fromNames(['AUTH_FACTOR_NUMBER']), 0, new ResolvedOutput(), $spelling);
65 $result = (new FactorLexemeGenerator())->generate($input);
66 self::assertNotNull($result);
67 self::assertSame($valid ? [$spelling] : [], array_map(static fn ($candidate): string => $candidate->lexemes[0]->text, [...$result->sequences()]));
68 }
69
70 /**
71 * @return list<array{string, bool}>
72 */
73 public static function providerSpellings(): array
74 {
75 return [['2', true], ['3', true], ['0', false], ['1', false], ['02', false], ['4', false]];
76 }
77
78 public function testGenerateLeavesOrdinaryNumbersToTheirGenerator(): void
79 {
80 self::assertNull((new FactorLexemeGenerator())->generate(new LexemeInput(TerminalSequence::fromNames(['NUM']), 0, new ResolvedOutput())));
81 }
82}
83