packages/ztd-query-core/tests/Unit/Sql/SqlKeywordSequenceTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Sql;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use Tests\Fake\FakeSqlLexerProfiles;
11use ZtdQuery\Sql\Profile\SqlCommentProfile;
12use ZtdQuery\Sql\Profile\SqlParameterProfile;
13use ZtdQuery\Sql\Profile\SqlQuoteProfile;
14use ZtdQuery\Sql\Profile\SqlSymbolProfile;
15use ZtdQuery\Sql\Reader\SqlBlockCommentReader;
16use ZtdQuery\Sql\Reader\SqlDelimitedReader;
17use ZtdQuery\Sql\Reader\SqlLexeme;
18use ZtdQuery\Sql\Reader\SqlParameterReader;
19use ZtdQuery\Sql\Reader\SqlTriviaReader;
20use ZtdQuery\Sql\Reader\SqlWordReader;
21use ZtdQuery\Sql\SqlKeywordSequence;
22use ZtdQuery\Sql\SqlLexerProfile;
23use ZtdQuery\Sql\SqlToken;
24use ZtdQuery\Sql\SqlTokenScanner;
25use ZtdQuery\Sql\SqlTokenStream;
26
27#[CoversClass(SqlKeywordSequence::class)]
28#[UsesClass(SqlToken::class)]
29#[UsesClass(SqlTokenStream::class)]
30#[UsesClass(SqlTokenScanner::class)]
31#[UsesClass(SqlLexerProfile::class)]
32#[UsesClass(\ZtdQuery\Sql\LexicalDelimiters::class)]
33#[UsesClass(\ZtdQuery\Sql\LexicalPattern::class)]
34#[UsesClass(SqlCommentProfile::class)]
35#[UsesClass(SqlParameterProfile::class)]
36#[UsesClass(SqlQuoteProfile::class)]
37#[UsesClass(SqlSymbolProfile::class)]
38#[UsesClass(SqlBlockCommentReader::class)]
39#[UsesClass(SqlDelimitedReader::class)]
40#[UsesClass(SqlLexeme::class)]
41#[UsesClass(SqlParameterReader::class)]
42#[UsesClass(SqlTriviaReader::class)]
43#[UsesClass(SqlWordReader::class)]
44final class SqlKeywordSequenceTest extends TestCase
45{
46 public function testPositionInAnswersWhereTheRunOfKeywordsBegins(): void
47 {
48 $tokens = SqlTokenStream::tokenize(
49 'SELECT a FROM t ORDER BY a',
50 FakeSqlLexerProfiles::standard(),
51 )->significantTokens();
52
53 self::assertSame(4, (new SqlKeywordSequence())->positionIn($tokens, ['ORDER', 'BY'], 0));
54 }
55
56 public function testPositionInIgnoresTheSameWordsWrittenInsideParentheses(): void
57 {
58 $tokens = SqlTokenStream::tokenize(
59 'SELECT (SELECT a FROM t ORDER BY a) FROM u',
60 FakeSqlLexerProfiles::standard(),
61 )->significantTokens();
62
63 self::assertNull((new SqlKeywordSequence())->positionIn($tokens, ['ORDER', 'BY'], 0));
64 }
65
66 public function testPositionInIsNothingWhereTheRunIsNotWrittenAtAll(): void
67 {
68 $tokens = SqlTokenStream::tokenize('SELECT a FROM t', FakeSqlLexerProfiles::standard())
69 ->significantTokens();
70
71 self::assertNull((new SqlKeywordSequence())->positionIn($tokens, ['GROUP', 'BY'], 0));
72 }
73
74 public function testPositionInLooksNoEarlierThanItWasToldTo(): void
75 {
76 $tokens = SqlTokenStream::tokenize(
77 'SELECT a FROM t WHERE a = 1',
78 FakeSqlLexerProfiles::standard(),
79 )->significantTokens();
80
81 self::assertNull((new SqlKeywordSequence())->positionIn($tokens, ['SELECT'], 1));
82 }
83
84 public function testPositionInIsNothingWhereOnlyPartOfTheRunIsWritten(): void
85 {
86 $tokens = SqlTokenStream::tokenize('SELECT a FROM t ORDER', FakeSqlLexerProfiles::standard())
87 ->significantTokens();
88
89 self::assertNull((new SqlKeywordSequence())->positionIn($tokens, ['ORDER', 'BY'], 0));
90 }
91}
92