github.com/sdbaiguanghe/helm@v2.16.7+incompatible/pkg/strvals/parser_test.go (about) 1 /* 2 Copyright The Helm Authors. 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 16 package strvals 17 18 import ( 19 "testing" 20 21 "github.com/ghodss/yaml" 22 ) 23 24 func TestSetIndex(t *testing.T) { 25 tests := []struct { 26 name string 27 initial []interface{} 28 expect []interface{} 29 add int 30 val int 31 }{ 32 { 33 name: "short", 34 initial: []interface{}{0, 1}, 35 expect: []interface{}{0, 1, 2}, 36 add: 2, 37 val: 2, 38 }, 39 { 40 name: "equal", 41 initial: []interface{}{0, 1}, 42 expect: []interface{}{0, 2}, 43 add: 1, 44 val: 2, 45 }, 46 { 47 name: "long", 48 initial: []interface{}{0, 1, 2, 3, 4, 5}, 49 expect: []interface{}{0, 1, 2, 4, 4, 5}, 50 add: 3, 51 val: 4, 52 }, 53 } 54 55 for _, tt := range tests { 56 got := setIndex(tt.initial, tt.add, tt.val) 57 if len(got) != len(tt.expect) { 58 t.Fatalf("%s: Expected length %d, got %d", tt.name, len(tt.expect), len(got)) 59 } 60 61 if gg := got[tt.add].(int); gg != tt.val { 62 t.Errorf("%s, Expected value %d, got %d", tt.name, tt.val, gg) 63 } 64 } 65 } 66 67 func TestParseSet(t *testing.T) { 68 testsString := []struct { 69 str string 70 expect map[string]interface{} 71 err bool 72 }{ 73 { 74 str: "long_int_string=1234567890", 75 expect: map[string]interface{}{"long_int_string": "1234567890"}, 76 err: false, 77 }, 78 { 79 str: "boolean=true", 80 expect: map[string]interface{}{"boolean": "true"}, 81 err: false, 82 }, 83 { 84 str: "is_null=null", 85 expect: map[string]interface{}{"is_null": "null"}, 86 err: false, 87 }, 88 { 89 str: "zero=0", 90 expect: map[string]interface{}{"zero": "0"}, 91 err: false, 92 }, 93 } 94 tests := []struct { 95 str string 96 expect map[string]interface{} 97 err bool 98 }{ 99 { 100 "name1=null,f=false,t=true", 101 map[string]interface{}{"name1": nil, "f": false, "t": true}, 102 false, 103 }, 104 { 105 "name1=value1", 106 map[string]interface{}{"name1": "value1"}, 107 false, 108 }, 109 { 110 "name1=value1,name2=value2", 111 map[string]interface{}{"name1": "value1", "name2": "value2"}, 112 false, 113 }, 114 { 115 "name1=value1,name2=value2,", 116 map[string]interface{}{"name1": "value1", "name2": "value2"}, 117 false, 118 }, 119 { 120 str: "name1=value1,,,,name2=value2,", 121 err: true, 122 }, 123 { 124 str: "name1=,name2=value2", 125 expect: map[string]interface{}{"name1": "", "name2": "value2"}, 126 }, 127 { 128 str: "leading_zeros=00009", 129 expect: map[string]interface{}{"leading_zeros": "00009"}, 130 }, 131 { 132 str: "zero_int=0", 133 expect: map[string]interface{}{"zero_int": 0}, 134 }, 135 { 136 str: "long_int=1234567890", 137 expect: map[string]interface{}{"long_int": 1234567890}, 138 }, 139 { 140 str: "boolean=true", 141 expect: map[string]interface{}{"boolean": true}, 142 }, 143 { 144 str: "is_null=null", 145 expect: map[string]interface{}{"is_null": nil}, 146 err: false, 147 }, 148 { 149 str: "name1,name2=", 150 err: true, 151 }, 152 { 153 str: "name1,name2=value2", 154 err: true, 155 }, 156 { 157 str: "name1,name2=value2\\", 158 err: true, 159 }, 160 { 161 str: "name1,name2", 162 err: true, 163 }, 164 { 165 "name1=one\\,two,name2=three\\,four", 166 map[string]interface{}{"name1": "one,two", "name2": "three,four"}, 167 false, 168 }, 169 { 170 "name1=one\\=two,name2=three\\=four", 171 map[string]interface{}{"name1": "one=two", "name2": "three=four"}, 172 false, 173 }, 174 { 175 "name1=one two three,name2=three two one", 176 map[string]interface{}{"name1": "one two three", "name2": "three two one"}, 177 false, 178 }, 179 { 180 "outer.inner=value", 181 map[string]interface{}{"outer": map[string]interface{}{"inner": "value"}}, 182 false, 183 }, 184 { 185 "outer.middle.inner=value", 186 map[string]interface{}{"outer": map[string]interface{}{"middle": map[string]interface{}{"inner": "value"}}}, 187 false, 188 }, 189 { 190 "outer.inner1=value,outer.inner2=value2", 191 map[string]interface{}{"outer": map[string]interface{}{"inner1": "value", "inner2": "value2"}}, 192 false, 193 }, 194 { 195 "outer.inner1=value,outer.middle.inner=value", 196 map[string]interface{}{ 197 "outer": map[string]interface{}{ 198 "inner1": "value", 199 "middle": map[string]interface{}{ 200 "inner": "value", 201 }, 202 }, 203 }, 204 false, 205 }, 206 { 207 str: "name1.name2", 208 err: true, 209 }, 210 { 211 str: "name1.name2,name1.name3", 212 err: true, 213 }, 214 { 215 str: "name1.name2=", 216 expect: map[string]interface{}{"name1": map[string]interface{}{"name2": ""}}, 217 }, 218 { 219 str: "name1.=name2", 220 err: true, 221 }, 222 { 223 str: "name1.,name2", 224 err: true, 225 }, 226 { 227 "name1={value1,value2}", 228 map[string]interface{}{"name1": []string{"value1", "value2"}}, 229 false, 230 }, 231 { 232 "name1={value1,value2},name2={value1,value2}", 233 map[string]interface{}{ 234 "name1": []string{"value1", "value2"}, 235 "name2": []string{"value1", "value2"}, 236 }, 237 false, 238 }, 239 { 240 "name1={1021,902}", 241 map[string]interface{}{"name1": []int{1021, 902}}, 242 false, 243 }, 244 { 245 "name1.name2={value1,value2}", 246 map[string]interface{}{"name1": map[string]interface{}{"name2": []string{"value1", "value2"}}}, 247 false, 248 }, 249 { 250 str: "name1={1021,902", 251 err: true, 252 }, 253 // List support 254 { 255 str: "list[0]=foo", 256 expect: map[string]interface{}{"list": []string{"foo"}}, 257 }, 258 { 259 str: "list[0].foo=bar", 260 expect: map[string]interface{}{ 261 "list": []interface{}{ 262 map[string]interface{}{"foo": "bar"}, 263 }, 264 }, 265 }, 266 { 267 str: "list[0].foo=bar,list[0].hello=world", 268 expect: map[string]interface{}{ 269 "list": []interface{}{ 270 map[string]interface{}{"foo": "bar", "hello": "world"}, 271 }, 272 }, 273 }, 274 { 275 str: "list[0]=foo,list[1]=bar", 276 expect: map[string]interface{}{"list": []string{"foo", "bar"}}, 277 }, 278 { 279 str: "list[0]=foo,list[1]=bar,", 280 expect: map[string]interface{}{"list": []string{"foo", "bar"}}, 281 }, 282 { 283 str: "list[0]=foo,list[3]=bar", 284 expect: map[string]interface{}{"list": []interface{}{"foo", nil, nil, "bar"}}, 285 }, 286 { 287 str: "illegal[0]name.foo=bar", 288 err: true, 289 }, 290 { 291 str: "noval[0]", 292 expect: map[string]interface{}{"noval": []interface{}{}}, 293 }, 294 { 295 str: "noval[0]=", 296 expect: map[string]interface{}{"noval": []interface{}{""}}, 297 }, 298 { 299 str: "nested[0][0]=1", 300 expect: map[string]interface{}{"nested": []interface{}{[]interface{}{1}}}, 301 }, 302 { 303 str: "nested[1][1]=1", 304 expect: map[string]interface{}{"nested": []interface{}{nil, []interface{}{nil, 1}}}, 305 }, 306 { 307 str: "name1.name2[0].foo=bar,name1.name2[1].foo=bar", 308 expect: map[string]interface{}{ 309 "name1": map[string]interface{}{ 310 "name2": []map[string]interface{}{{"foo": "bar"}, {"foo": "bar"}}, 311 }, 312 }, 313 }, 314 { 315 str: "name1.name2[1].foo=bar,name1.name2[0].foo=bar", 316 expect: map[string]interface{}{ 317 "name1": map[string]interface{}{ 318 "name2": []map[string]interface{}{{"foo": "bar"}, {"foo": "bar"}}, 319 }, 320 }, 321 }, 322 { 323 str: "name1.name2[1].foo=bar", 324 expect: map[string]interface{}{ 325 "name1": map[string]interface{}{ 326 "name2": []map[string]interface{}{nil, {"foo": "bar"}}, 327 }, 328 }, 329 }, 330 } 331 332 for _, tt := range tests { 333 got, err := Parse(tt.str) 334 if err != nil { 335 if tt.err { 336 continue 337 } 338 t.Fatalf("%s: %s", tt.str, err) 339 } 340 if tt.err { 341 t.Errorf("%s: Expected error. Got nil", tt.str) 342 } 343 344 y1, err := yaml.Marshal(tt.expect) 345 if err != nil { 346 t.Fatal(err) 347 } 348 y2, err := yaml.Marshal(got) 349 if err != nil { 350 t.Fatalf("Error serializing parsed value: %s", err) 351 } 352 353 if string(y1) != string(y2) { 354 t.Errorf("%s: Expected:\n%s\nGot:\n%s", tt.str, y1, y2) 355 } 356 } 357 for _, tt := range testsString { 358 got, err := ParseString(tt.str) 359 if err != nil { 360 if tt.err { 361 continue 362 } 363 t.Fatalf("%s: %s", tt.str, err) 364 } 365 if tt.err { 366 t.Errorf("%s: Expected error. Got nil", tt.str) 367 } 368 369 y1, err := yaml.Marshal(tt.expect) 370 if err != nil { 371 t.Fatal(err) 372 } 373 y2, err := yaml.Marshal(got) 374 if err != nil { 375 t.Fatalf("Error serializing parsed value: %s", err) 376 } 377 378 if string(y1) != string(y2) { 379 t.Errorf("%s: Expected:\n%s\nGot:\n%s", tt.str, y1, y2) 380 } 381 } 382 } 383 384 func TestParseInto(t *testing.T) { 385 got := map[string]interface{}{ 386 "outer": map[string]interface{}{ 387 "inner1": "overwrite", 388 "inner2": "value2", 389 }, 390 } 391 input := "outer.inner1=value1,outer.inner3=value3,outer.inner4=4" 392 expect := map[string]interface{}{ 393 "outer": map[string]interface{}{ 394 "inner1": "value1", 395 "inner2": "value2", 396 "inner3": "value3", 397 "inner4": 4, 398 }, 399 } 400 401 if err := ParseInto(input, got); err != nil { 402 t.Fatal(err) 403 } 404 405 y1, err := yaml.Marshal(expect) 406 if err != nil { 407 t.Fatal(err) 408 } 409 y2, err := yaml.Marshal(got) 410 if err != nil { 411 t.Fatalf("Error serializing parsed value: %s", err) 412 } 413 414 if string(y1) != string(y2) { 415 t.Errorf("%s: Expected:\n%s\nGot:\n%s", input, y1, y2) 416 } 417 } 418 func TestParseIntoString(t *testing.T) { 419 got := map[string]interface{}{ 420 "outer": map[string]interface{}{ 421 "inner1": "overwrite", 422 "inner2": "value2", 423 }, 424 } 425 input := "outer.inner1=1,outer.inner3=3" 426 expect := map[string]interface{}{ 427 "outer": map[string]interface{}{ 428 "inner1": "1", 429 "inner2": "value2", 430 "inner3": "3", 431 }, 432 } 433 434 if err := ParseIntoString(input, got); err != nil { 435 t.Fatal(err) 436 } 437 438 y1, err := yaml.Marshal(expect) 439 if err != nil { 440 t.Fatal(err) 441 } 442 y2, err := yaml.Marshal(got) 443 if err != nil { 444 t.Fatalf("Error serializing parsed value: %s", err) 445 } 446 447 if string(y1) != string(y2) { 448 t.Errorf("%s: Expected:\n%s\nGot:\n%s", input, y1, y2) 449 } 450 } 451 452 func TestParseIntoFile(t *testing.T) { 453 got := map[string]interface{}{} 454 input := "name1=path1" 455 expect := map[string]interface{}{ 456 "name1": "value1", 457 } 458 rs2v := func(rs []rune) (interface{}, error) { 459 v := string(rs) 460 if v != "path1" { 461 t.Errorf("%s: runesToVal: Expected value path1, got %s", input, v) 462 return "", nil 463 } 464 return "value1", nil 465 } 466 467 if err := ParseIntoFile(input, got, rs2v); err != nil { 468 t.Fatal(err) 469 } 470 471 y1, err := yaml.Marshal(expect) 472 if err != nil { 473 t.Fatal(err) 474 } 475 y2, err := yaml.Marshal(got) 476 if err != nil { 477 t.Fatalf("Error serializing parsed value: %s", err) 478 } 479 480 if string(y1) != string(y2) { 481 t.Errorf("%s: Expected:\n%s\nGot:\n%s", input, y1, y2) 482 } 483 } 484 485 func TestToYAML(t *testing.T) { 486 // The TestParse does the hard part. We just verify that YAML formatting is 487 // happening. 488 o, err := ToYAML("name=value") 489 if err != nil { 490 t.Fatal(err) 491 } 492 expect := "name: value\n" 493 if o != expect { 494 t.Errorf("Expected %q, got %q", expect, o) 495 } 496 }