github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/cmd/sql-main_test.go (about) 1 // Copyright (c) 2015-2022 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package cmd 19 20 import ( 21 "strings" 22 "testing" 23 ) 24 25 var testParseKVArgsCases = []struct { 26 inp string 27 kvmap map[string]string 28 errMsg string 29 }{ 30 {"fh=use,rd=|,fd=;,qec=\"", map[string]string{"fh": "use", "rd": "|", "fd": ";", "qec": "\""}, "<nil>"}, 31 {"", map[string]string{}, "<nil>"}, 32 {"not the right format", map[string]string{}, "Arguments should be of the form key=value,... "}, 33 {"k==v", map[string]string{"k": "=v"}, "<nil>"}, 34 {"k=v1,k=v2", map[string]string{}, "More than one key=value found for k"}, 35 {"k=v1;k=v2", map[string]string{"k": "v1;k=v2"}, "<nil>"}, 36 } 37 38 func TestParseKVArgs(t *testing.T) { 39 for _, test := range testParseKVArgsCases { 40 kvmap, err := parseKVArgs(test.inp) 41 gerr := err.ToGoError() 42 if gerr != nil && gerr.Error() != test.errMsg { 43 t.Fatalf("Unexpected result for \"%s\", expected: |%s| got: |%s|\n", test.inp, test.errMsg, gerr) 44 } 45 if gerr == nil && test.errMsg != "<nil>" { 46 t.Fatalf("Unexpected result for \"%s\", expected: |%s| got: |%s|\n", test.inp, test.errMsg, gerr) 47 } 48 for k, v := range test.kvmap { 49 actual, ok := kvmap[k] 50 if !ok { 51 t.Fatalf("Unexpected result for \"%s,\" expected %s , found %s for key %s\n", test.inp, v, actual, k) 52 } 53 } 54 } 55 } 56 57 var testParseSerializationCases = []struct { 58 inp string 59 validKeys []string 60 validAbbrKeys map[string]string 61 parsedOpts map[string]string 62 errMsg string 63 }{ 64 { 65 "rd=\n,fd=;,qc=\"", 66 append(validCSVCommonKeys, validCSVInputKeys...), 67 validCSVInputAbbrKeys, 68 map[string]string{"recorddelimiter": "\n", "fielddelimiter": ";", "quotechar": "\""}, 69 "<nil>", 70 }, 71 { 72 "rd=\n,fd=;,qc=\"", 73 validCSVInputKeys, 74 validCSVInputAbbrKeys, 75 map[string]string{}, 76 "Options should be key-value pairs in the form key=value,... where valid key(s) are ", 77 }, 78 { 79 "nokey=\n,fd=;,qc=\"", 80 validCSVInputKeys, 81 validCSVInputAbbrKeys, 82 map[string]string{}, 83 "Options should be key-value pairs in the form key=value,... where valid key(s) are ", 84 }, 85 { 86 "rd=\n\n,fd=|,qc=\",qc='", 87 validCSVInputKeys, 88 validCSVInputAbbrKeys, 89 map[string]string{}, 90 "More than one key=value found for ", 91 }, 92 { 93 "recordDelimiter=\n\n,FieldDelimiter=|,QuoteChAR=\"", 94 append(validCSVCommonKeys, validCSVInputKeys...), 95 validCSVInputAbbrKeys, 96 map[string]string{"recorddelimiter": "\n\n", "fielddelimiter": "|", "quotechar": "\""}, 97 "<nil>", 98 }, 99 { 100 "recordDelimiter=\n\n,FieldDelimiter=|,QuoteChAR=\",fh=use,qrd=;", 101 append(validCSVCommonKeys, validCSVInputKeys...), 102 validCSVInputAbbrKeys, 103 map[string]string{"recorddelimiter": "\n\n", "fielddelimiter": "|", "quotechar": "\"", "quotedrecorddelimiter": ";", "fileheader": "use"}, 104 "<nil>", 105 }, 106 { 107 "recordDelimiter=\n\n,FieldDelimiter=|,QuoteChar=\",qf=;,qec='", 108 append(validCSVCommonKeys, validCSVOutputKeys...), 109 validCSVOutputAbbrKeys, 110 map[string]string{}, 111 "Options should be key-value pairs in the form key=value,... where valid key(s) are ", 112 }, 113 { 114 "FieldDelimiter=|,QuoteChar=\",qf=;,qec='", 115 append(validCSVCommonKeys, validCSVOutputKeys...), 116 validCSVOutputAbbrKeys, 117 map[string]string{"fielddelimiter": "|", "quotechar": "\"", "quotefields": ";", "quoteescchar": "'"}, 118 "<nil>", 119 }, 120 { 121 "type=lines", 122 validJSONInputKeys, 123 nil, 124 map[string]string{"type": "lines"}, 125 "<nil>", 126 }, 127 } 128 129 func TestParseSerializationOpts(t *testing.T) { 130 for i, test := range testParseSerializationCases { 131 optsMap, err := parseSerializationOpts(test.inp, test.validKeys, test.validAbbrKeys) 132 gerr := err.ToGoError() 133 if gerr != nil && gerr.Error() != test.errMsg { 134 // match partial error message 135 if !strings.Contains(gerr.Error(), test.errMsg) { 136 t.Fatalf("Test %d: Unexpected result for \"%s\", expected: |%s| got: |%s|\n", i+1, test.inp, test.errMsg, gerr) 137 } 138 } 139 if gerr == nil && test.errMsg != "<nil>" { 140 t.Fatalf("Test %d: Unexpected result for \"%s\", expected: |%s| got: |%s|\n", i+1, test.inp, test.errMsg, gerr) 141 } 142 for k, v := range test.parsedOpts { 143 actual, ok := optsMap[strings.ToLower(k)] 144 if !ok { 145 t.Fatalf("Test %d:Unexpected result for \"%s,\" expected %s , found %s for key %s\n", i+1, test.inp, v, actual, k) 146 } 147 } 148 } 149 }