packages/sql-faker/tests/Unit/MySql/Generation/Rewrite/Query/QueryContextRuleTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\MySql\Generation\Rewrite\Query;
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\Query\QueryContextRule;
15
16#[CoversClass(QueryContextRule::class)]
17#[UsesClass(ProductionOccurrence::class)]
18#[UsesClass(TerminalOccurrence::class)]
19#[UsesClass(TerminalSequence::class)]
20final class QueryContextRuleTest extends TestCase
21{
22    #[DataProvider('providerOptions')]
23    public function testRewriteRestrictsOnlyNestedSelectOptions(string $name, string $scope, string $role, bool $remove): void
24    {
25        $option = new TerminalOccurrence($name, 1, [0, 2], [$scope, $role]);
26        $input = new TerminalSequence([$option], [$option]);
27        $result = (new QueryContextRule())->rewrite($input);
28        self::assertSame($remove ? [] : [$option], $result->terminals);
29        self::assertSame($input->original, $result->original);
30    }
31
32    /**
33     * @return list<array{string, string, string, bool}>
34     */
35    public static function providerOptions(): array
36    {
37        return [
38            ['SQL_BUFFER_RESULT', 'subquery', 'select_option', true],
39            ['SQL_CALC_FOUND_ROWS', 'subquery', 'select_option', true],
40            ['HIGH_PRIORITY', 'subquery', 'select_option', true],
41            ['SQL_BIG_RESULT', 'subquery', 'select_option', false],
42            ['HIGH_PRIORITY', 'select_stmt', 'select_option', false],
43            ['HIGH_PRIORITY', 'subquery', 'ident', false],
44        ];
45    }
46
47    #[DataProvider('providerSources')]
48    public function testRewriteSeparatesCreateTableQuerySources(string $first, bool $insert): void
49    {
50        $query = new TerminalOccurrence($first, 1, [0], ['as_create_query_expression']);
51        $input = new TerminalSequence([$query], [$query], [], [new ProductionOccurrence(0, null, 'as_create_query_expression', 1), new ProductionOccurrence(9, null, 'as_create_query_expression', 0)]);
52        $rule = new QueryContextRule();
53        $result = $rule->rewrite($input);
54        self::assertSame($insert ? ['AS', $first] : [$first], $result->names());
55        self::assertSame($input->original, $result->original);
56        self::assertSame($input->productions, $result->productions);
57        self::assertSame($query, $result->terminals[count($result->terminals) - 1]);
58        self::assertSame($result, $rule->rewrite($result));
59    }
60
61    /**
62     * @return list<array{string, bool}>
63     */
64    public static function providerSources(): array
65    {
66        return [['(', true], ['SELECT_SYM', true], ['AS', false]];
67    }
68}
69