packages/ztd-query-mysql/tests/Unit/Sql/Relation/ReferenceReaderTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Sql\Relation;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use ZtdQuery\Platform\MySql\Sql\Relation\ReferenceReader;
10
11#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\MySqlLexerProfile::class)]
12#[CoversClass(ReferenceReader::class)]
13final class ReferenceReaderTest extends TestCase
14{
15    public function testReferencesFromClause(): void
16    {
17        self::assertSame([['name' => 'users', 'start' => 0, 'unqualifiedStart' => 3, 'end' => 8], ['name' => 'posts', 'start' => 16, 'unqualifiedStart' => 16, 'end' => 21]], (new ReferenceReader())->referencesFromClause('db.users u JOIN posts p ON p.uid = u.id'));
18    }
19
20    public function testClosingToken(): void
21    {
22        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize('(users)', \ZtdQuery\Platform\MySql\Sql\MySqlLexerProfile::create())->significantTokens();
23        $reader = new ReferenceReader();
24        self::assertSame($tokens[2], $reader->closingToken($tokens, 0));
25        self::assertNull($reader->closingToken([$tokens[0]], 0));
26    }
27
28    public function testReferenceAt(): void
29    {
30        $sql = '`db`.`users`';
31        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\MySql\Sql\MySqlLexerProfile::create())->significantTokens();
32        self::assertSame(['name' => 'users', 'start' => 0, 'unqualifiedStart' => 5, 'end' => 12], (new ReferenceReader())->referenceAt($sql, $tokens, 0));
33        self::assertNull((new ReferenceReader())->referenceAt('SELECT', \ZtdQuery\Sql\SqlTokenStream::tokenize('SELECT', \ZtdQuery\Platform\MySql\Sql\MySqlLexerProfile::create())->significantTokens(), 0));
34    }
35
36    public function testIdentifierComponentAt(): void
37    {
38        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize('`a``b` +', \ZtdQuery\Platform\MySql\Sql\MySqlLexerProfile::create())->significantTokens();
39        $reader = new ReferenceReader();
40        self::assertSame(['a`b', 1, 0, 0, 6], $reader->identifierComponentAt($tokens, 0));
41        self::assertNull($reader->identifierComponentAt($tokens, 1));
42        self::assertNull($reader->identifierComponentAt($tokens, 2));
43    }
44
45    public function testFindFromEnd(): void
46    {
47        $sql = 'SELECT * FROM users WHERE id = 1';
48        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\MySql\Sql\MySqlLexerProfile::create())->significantTokens();
49        self::assertSame(20, (new ReferenceReader())->findFromEnd($sql, $tokens, $tokens[2]));
50    }
51
52    public function testMatchesKeywordSequence(): void
53    {
54        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize('ORDER BY id', \ZtdQuery\Platform\MySql\Sql\MySqlLexerProfile::create())->significantTokens();
55        $reader = new ReferenceReader();
56        self::assertTrue($reader->matchesKeywordSequence($tokens, 0, ['ORDER', 'BY']));
57        self::assertFalse($reader->matchesKeywordSequence($tokens, 0, ['GROUP', 'BY']));
58        self::assertFalse($reader->matchesKeywordSequence($tokens, 2, ['ORDER', 'BY']));
59    }
60
61    public function testParenthesizedReferences(): void
62    {
63        $sql = '(db.users)';
64        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\MySql\Sql\MySqlLexerProfile::create())->significantTokens();
65        self::assertSame([['name' => 'users', 'start' => 1, 'unqualifiedStart' => 4, 'end' => 9]], (new ReferenceReader())->parenthesizedReferences($sql, $tokens, 0));
66        $sql = '(SELECT * FROM users)';
67        self::assertSame([], (new ReferenceReader())->parenthesizedReferences($sql, \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\MySql\Sql\MySqlLexerProfile::create())->significantTokens(), 0));
68    }
69
70}
71