packages/ztd-query-sqlite/tests/Unit/Sql/SqliteLexicalMaskerTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Sql;
6
7use Generator;
8use PHPUnit\Framework\Attributes\CoversClass;
9use PHPUnit\Framework\Attributes\DataProvider;
10use PHPUnit\Framework\Attributes\UsesClass;
11use PHPUnit\Framework\TestCase;
12use ZtdQuery\Platform\Sqlite\Sql\SqliteLexicalMasker;
13
14#[CoversClass(SqliteLexicalMasker::class)]
15#[UsesClass(\ZtdQuery\Platform\Sqlite\Sql\Lexing\QuotedSpan::class)]
16final class SqliteLexicalMaskerTest extends TestCase
17{
18 #[DataProvider('providerComments')]
19 public function testMaskCommentsMasksCommentsAsSingleLexicalSeparators(string $sql, string $expected): void
20 {
21 self::assertSame($expected, SqliteLexicalMasker::maskComments($sql));
22 }
23
24 #[DataProvider('providerQuotedForms')]
25 public function testPreservesCommentMarkersInsideQuotedForms(string $quoted, bool $terminated): void
26 {
27 $sql = 'SELECT ' . $quoted . '/* outside */1';
28 $expected = $terminated ? 'SELECT ' . $quoted . ' 1' : $sql;
29
30 self::assertSame($expected, SqliteLexicalMasker::maskComments($sql));
31 }
32
33 /**
34 * @return Generator<string, array{string, string}>
35 */
36 public static function providerComments(): Generator
37 {
38 yield 'empty query' => ['', ''];
39 yield 'line comment' => ['SELECT-- comment', 'SELECT '];
40 yield 'line comment with newline' => ["SELECT-- comment\n1", "SELECT \n1"];
41 yield 'line comment with carriage return' => ["SELECT-- comment\r1", "SELECT \r1"];
42 yield 'empty line comment' => ["--\nSELECT", " \nSELECT"];
43 yield 'separated minus signs' => ['SELECT- -1', 'SELECT- -1'];
44 yield 'hash comment' => ['SELECT# comment', 'SELECT '];
45 yield 'empty hash comment' => ["#\nSELECT", " \nSELECT"];
46 yield 'block comment' => ['SELECT/* comment */1', 'SELECT 1'];
47 yield 'minimal block comment' => ['SELECT/**/1', 'SELECT 1'];
48 yield 'adjacent block comments' => ['SELECT/**//**/1', 'SELECT 1'];
49 yield 'unterminated block comment' => ['SELECT/* comment', 'SELECT '];
50 yield 'separated slash and asterisk' => ['SELECT/ *1', 'SELECT/ *1'];
51 yield 'comment-like closing marker' => ['SELECT*/1', 'SELECT*/1'];
52 yield 'comment closing boundary' => ['SELECT/**/*1', 'SELECT *1'];
53 yield 'overlapping unterminated block marker' => ['SELECT/*/1', 'SELECT '];
54 }
55
56 /**
57 * @return Generator<string, array{string, bool}>
58 */
59 public static function providerQuotedForms(): Generator
60 {
61 yield 'single quoted line marker' => ["'-- comment'", true];
62 yield 'single quoted block marker' => ["'/* comment */'", true];
63 yield 'empty single quote' => ["''", true];
64 yield 'doubled single quote' => ["'value''/* comment */'", true];
65 yield 'triple single quote closing run' => ["'value'''", true];
66 yield 'unterminated single quote' => ["'/* comment", false];
67 yield 'double quoted line marker' => ['"-- comment"', true];
68 yield 'double quoted block marker' => ['"/* comment */"', true];
69 yield 'empty double quote' => ['""', true];
70 yield 'doubled double quote' => ['"value""/* comment */"', true];
71 yield 'unterminated double quote' => ['"/* comment', false];
72 yield 'backtick quoted hash marker' => ['`# comment`', true];
73 yield 'empty backtick quote' => ['``', true];
74 yield 'doubled backtick' => ['`value``/* comment */`', true];
75 yield 'unterminated backtick' => ['`/* comment', false];
76 yield 'bracket quoted line marker' => ['[-- comment]', true];
77 yield 'bracket quoted block marker' => ['[/* comment */]', true];
78 yield 'empty bracket quote' => ['[]', true];
79 yield 'unterminated bracket' => ['[/* comment', false];
80 }
81}
82