packages/ztd-query-core/tests/Unit/Sql/Reader/SqlTriviaReaderTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Sql\Reader;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use Tests\Fake\FakeSqlLexerProfiles;
11use ZtdQuery\Sql\LexicalDelimiters;
12use ZtdQuery\Sql\LexicalPattern;
13use ZtdQuery\Sql\Profile\SqlCommentProfile;
14use ZtdQuery\Sql\Profile\SqlParameterProfile;
15use ZtdQuery\Sql\Profile\SqlQuoteProfile;
16use ZtdQuery\Sql\Profile\SqlSymbolProfile;
17use ZtdQuery\Sql\Reader\SqlBlockCommentReader;
18use ZtdQuery\Sql\Reader\SqlLexeme;
19use ZtdQuery\Sql\Reader\SqlTriviaReader;
20use ZtdQuery\Sql\SqlLexerProfile;
21use ZtdQuery\Sql\SqlTokenKind;
22
23#[CoversClass(SqlTriviaReader::class)]
24#[UsesClass(SqlBlockCommentReader::class)]
25#[UsesClass(SqlLexeme::class)]
26#[UsesClass(SqlLexerProfile::class)]
27#[UsesClass(LexicalDelimiters::class)]
28#[UsesClass(LexicalPattern::class)]
29#[UsesClass(SqlCommentProfile::class)]
30#[UsesClass(SqlParameterProfile::class)]
31#[UsesClass(SqlQuoteProfile::class)]
32#[UsesClass(SqlSymbolProfile::class)]
33final class SqlTriviaReaderTest extends TestCase
34{
35    public function testReadAtAnswersNothingWhereSomethingMeaningfulBegins(): void
36    {
37        self::assertNull((new SqlTriviaReader())->readAt('SELECT', 0, FakeSqlLexerProfiles::standard()));
38    }
39
40    public function testReadAtReadsAWholeRunOfWhitespaceAsOneLexeme(): void
41    {
42        $lexeme = (new SqlTriviaReader())->readAt("  \n\tx", 0, FakeSqlLexerProfiles::standard());
43
44        self::assertSame([SqlTokenKind::Whitespace, 4], [$lexeme?->kind, $lexeme?->end]);
45    }
46
47    public function testReadAtLeavesTheNewlineThatEndsALineCommentToBeReadAsWhitespace(): void
48    {
49        $lexeme = (new SqlTriviaReader())->readAt("-- a\nx", 0, FakeSqlLexerProfiles::standard());
50
51        self::assertSame([SqlTokenKind::Comment, 4], [$lexeme?->kind, $lexeme?->end]);
52    }
53
54    public function testReadAtReadsALineCommentToTheEndOfAStatementThatNeverBreaksTheLine(): void
55    {
56        $lexeme = (new SqlTriviaReader())->readAt('-- a', 0, FakeSqlLexerProfiles::standard());
57
58        self::assertSame([SqlTokenKind::Comment, 4], [$lexeme?->kind, $lexeme?->end]);
59    }
60
61    public function testReadAtReadsAWholeBlockCommentAsOneLexeme(): void
62    {
63        $lexeme = (new SqlTriviaReader())->readAt('/* a */x', 0, FakeSqlLexerProfiles::standard());
64
65        self::assertSame([SqlTokenKind::Comment, 7], [$lexeme?->kind, $lexeme?->end]);
66    }
67}
68