packages/sql-faker/tests/Unit/MySql/Generation/Rewrite/Routine/LanguageRuleTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\MySql\Generation\Rewrite\Routine;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\DataProvider;
9use PHPUnit\Framework\Attributes\UsesClass;
10use PHPUnit\Framework\TestCase;
11use SqlFaker\Generation\Token\ProductionOccurrence;
12use SqlFaker\Generation\Token\TerminalOccurrence;
13use SqlFaker\Generation\Token\TerminalSequence;
14use SqlFaker\MySql\Generation\Rewrite\Routine\LanguageRule;
15
16#[CoversClass(LanguageRule::class)]
17#[UsesClass(ProductionOccurrence::class)]
18#[UsesClass(TerminalOccurrence::class)]
19#[UsesClass(TerminalSequence::class)]
20final class LanguageRuleTest extends TestCase
21{
22 #[DataProvider('providerBodies')]
23 public function testRewriteSelectsTheLanguageFromTheRetainedBody(string $scope, string $body, ?string $language): void
24 {
25 $name = new TerminalOccurrence('IDENT', 10, [0], [$scope]);
26 $content = new TerminalOccurrence($body, 11, [0, 1], [$scope, 'stored_routine_body']);
27 $input = new TerminalSequence([$name, $content], productions: [new ProductionOccurrence(0, null, $scope, 0), new ProductionOccurrence(1, 0, 'stored_routine_body', 0)]);
28 $result = (new LanguageRule())->rewrite($input);
29 self::assertSame($language === null ? ['IDENT', $body] : ['IDENT', 'LANGUAGE_SYM', $language, $body], $result->names());
30 self::assertSame($input->original, $result->original);
31 self::assertSame($input->productions, $result->productions);
32 self::assertSame($content, $result->terminals[count($result->terminals) - 1]);
33 self::assertCount(count($result->terminals), array_unique(array_column($result->terminals, 'id')));
34 self::assertSame($result, (new LanguageRule())->rewrite($result));
35 }
36
37 /**
38 * @return list<array{string, string, string|null}>
39 */
40 public static function providerBodies(): array
41 {
42 return [['sp_tail', 'AS', 'EXTERNAL_ROUTINE_LANGUAGE'], ['sf_tail', 'AS', 'EXTERNAL_ROUTINE_LANGUAGE'], ['sp_tail', 'BEGIN_SYM', 'SQL_SYM'], ['sf_tail', 'RETURN_SYM', 'SQL_SYM'], ['ordinary', 'AS', null]];
43 }
44
45 public function testRewritePreservesAnEmptyBody(): void
46 {
47 $input = new TerminalSequence([], productions: [new ProductionOccurrence(0, null, 'stored_routine_body', 0)]);
48 self::assertSame($input, (new LanguageRule())->rewrite($input));
49 }
50}
51