packages/ztd-query-sqlite/tests/Unit/Sql/SqliteIdentifierQuoterTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Sql;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use ZtdQuery\Platform\Sqlite\Sql\SqliteIdentifierQuoter;
9
10#[CoversClass(SqliteIdentifierQuoter::class)]
11final class SqliteIdentifierQuoterTest extends \PHPUnit\Framework\TestCase
12{
13    public function testQuoteReturnsNonEmptyString(): void
14    {
15        $quoter = new SqliteIdentifierQuoter();
16        $result = $quoter->quote('x');
17        self::assertNotEmpty($result);
18    }
19
20    public function testQuoteWrapsIdentifier(): void
21    {
22        $quoter = new SqliteIdentifierQuoter();
23        $char = '"';
24        $result = $quoter->quote('table_name');
25        self::assertStringStartsWith($char, $result);
26        self::assertStringEndsWith($char, $result);
27    }
28
29    public function testQuoteEscapesQuoteCharacterInIdentifier(): void
30    {
31        $quoter = new SqliteIdentifierQuoter();
32        $char = '"';
33        $identifier = 'col' . $char . 'name';
34        $result = $quoter->quote($identifier);
35        self::assertNotEmpty($result);
36        self::assertStringStartsWith($char, $result);
37        self::assertStringEndsWith($char, $result);
38        $simpleQuoted = $char . $identifier . $char;
39        self::assertGreaterThanOrEqual(strlen($simpleQuoted), strlen($result), 'Escaped identifier should be at least as long as non-escaped form');
40    }
41
42    public function testQuoteProducesExactResult(): void
43    {
44        $quoter = new SqliteIdentifierQuoter();
45        $char = '"';
46        $result = $quoter->quote('users');
47        self::assertSame($char . 'users' . $char, $result);
48    }
49
50    public function testQuoteEscapesEmbeddedQuoteExactly(): void
51    {
52        $quoter = new SqliteIdentifierQuoter();
53        $char = '"';
54        $result = $quoter->quote('col' . $char . 'name');
55        $expected = $char . 'col' . $char . $char . 'name' . $char;
56        self::assertSame($expected, $result);
57    }
58
59    public function testQuoteIsDeterministic(): void
60    {
61        $quoter = new SqliteIdentifierQuoter();
62        $result1 = $quoter->quote('my_table');
63        $result2 = $quoter->quote('my_table');
64        self::assertSame($result1, $result2);
65    }
66
67    public function testQuotedIdentifierContainsOriginalName(): void
68    {
69        $quoter = new SqliteIdentifierQuoter();
70        $identifier = 'column_name';
71        $result = $quoter->quote($identifier);
72        self::assertStringContainsString($identifier, $result);
73    }
74
75    public function testQuoteSimpleIdentifier(): void
76    {
77        $quoter = new SqliteIdentifierQuoter();
78        self::assertSame('"users"', $quoter->quote('users'));
79    }
80
81    public function testQuoteIdentifierWithSpaces(): void
82    {
83        $quoter = new SqliteIdentifierQuoter();
84        self::assertSame('"my table"', $quoter->quote('my table'));
85    }
86
87    public function testQuoteIdentifierWithDoubleQuotes(): void
88    {
89        $quoter = new SqliteIdentifierQuoter();
90        self::assertSame('"col""name"', $quoter->quote('col"name'));
91    }
92
93    public function testQuoteAlreadyQuotedIdentifier(): void
94    {
95        $quoter = new SqliteIdentifierQuoter();
96        self::assertSame('"users"', $quoter->quote('"users"'));
97    }
98
99    public function testQuoteAlreadyQuotedWithEscapedQuotes(): void
100    {
101        $quoter = new SqliteIdentifierQuoter();
102        self::assertSame('"col""name"', $quoter->quote('"col""name"'));
103    }
104
105    public function testQuoteStartsAndEndsWithDoubleQuote(): void
106    {
107        $quoter = new SqliteIdentifierQuoter();
108        $result = $quoter->quote('test_table');
109        self::assertStringStartsWith('"', $result);
110        self::assertStringEndsWith('"', $result);
111    }
112
113    public function testDeterminism(): void
114    {
115        $quoter = new SqliteIdentifierQuoter();
116        $result1 = $quoter->quote('users');
117        $result2 = $quoter->quote('users');
118        self::assertSame($result1, $result2);
119    }
120
121    public function testContainment(): void
122    {
123        $quoter = new SqliteIdentifierQuoter();
124        $original = 'my_table';
125        $result = $quoter->quote($original);
126        self::assertStringContainsString($original, $result);
127    }
128
129    public function testQuoteEmptyQuotedIdentifier(): void
130    {
131        $quoter = new SqliteIdentifierQuoter();
132        self::assertSame('""', $quoter->quote('""'));
133    }
134
135    public function testQuoteSingleCharIdentifier(): void
136    {
137        $quoter = new SqliteIdentifierQuoter();
138        self::assertSame('"x"', $quoter->quote('x'));
139    }
140
141    public function testQuoteSingleDoubleQuote(): void
142    {
143        $quoter = new SqliteIdentifierQuoter();
144        self::assertSame('""""', $quoter->quote('"'));
145    }
146}
147