packages/sql-faker/tests/Unit/MySql/Generation/Rewrite/Partition/FieldListRuleTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\MySql\Generation\Rewrite\Partition;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\DataProvider;
9use PHPUnit\Framework\Attributes\UsesClass;
10use PHPUnit\Framework\TestCase;
11use SqlFaker\Generation\Derivation\DerivationTrace;
12use SqlFaker\Generation\Token\TerminalSequence;
13use SqlFaker\Grammar\Model\NonTerminal;
14use SqlFaker\Grammar\Model\Production;
15use SqlFaker\Grammar\Model\Terminal;
16use SqlFaker\MySql\Generation\Rewrite\Partition\FieldListRule;
17
18#[CoversClass(FieldListRule::class)]
19#[UsesClass(DerivationTrace::class)]
20#[UsesClass(NonTerminal::class)]
21#[UsesClass(Production::class)]
22#[UsesClass(Terminal::class)]
23#[UsesClass(\SqlFaker\Generation\Token\ProductionOccurrence::class)]
24#[UsesClass(\SqlFaker\Generation\Token\TerminalOccurrence::class)]
25#[UsesClass(TerminalSequence::class)]
26final class FieldListRuleTest extends TestCase
27{
28 /**
29 * @param list<string> $expected
30 */
31 #[DataProvider('providerLists')]
32 public function testRewriteKeepsUpToSixteenPartitionFieldsAndPreservesOtherLists(TerminalSequence $input, array $expected): void
33 {
34 $rule = new FieldListRule();
35 $result = $rule->rewrite($input);
36 self::assertSame($expected, $result->names());
37 self::assertSame($input->original, $result->original);
38 self::assertSame($input->productions, $result->productions);
39 self::assertSame($input->terminals[1], $result->terminals[1]);
40 self::assertSame($result, $rule->rewrite($result));
41 }
42
43 /**
44 * @return iterable<array{TerminalSequence, list<string>}>
45 */
46 public static function providerLists(): iterable
47 {
48 foreach ([['part_type_def', 'name_list', true], ['opt_sub_part', 'name_list', true], ['part_field_list', 'part_field_item_list', true], ['opt_sub_part', 'sub_part_field_list', true], ['ordinary', 'name_list', false]] as [$scope, $list, $limited]) {
49 foreach ([1, 16, 17, 19] as $count) {
50 $trace = new DerivationTrace($scope);
51 $trace->expand(0, new Production([new Terminal('PREFIX'), new NonTerminal($list), new Terminal('TAIL')]), 0);
52 $symbols = [];
53 $expected = ['PREFIX'];
54 for ($index = 0; $index < $count; ++$index) {
55 if ($index !== 0) {
56 $symbols[] = new Terminal(',');
57 }
58 $symbols[] = new NonTerminal('ident');
59 if (!$limited || $index < 16) {
60 if ($index !== 0) {
61 $expected[] = ',';
62 }
63 $expected[] = 'FIELD_' . $index;
64 }
65 }
66 $trace->expand(1, new Production($symbols), 0);
67 for ($index = 0; $index < $count; ++$index) {
68 $trace->expand(1 + 2 * $index, new Production([new Terminal('FIELD_' . $index)]), 0);
69 }
70 yield [$trace->terminals(), [...$expected, 'TAIL']];
71 }
72 }
73 }
74}
75