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