packages/ztd-query-sqlite/tests/Unit/Sql/Transaction/TransactionTokensTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Sql\Transaction;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use ZtdQuery\Platform\Sqlite\Sql\SqliteLexerProfile;
11use ZtdQuery\Platform\Sqlite\Sql\Transaction\TransactionTokens;
12use ZtdQuery\Sql\SqlTokenStream;
13
14#[CoversClass(TransactionTokens::class)]
15#[UsesClass(SqliteLexerProfile::class)]
16final class TransactionTokensTest extends TestCase
17{
18    public function testMatchesAnySelectsOneCompleteForm(): void
19    {
20        $tokens = SqlTokenStream::tokenize('BEGIN IMMEDIATE', SqliteLexerProfile::create())->significantTokens();
21        self::assertTrue((new TransactionTokens())->matchesAny($tokens, [['BEGIN'], ['BEGIN', 'IMMEDIATE']]));
22        self::assertFalse((new TransactionTokens())->matchesAny($tokens, [['BEGIN']]));
23    }
24
25    public function testMatchesRequiresEveryKeywordAndToken(): void
26    {
27        $matcher = new TransactionTokens();
28        $tokens = SqlTokenStream::tokenize('begin immediate', SqliteLexerProfile::create())->significantTokens();
29        self::assertTrue($matcher->matches($tokens, ['BEGIN', 'IMMEDIATE']));
30        self::assertFalse($matcher->matches($tokens, ['BEGIN', 'EXCLUSIVE']));
31        self::assertFalse($matcher->matches($tokens, ['BEGIN']));
32    }
33
34    public function testNameAfterDecodesOnlyACompleteSavepointForm(): void
35    {
36        $matcher = new TransactionTokens();
37        self::assertSame('point "one', $matcher->nameAfter(SqlTokenStream::tokenize('SAVEPOINT "point ""one"', SqliteLexerProfile::create())->significantTokens(), [['SAVEPOINT']]));
38        self::assertNull($matcher->nameAfter(SqlTokenStream::tokenize('SAVEPOINT 1', SqliteLexerProfile::create())->significantTokens(), [['SAVEPOINT']]));
39        self::assertNull($matcher->nameAfter(SqlTokenStream::tokenize('SAVEPOINT a extra', SqliteLexerProfile::create())->significantTokens(), [['SAVEPOINT']]));
40    }
41
42    public function testUnquotePreservesPlainNamesAndRejectsUnclosedQuotes(): void
43    {
44        $matcher = new TransactionTokens();
45        self::assertSame('point', $matcher->unquote('point'));
46        self::assertSame('a`b', $matcher->unquote('`a``b`'));
47        self::assertNull($matcher->unquote('"point'));
48        self::assertSame('', $matcher->unquote(''));
49    }
50
51}
52