istio.io/istio@v0.0.0-20240520182934-d79c90f27776/operator/pkg/util/path_test.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package util 16 17 import ( 18 "errors" 19 "testing" 20 ) 21 22 func TestSplitEscaped(t *testing.T) { 23 tests := []struct { 24 desc string 25 in string 26 want []string 27 }{ 28 { 29 desc: "empty", 30 in: "", 31 want: []string{}, 32 }, 33 { 34 desc: "no match", 35 in: "foo", 36 want: []string{"foo"}, 37 }, 38 { 39 desc: "first", 40 in: ":foo", 41 want: []string{"", "foo"}, 42 }, 43 { 44 desc: "last", 45 in: "foo:", 46 want: []string{"foo", ""}, 47 }, 48 { 49 desc: "multiple", 50 in: "foo:bar:baz", 51 want: []string{"foo", "bar", "baz"}, 52 }, 53 { 54 desc: "multiple with escapes", 55 in: `foo\:bar:baz\:qux`, 56 want: []string{`foo\:bar`, `baz\:qux`}, 57 }, 58 } 59 for _, tt := range tests { 60 t.Run(tt.desc, func(t *testing.T) { 61 if got, want := splitEscaped(tt.in, kvSeparatorRune), tt.want; !stringSlicesEqual(got, want) { 62 t.Errorf("%s: got:%v, want:%v", tt.desc, got, want) 63 } 64 }) 65 } 66 } 67 68 func TestIsNPathElement(t *testing.T) { 69 tests := []struct { 70 desc string 71 in string 72 expect bool 73 }{ 74 { 75 desc: "empty", 76 in: "", 77 expect: false, 78 }, 79 { 80 desc: "negative", 81 in: "[-45]", 82 expect: false, 83 }, 84 { 85 desc: "negative-1", 86 in: "[-1]", 87 expect: true, 88 }, 89 { 90 desc: "valid", 91 in: "[0]", 92 expect: true, 93 }, 94 } 95 96 for _, tt := range tests { 97 t.Run(tt.desc, func(t *testing.T) { 98 if got := IsNPathElement(tt.in); got != tt.expect { 99 t.Errorf("%s: expect %v got %v", tt.desc, tt.expect, got) 100 } 101 }) 102 } 103 } 104 105 func stringSlicesEqual(a, b []string) bool { 106 if len(a) != len(b) { 107 return false 108 } 109 for i, aa := range a { 110 if aa != b[i] { 111 return false 112 } 113 } 114 return true 115 } 116 117 func TestPathFromString(t *testing.T) { 118 tests := []struct { 119 desc string 120 in string 121 expect Path 122 }{ 123 { 124 desc: "no-path", 125 in: "", 126 expect: Path{}, 127 }, 128 { 129 desc: "valid-path", 130 in: "a.b.c", 131 expect: Path{"a", "b", "c"}, 132 }, 133 { 134 desc: "surround-periods", 135 in: ".a.", 136 expect: Path{"a"}, 137 }, 138 } 139 140 for _, tt := range tests { 141 t.Run(tt.desc, func(t *testing.T) { 142 if got := PathFromString(tt.in); !got.Equals(tt.expect) { 143 t.Errorf("%s: expect %v got %v", tt.desc, tt.expect, got) 144 } 145 }) 146 } 147 } 148 149 func TestToYAMLPath(t *testing.T) { 150 tests := []struct { 151 desc string 152 in string 153 expect Path 154 }{ 155 { 156 desc: "all-uppercase", 157 in: "A.B.C.D", 158 expect: Path{"a", "b", "c", "d"}, 159 }, 160 } 161 162 for _, tt := range tests { 163 t.Run(tt.desc, func(t *testing.T) { 164 if got := ToYAMLPath(tt.in); !got.Equals(tt.expect) { 165 t.Errorf("%s: expect %v got %v", tt.desc, tt.expect, got) 166 } 167 }) 168 } 169 } 170 171 func TestIsKVPathElement(t *testing.T) { 172 tests := []struct { 173 desc string 174 in string 175 expect bool 176 }{ 177 { 178 desc: "valid", 179 in: "[1:2]", 180 expect: true, 181 }, 182 { 183 desc: "invalid", 184 in: "[:2]", 185 expect: false, 186 }, 187 { 188 desc: "invalid-2", 189 in: "[1:]", 190 expect: false, 191 }, 192 { 193 desc: "empty", 194 in: "", 195 expect: false, 196 }, 197 { 198 desc: "no-brackets", 199 in: "1:2", 200 expect: false, 201 }, 202 { 203 desc: "one-bracket", 204 in: "[1:2", 205 expect: false, 206 }, 207 } 208 209 for _, tt := range tests { 210 t.Run(tt.desc, func(t *testing.T) { 211 if got := IsKVPathElement(tt.in); got != tt.expect { 212 t.Errorf("%s: expect %v got %v", tt.desc, tt.expect, got) 213 } 214 }) 215 } 216 } 217 218 func TestIsVPathElement(t *testing.T) { 219 tests := []struct { 220 desc string 221 in string 222 expect bool 223 }{ 224 { 225 desc: "valid", 226 in: "[:1]", 227 expect: true, 228 }, 229 { 230 desc: "kv-path-elem", 231 in: "[1:2]", 232 expect: false, 233 }, 234 { 235 desc: "invalid", 236 in: "1:2", 237 expect: false, 238 }, 239 { 240 desc: "empty", 241 in: "", 242 expect: false, 243 }, 244 } 245 246 for _, tt := range tests { 247 t.Run(tt.desc, func(t *testing.T) { 248 if got := IsVPathElement(tt.in); got != tt.expect { 249 t.Errorf("%s: expect %v got %v", tt.desc, tt.expect, got) 250 } 251 }) 252 } 253 } 254 255 func TestPathKV(t *testing.T) { 256 tests := []struct { 257 desc string 258 in string 259 wantK string 260 wantV string 261 wantErr error 262 }{ 263 { 264 desc: "valid", 265 in: "[1:2]", 266 wantK: "1", 267 wantV: "2", 268 wantErr: nil, 269 }, 270 { 271 desc: "invalid", 272 in: "[1:", 273 wantErr: errors.New(""), 274 }, 275 { 276 desc: "empty", 277 in: "", 278 wantErr: errors.New(""), 279 }, 280 } 281 282 for _, tt := range tests { 283 t.Run(tt.desc, func(t *testing.T) { 284 if k, v, err := PathKV(tt.in); k != tt.wantK || v != tt.wantV || errNilCheck(err, tt.wantErr) { 285 t.Errorf("%s: expect %v %v %v got %v %v %v", tt.desc, tt.wantK, tt.wantV, tt.wantErr, k, v, err) 286 } 287 }) 288 } 289 } 290 291 func TestPathV(t *testing.T) { 292 tests := []struct { 293 desc string 294 in string 295 want string 296 err error 297 }{ 298 { 299 desc: "valid-kv", 300 in: "[1:2]", 301 want: "1:2", 302 err: nil, 303 }, 304 { 305 desc: "valid-v", 306 in: "[:1]", 307 want: "1", 308 err: nil, 309 }, 310 { 311 desc: "invalid", 312 in: "083fj", 313 want: "", 314 err: errors.New(""), 315 }, 316 { 317 desc: "empty", 318 in: "", 319 want: "", 320 err: errors.New(""), 321 }, 322 } 323 324 for _, tt := range tests { 325 t.Run(tt.desc, func(t *testing.T) { 326 if got, err := PathV(tt.in); got != tt.want || errNilCheck(err, tt.err) { 327 t.Errorf("%s: expect %v %v got %v %v", tt.desc, tt.want, tt.err, got, err) 328 } 329 }) 330 } 331 } 332 333 func TestRemoveBrackets(t *testing.T) { 334 tests := []struct { 335 desc string 336 in string 337 expect string 338 expectStat bool 339 }{ 340 { 341 desc: "has-brackets", 342 in: "[yo]", 343 expect: "yo", 344 expectStat: true, 345 }, 346 { 347 desc: "one-bracket", 348 in: "[yo", 349 expect: "", 350 expectStat: false, 351 }, 352 { 353 desc: "other-bracket", 354 in: "yo]", 355 expect: "", 356 expectStat: false, 357 }, 358 { 359 desc: "no-brackets", 360 in: "yo", 361 expect: "", 362 expectStat: false, 363 }, 364 { 365 desc: "empty", 366 in: "", 367 expect: "", 368 expectStat: false, 369 }, 370 } 371 372 for _, tt := range tests { 373 t.Run(tt.desc, func(t *testing.T) { 374 if got, stat := RemoveBrackets(tt.in); got != tt.expect || stat != tt.expectStat { 375 t.Errorf("%s: expect %v %v got %v %v", tt.desc, tt.expect, tt.expectStat, got, stat) 376 } 377 }) 378 } 379 } 380 381 func errNilCheck(err1, err2 error) bool { 382 return (err1 == nil && err2 != nil) || (err1 != nil && err2 == nil) 383 }