packages/sql-parser/tests/Unit/MySql/Lexer/TriviaScannerTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\MySql\Lexer;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\Small;
9use PHPUnit\Framework\Attributes\UsesClass;
10use PHPUnit\Framework\TestCase;
11use SqlParser\Lexer\Cursor;
12use SqlParser\Lexer\LexicalException;
13use SqlParser\MySql\Lexer\KeywordTable;
14use SqlParser\MySql\Lexer\Scan;
15use SqlParser\MySql\Lexer\TriviaScanner;
16use SqlParser\MySql\MySqlVersion;
17use SqlParser\MySql\SqlMode;
18
19#[CoversClass(TriviaScanner::class)]
20#[UsesClass(Cursor::class)]
21#[UsesClass(LexicalException::class)]
22#[UsesClass(KeywordTable::class)]
23#[UsesClass(MySqlVersion::class)]
24#[UsesClass(Scan::class)]
25#[UsesClass(SqlMode::class)]
26#[UsesClass(\SqlParser\Lexer\SourcePosition::class)]
27#[UsesClass(\SqlParser\Resource\SqlVersion::class)]
28#[UsesClass(\SqlParser\Resource\VersionRegistry::class)]
29#[UsesClass(\SqlParser\Lexer\SourceException::class)]
30#[Small]
31final class TriviaScannerTest extends TestCase
32{
33    public function testSkipPassesWhitespaceAndComments(): void
34    {
35        $scan = new Scan(new Cursor("  # hash\n-- dash \n\t/* block */ --x"), new KeywordTable([], []), new SqlMode(), MySqlVersion::resolve());
36        (new TriviaScanner())->skip($scan);
37
38        self::assertSame('--x', $scan->cursor->take(3));
39    }
40
41    public function testSkipReadsAVersionCommentBodyAsSql(): void
42    {
43        $scan = new Scan(new Cursor('/*!80000 FORCE */ x'), new KeywordTable([], []), new SqlMode(), MySqlVersion::resolve('mysql-8.4.7'));
44        $trivia = new TriviaScanner();
45        $trivia->skip($scan);
46
47        self::assertSame('FORCE', $scan->cursor->take(5));
48        self::assertTrue($scan->inVersionComment);
49        $trivia->skip($scan);
50        self::assertSame('x', $scan->cursor->take(1));
51        self::assertFalse($scan->inVersionComment);
52    }
53
54    public function testSkipDropsAVersionCommentForANewerRelease(): void
55    {
56        $scan = new Scan(new Cursor('/*!90000 FORCE */ x'), new KeywordTable([], []), new SqlMode(), MySqlVersion::resolve('mysql-8.4.7'));
57        (new TriviaScanner())->skip($scan);
58
59        self::assertSame('x', $scan->cursor->take(1));
60        self::assertFalse($scan->inVersionComment);
61    }
62
63    public function testBlockComment(): void
64    {
65        $scan = new Scan(new Cursor('/*+ hint */x'), new KeywordTable([], []), new SqlMode(), MySqlVersion::resolve());
66        (new TriviaScanner())->blockComment($scan);
67
68        self::assertSame('x', $scan->cursor->take(1));
69    }
70
71    public function testBlockCommentRejectsAnUnterminatedComment(): void
72    {
73        $scan = new Scan(new Cursor('/* open'), new KeywordTable([], []), new SqlMode(), MySqlVersion::resolve());
74
75        $this->expectException(LexicalException::class);
76
77        (new TriviaScanner())->blockComment($scan);
78    }
79}
80