@@ -141,39 +141,111 @@ func TestHandleTableNameDefaults_TableNamePresent(t *testing.T) {
141141 assert .Equal (t , "explicit_table" , result )
142142}
143143
144- func TestHandleTableNameDefaults_TableNameEmptyFileScheme (t * testing.T ) {
145- tableName := ""
146- sourceUri := "file:///path/to/my_data.csv"
147- result := handleTableNameDefaults (tableName , sourceUri )
148- assert .Equal (t , "my_data" , result )
149- }
150-
151- func TestHandleTableNameDefaults_TableNameEmptyGCScheme (t * testing.T ) {
152- tableName := ""
153- sourceUri := "gs://my-bucket/data_file.txt"
154- result := handleTableNameDefaults (tableName , sourceUri )
155- assert .Equal (t , "data_file" , result )
156- }
157-
158- func TestHandleTableNameDefaults_TableNameEmptyLocalPathNoScheme (t * testing.T ) {
159- tableName := ""
160- sourceUri := "/tmp/another_file.json"
161- result := handleTableNameDefaults (tableName , sourceUri )
162- assert .Equal (t , "another_file" , result )
144+ func TestHandleTableNameDefaults (t * testing.T ) {
145+ tests := []struct {
146+ name string
147+ sourceUri string
148+ expected string
149+ }{
150+ {
151+ name : "URIWithTrailingSlash" ,
152+ sourceUri : "gs://my-bucket/folder/" ,
153+ expected : "folder" ,
154+ },
155+ {
156+ name : "RelativePath" ,
157+ sourceUri : "relative/path/some_data.avro" ,
158+ expected : "some_data" ,
159+ },
160+ {
161+ name : "LocalPathNoScheme" ,
162+ sourceUri : "/tmp/another_file.json" ,
163+ expected : "another_file" ,
164+ },
165+ {
166+ name : "GCScheme" ,
167+ sourceUri : "s://my-bucket/data_file.txt" ,
168+ expected : "data_file" ,
169+ },
170+ {
171+ name : "FileScheme" ,
172+ sourceUri : "file:///path/to/my_data.csv" ,
173+ expected : "my_data" ,
174+ },
175+ }
176+ for _ , tc := range tests {
177+ t .Run (tc .name , func (t * testing.T ) {
178+ result := handleTableNameDefaults ("" , tc .sourceUri )
179+ assert .Equal (t , tc .expected , result )
180+ })
181+ }
163182}
164183
165- func TestHandleTableNameDefaults_TableNameEmptyRelativePath (t * testing.T ) {
166- tableName := ""
167- sourceUri := "relative/path/some_data.avro"
168- result := handleTableNameDefaults (tableName , sourceUri )
169- assert .Equal (t , "some_data" , result )
170- }
184+ func TestSanitizeTableName (t * testing.T ) {
185+ tests := []struct {
186+ input string
187+ expected string
188+ }{
189+ // --- Basic Valid Cases ---
190+ {"myTableName" , "mytablename" },
191+ {"another_table" , "another_table" },
192+ {"table123" , "table123" },
193+ {"_leading_underscore" , "_leading_underscore" },
194+ {"has_numbers_123" , "has_numbers_123" },
195+ {"ALLCAPS" , "allcaps" },
196+
197+ // --- Leading Character Trimming (underscoreOrAlphabet) ---
198+ {"_ABC" , "_abc" },
199+ {"-table" , "table" },
200+ {"#table" , "table" },
201+ {"1table" , "table" },
202+ {"-1table" , "table" },
203+ {" leading_spaces" , "leading_spaces" },
204+ {"_leading_underscores_and_spaces" , "_leading_underscores_and_spaces" },
205+ {"__leading_double_underscore" , "__leading_double_underscore" },
206+
207+ // --- Invalid Characters Removal (underscoreOrAlphanumeric) ---
208+ {"table name" , "tablename" },
209+ {"table.name" , "tablename" },
210+ {"table-name" , "tablename" },
211+ {"table!@#$%^&*()" , "table" },
212+ {"table_name_with_spaces and stuff" , "table_name_with_spacesandstuff" },
213+ {"mixed_Case_AND_SYMBOLS!@" , "mixed_case_and_symbols" },
214+ {"__Table__Name__" , "__table__name__" },
215+ {"Table Name With Space And Special Chars!@#$" , "tablenamewithspaceandspecialchars" },
216+
217+ // --- Empty/Edge Cases ---
218+ {"" , "" },
219+ {" " , "" },
220+ {"!!!" , "" },
221+ {"_!@#" , "_" },
222+ {"_123" , "_123" },
223+ {"__" , "__" },
224+ {"A" , "a" },
225+ {"1" , "" },
226+ {"-" , "" },
227+ {"-1" , "" },
228+ {"-a" , "a" },
229+
230+ // --- Unicode Characters ---
231+ {"tābļē_ňāmē" , "tābļē_ňāmē" },
232+ {"table_名稱" , "table_名稱" },
233+ {"table_привет" , "table_привет" },
234+ {"😊table😁name" , "tablename" },
235+ {"table_日本語_123" , "table_日本語_123" },
236+ {"你好_world" , "你好_world" },
237+ {"_hello_世界_123" , "_hello_世界_123" },
238+ {"table_!@#_name" , "table__name" },
239+ }
171240
172- func TestHandleTableNameDefaults_TableNameEmptyURIWithTrailingSlash (t * testing.T ) {
173- tableName := ""
174- sourceUri := "gs://my-bucket/folder/"
175- result := handleTableNameDefaults (tableName , sourceUri )
176- assert .Equal (t , "folder" , result )
241+ for _ , tt := range tests {
242+ t .Run (tt .input , func (t * testing.T ) { // Use t.Run for better test output for each case
243+ got := sanitizeTableName (tt .input )
244+ if got != tt .expected {
245+ t .Errorf ("sanitizeTableName(%q) = %q; want %q" , tt .input , got , tt .expected )
246+ }
247+ })
248+ }
177249}
178250
179251func TestImportDataCmd_HandleCsvExecute (t * testing.T ) {
@@ -680,7 +752,7 @@ func TestHandleCsv(t *testing.T) {
680752 assert .Equal (t , "test-project" , projectId )
681753 assert .Equal (t , "test-instance" , instanceId )
682754 assert .Equal (t , "test-db" , dbName )
683- assert .Equal (t , "test-table " , tableName )
755+ assert .Equal (t , "testtable " , tableName )
684756 assert .Equal (t , "gs://test-bucket/test_schema.json" , schemaUri )
685757
686758 return & import_file.MockCsvSchema {}
@@ -689,7 +761,7 @@ func TestHandleCsv(t *testing.T) {
689761 assert .Equal (t , "test-project" , projectId )
690762 assert .Equal (t , "test-instance" , instanceId )
691763 assert .Equal (t , "test-db" , dbName )
692- assert .Equal (t , "test-table " , tableName )
764+ assert .Equal (t , "testtable " , tableName )
693765 assert .Equal (t , "," , csvFieldDelimiter )
694766 return & import_file.MockCsvData {}
695767 },
0 commit comments