packages/ztd-query-postgres/tests/Unit/Sql/Merge/BranchTokensTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Sql\Merge;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9
10#[CoversClass(\ZtdQuery\Platform\Postgres\Sql\Merge\BranchTokens::class)]
11#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::class)]
12final class BranchTokensTest extends TestCase
13{
14    public function testKeywordIndexAfter(): void
15    {
16        $sql = 'MERGE INTO users u USING incoming s ON u.id = s.id WHEN MATCHED AND s.active THEN UPDATE SET name = s.name WHEN NOT MATCHED THEN INSERT (id, name) VALUES (s.id, s.name)';
17        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
18
19        self::assertSame(4, (new \ZtdQuery\Platform\Postgres\Sql\Merge\BranchTokens())->keywordIndexAfter($tokens, 'USING', $tokens[0]));
20
21        $sql = 'MERGE INTO users u USING incoming s ON u.id = s.id WHEN MATCHED AND s.active THEN UPDATE SET name = s.name WHEN NOT MATCHED THEN INSERT (id, name) VALUES (s.id, s.name)';
22        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
23
24        self::assertSame(null, (new \ZtdQuery\Platform\Postgres\Sql\Merge\BranchTokens())->keywordIndexAfter($tokens, 'ABSENT', $tokens[0]));
25    }
26
27    public function testLastKeywordBetween(): void
28    {
29        $sql = 'MERGE INTO users u USING incoming s ON u.id = s.id WHEN MATCHED AND s.active THEN UPDATE SET name = s.name WHEN NOT MATCHED THEN INSERT (id, name) VALUES (s.id, s.name)';
30        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
31
32        self::assertEquals(new \ZtdQuery\Sql\SqlToken(kind: \ZtdQuery\Sql\SqlTokenKind::Word, text: 'ON', offset: 36, depth: 0, bracketDepth: 0), (new \ZtdQuery\Platform\Postgres\Sql\Merge\BranchTokens())->lastKeywordBetween($tokens, 'ON', $tokens[0], $tokens[count($tokens) - 1]));
33    }
34
35    public function testMergeWhenTokens(): void
36    {
37        $sql = 'MERGE INTO users u USING incoming s ON u.id = s.id WHEN MATCHED AND s.active THEN UPDATE SET name = s.name WHEN NOT MATCHED THEN INSERT (id, name) VALUES (s.id, s.name)';
38        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
39
40        self::assertEquals([new \ZtdQuery\Sql\SqlToken(kind: \ZtdQuery\Sql\SqlTokenKind::Word, text: 'WHEN', offset: 51, depth: 0, bracketDepth: 0), new \ZtdQuery\Sql\SqlToken(kind: \ZtdQuery\Sql\SqlTokenKind::Word, text: 'WHEN', offset: 107, depth: 0, bracketDepth: 0)], (new \ZtdQuery\Platform\Postgres\Sql\Merge\BranchTokens())->mergeWhenTokens($tokens));
41    }
42
43    public function testKeywordIndexOutsideCase(): void
44    {
45        $sql = 'WHEN MATCHED AND CASE WHEN x THEN 1 ELSE 0 END = 1 THEN DELETE';
46        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
47
48        self::assertSame(13, (new \ZtdQuery\Platform\Postgres\Sql\Merge\BranchTokens())->keywordIndexOutsideCase($tokens, 'THEN'));
49    }
50}
51