1
+ package com .clickhouse .client .api .sql ;
2
+
3
+ import org .apache .commons .lang3 .StringUtils ;
4
+ import org .testng .annotations .DataProvider ;
5
+ import org .testng .annotations .Test ;
6
+
7
+ import static org .testng .Assert .assertEquals ;
8
+
9
+ @ Test (groups = {"unit" })
10
+ public class SQLUtilsTest {
11
+ // Test data for enquoteLiteral
12
+ @ DataProvider (name = "enquoteLiteralTestData" )
13
+ public Object [][] enquoteLiteralTestData () {
14
+ return new Object [][] {
15
+ // input, expected output
16
+ {"test 123" , "'test 123'" },
17
+ {"こんにちは世界" , "'こんにちは世界'" },
18
+ {"O'Reilly" , "'O''Reilly'" },
19
+ {"😊👍" , "'😊👍'" },
20
+ {"" , "''" },
21
+ {"single'quote'double''quote\" " , "'single''quote''double''''quote\" '" }
22
+ };
23
+ }
24
+
25
+ // Test data for enquoteIdentifier
26
+ @ DataProvider (name = "enquoteIdentifierTestData" )
27
+ public Object [][] enquoteIdentifierTestData () {
28
+ return new Object [][] {
29
+ // input, expected output
30
+ {"column1" , "\" column1\" " },
31
+ {"table.name" , "\" table.name\" " },
32
+ {"column with spaces" , "\" column with spaces\" " },
33
+ {"column\" with\" quotes" , "\" column\" \" with\" \" quotes\" " },
34
+ {"UPPERCASE" , "\" UPPERCASE\" " },
35
+ {"1column" , "\" 1column\" " },
36
+ {"column-with-hyphen" , "\" column-with-hyphen\" " },
37
+ {"😊👍" , "\" 😊👍\" " },
38
+ {"" , "\" \" " }
39
+ };
40
+ }
41
+
42
+ @ Test (dataProvider = "enquoteLiteralTestData" )
43
+ public void testEnquoteLiteral (String input , String expected ) {
44
+ assertEquals (SQLUtils .enquoteLiteral (input ), expected );
45
+ }
46
+
47
+ @ Test (expectedExceptions = IllegalArgumentException .class )
48
+ public void testEnquoteLiteral_NullInput () {
49
+ SQLUtils .enquoteLiteral (null );
50
+ }
51
+
52
+ @ Test (dataProvider = "enquoteIdentifierTestData" )
53
+ public void testEnquoteIdentifier (String input , String expected ) {
54
+ // Test with quotesRequired = true (always quote)
55
+ assertEquals (SQLUtils .enquoteIdentifier (input ), expected );
56
+ assertEquals (SQLUtils .enquoteIdentifier (input , true ), expected );
57
+
58
+ // Test with quotesRequired = false (quote only if needed)
59
+ boolean needsQuoting = !input .matches ("[a-zA-Z_][a-zA-Z0-9_]*" );
60
+ String expectedUnquoted = needsQuoting ? expected : input ;
61
+ assertEquals (SQLUtils .enquoteIdentifier (input , false ), expectedUnquoted );
62
+ }
63
+
64
+ @ Test (expectedExceptions = IllegalArgumentException .class )
65
+ public void testEnquoteIdentifier_NullInput () {
66
+ SQLUtils .enquoteIdentifier (null );
67
+ }
68
+
69
+ @ Test (expectedExceptions = IllegalArgumentException .class )
70
+ public void testEnquoteIdentifier_NullInput_WithQuotesRequired () {
71
+ SQLUtils .enquoteIdentifier (null , true );
72
+ }
73
+
74
+ @ Test
75
+ public void testEnquoteIdentifier_NoQuotesWhenNotNeeded () {
76
+ // These identifiers don't need quoting
77
+ String [] simpleIdentifiers = {
78
+ "column1" , "table_name" , "_id" , "a1b2c3" , "ColumnName"
79
+ };
80
+
81
+ for (String id : simpleIdentifiers ) {
82
+ // With quotesRequired=false, should return as-is
83
+ assertEquals (SQLUtils .enquoteIdentifier (id , false ), id );
84
+ // With quotesRequired=true, should be quoted
85
+ assertEquals (SQLUtils .enquoteIdentifier (id , true ), "\" " + id + "\" " );
86
+ }
87
+ }
88
+
89
+ @ DataProvider (name = "simpleIdentifierTestData" )
90
+ public Object [][] simpleIdentifierTestData () {
91
+ return new Object [][] {
92
+ // identifier, expected result
93
+ {"Hello" , true },
94
+ {"hello_world" , true },
95
+ {"Hello123" , true },
96
+ {"H" , true }, // minimum length
97
+ {StringUtils .repeat ("a" , 128 ), true }, // maximum length
98
+
99
+ // Test cases from requirements
100
+ {"G'Day" , false },
101
+ {"\" \" Bruce Wayne\" \" " , false },
102
+ {"GoodDay$" , false },
103
+ {"Hello\" \" World" , false },
104
+ {"\" \" Hello\" \" World\" \" " , false },
105
+
106
+ // Additional test cases
107
+ {"" , false }, // empty string
108
+ {"123test" , false }, // starts with number
109
+ {"_test" , false }, // starts with underscore
110
+ {"test-name" , false }, // contains hyphen
111
+ {"test name" , false }, // contains space
112
+ {"test\" name" , false }, // contains quote
113
+ {"test.name" , false }, // contains dot
114
+ {StringUtils .repeat ("a" , 129 ), false }, // exceeds max length
115
+ {"testName" , true },
116
+ {"TEST_NAME" , true },
117
+ {"test123" , true },
118
+ {"t123" , true },
119
+ {"t" , true }
120
+ };
121
+ }
122
+
123
+ @ Test (dataProvider = "simpleIdentifierTestData" )
124
+ public void testIsSimpleIdentifier (String identifier , boolean expected ) {
125
+ assertEquals (SQLUtils .isSimpleIdentifier (identifier ), expected ,
126
+ String .format ("Failed for identifier: %s" , identifier ));
127
+ }
128
+
129
+ @ Test (expectedExceptions = IllegalArgumentException .class )
130
+ public void testIsSimpleIdentifier_NullInput () {
131
+ SQLUtils .isSimpleIdentifier (null );
132
+ }
133
+
134
+ @ Test
135
+ public void testUnquoteIdentifier () {
136
+ String [] names = new String []{"test" , "`test name1`" , "\" test name 2\" " };
137
+ String [] expected = new String []{"test" , "test name1" , "test name 2" };
138
+
139
+ for (int i = 0 ; i < names .length ; i ++) {
140
+ assertEquals (SQLUtils .unquoteIdentifier (names [i ]), expected [i ]);
141
+ }
142
+ }
143
+ }
0 commit comments