packages/ztd-query-postgres/tests/Unit/Sql/PgSqlIdentifierQuoterTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Sql;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use ZtdQuery\Platform\Postgres\Sql\PgSqlIdentifierQuoter;
9
10#[CoversClass(PgSqlIdentifierQuoter::class)]
11final class PgSqlIdentifierQuoterTest extends \PHPUnit\Framework\TestCase
12{
13 public function testQuoteReturnsNonEmptyString(): void
14 {
15 $quoter = new PgSqlIdentifierQuoter();
16 $result = $quoter->quote('users');
17 self::assertNotEmpty($result);
18 }
19
20 public function testQuoteWrapsIdentifier(): void
21 {
22 $quoter = new PgSqlIdentifierQuoter();
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 PgSqlIdentifierQuoter();
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 PgSqlIdentifierQuoter();
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 PgSqlIdentifierQuoter();
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 PgSqlIdentifierQuoter();
62 self::assertSame($quoter->quote('test_table'), $quoter->quote('test_table'));
63 }
64
65 public function testQuotedIdentifierContainsOriginalName(): void
66 {
67 $quoter = new PgSqlIdentifierQuoter();
68 $identifier = 'column_name';
69 $result = $quoter->quote($identifier);
70 self::assertStringContainsString($identifier, $result);
71 }
72 public function testQuoteSimpleIdentifier(): void
73 {
74 $quoter = new PgSqlIdentifierQuoter();
75 self::assertSame('"users"', $quoter->quote('users'));
76 }
77 public function testQuoteIdentifierWithUnderscore(): void
78 {
79 $quoter = new PgSqlIdentifierQuoter();
80 self::assertSame('"user_name"', $quoter->quote('user_name'));
81 }
82 public function testQuoteEscapesEmbeddedDoubleQuotes(): void
83 {
84 $quoter = new PgSqlIdentifierQuoter();
85 self::assertSame('"""users"""', $quoter->quote('"users"'));
86 }
87 public function testQuoteReturnsNonEmpty(): void
88 {
89 $quoter = new PgSqlIdentifierQuoter();
90 self::assertNotEmpty($quoter->quote('x'));
91 }
92 public function testQuoteStartsAndEndsWithDoubleQuote(): void
93 {
94 $quoter = new PgSqlIdentifierQuoter();
95 $result = $quoter->quote('table_name');
96 self::assertStringStartsWith('"', $result);
97 self::assertStringEndsWith('"', $result);
98 }
99 public function testQuoteReservedWord(): void
100 {
101 $quoter = new PgSqlIdentifierQuoter();
102 self::assertSame('"select"', $quoter->quote('select'));
103 }
104 public function testQuoteWithSpaces(): void
105 {
106 $quoter = new PgSqlIdentifierQuoter();
107 $result = $quoter->quote('my table');
108 self::assertSame('"my table"', $result);
109 }
110 public function testQuoteEmptyString(): void
111 {
112 $quoter = new PgSqlIdentifierQuoter();
113 $result = $quoter->quote('');
114 self::assertSame('""', $result);
115 }
116 public function testQuoteWithNumbers(): void
117 {
118 $quoter = new PgSqlIdentifierQuoter();
119 self::assertSame('"123"', $quoter->quote('123'));
120 }
121}
122