packages/ztd-query-sqlite/tests/Unit/Sql/Lexing/TopLevelKeywordScannerTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Sql\Lexing;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use ZtdQuery\Platform\Sqlite\Sql\Lexing\TopLevelKeywordScanner;
11
12#[CoversClass(TopLevelKeywordScanner::class)]
13#[UsesClass(\ZtdQuery\Platform\Sqlite\Sql\Lexing\OpaqueSqlSpan::class)]
14#[UsesClass(\ZtdQuery\Platform\Sqlite\Sql\Lexing\QuotedSpan::class)]
15final class TopLevelKeywordScannerTest extends TestCase
16{
17    public function testScanTopLevelKeywordsPreservesOffsetsAndGroupState(): void
18    {
19        self::assertSame([
20            ['keyword' => 'WITH', 'afterGroup' => false, 'offset' => 0],
21            ['keyword' => 'T', 'afterGroup' => false, 'offset' => 5],
22            ['keyword' => 'AS', 'afterGroup' => false, 'offset' => 7],
23            ['keyword' => 'SELECT', 'afterGroup' => true, 'offset' => 21],
24            ['keyword' => 'FROM', 'afterGroup' => true, 'offset' => 30],
25            ['keyword' => 'T', 'afterGroup' => true, 'offset' => 35],
26        ], (new TopLevelKeywordScanner())->scanTopLevelKeywords('WITH t AS (SELECT 1) SELECT * FROM t'));
27    }
28
29    public function testScanTopLevelKeywordsSkipsQuotedAndCommentedKeywords(): void
30    {
31        self::assertSame([], (new TopLevelKeywordScanner())->scanTopLevelKeywords("'SELECT' /* DELETE */ \"UPDATE\" [INSERT] `DROP` -- ALTER"));
32        self::assertSame([['keyword' => 'SELECT', 'afterGroup' => false, 'offset' => 2]], (new TopLevelKeywordScanner())->scanTopLevelKeywords(') SELECT 123'));
33    }
34
35}
36