github.com/amtisyAts/helm@v2.17.0+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 tests := []struct { 386 input string 387 input2 string 388 got map[string]interface{} 389 expect map[string]interface{} 390 err bool 391 }{ 392 { 393 input: "outer.inner1=value1,outer.inner3=value3,outer.inner4=4", 394 got: map[string]interface{}{ 395 "outer": map[string]interface{}{ 396 "inner1": "overwrite", 397 "inner2": "value2", 398 }, 399 }, 400 expect: map[string]interface{}{ 401 "outer": map[string]interface{}{ 402 "inner1": "value1", 403 "inner2": "value2", 404 "inner3": "value3", 405 "inner4": 4, 406 }}, 407 err: false, 408 }, 409 { 410 input: "listOuter[0][0].type=listValue", 411 input2: "listOuter[0][0].status=alive", 412 got: map[string]interface{}{}, 413 expect: map[string]interface{}{ 414 "listOuter": [][]interface{}{{map[string]string{ 415 "type": "listValue", 416 "status": "alive", 417 }}}, 418 }, 419 err: false, 420 }, 421 { 422 input: "listOuter[0][0].type=listValue", 423 input2: "listOuter[1][0].status=alive", 424 got: map[string]interface{}{}, 425 expect: map[string]interface{}{ 426 "listOuter": [][]interface{}{ 427 { 428 map[string]string{"type": "listValue"}, 429 }, 430 { 431 map[string]string{"status": "alive"}, 432 }, 433 }, 434 }, 435 err: false, 436 }, 437 { 438 input: "listOuter[0][1][0].type=listValue", 439 input2: "listOuter[0][0][1].status=alive", 440 got: map[string]interface{}{ 441 "listOuter": []interface{}{ 442 []interface{}{ 443 []interface{}{ 444 map[string]string{"exited": "old"}, 445 }, 446 }, 447 }, 448 }, 449 expect: map[string]interface{}{ 450 "listOuter": [][][]interface{}{ 451 { 452 { 453 map[string]string{"exited": "old"}, 454 map[string]string{"status": "alive"}, 455 }, 456 { 457 map[string]string{"type": "listValue"}, 458 }, 459 }, 460 }, 461 }, 462 err: false, 463 }, 464 } 465 for _, tt := range tests { 466 if err := ParseInto(tt.input, tt.got); err != nil { 467 t.Fatal(err) 468 } 469 if tt.err { 470 t.Errorf("%s: Expected error. Got nil", tt.input) 471 } 472 473 if tt.input2 != "" { 474 if err := ParseInto(tt.input2, tt.got); err != nil { 475 t.Fatal(err) 476 } 477 if tt.err { 478 t.Errorf("%s: Expected error. Got nil", tt.input2) 479 } 480 } 481 482 y1, err := yaml.Marshal(tt.expect) 483 if err != nil { 484 t.Fatal(err) 485 } 486 y2, err := yaml.Marshal(tt.got) 487 if err != nil { 488 t.Fatalf("Error serializing parsed value: %s", err) 489 } 490 491 if string(y1) != string(y2) { 492 t.Errorf("%s: Expected:\n%s\nGot:\n%s", tt.input, y1, y2) 493 } 494 } 495 } 496 497 func TestParseIntoString(t *testing.T) { 498 got := map[string]interface{}{ 499 "outer": map[string]interface{}{ 500 "inner1": "overwrite", 501 "inner2": "value2", 502 }, 503 } 504 input := "outer.inner1=1,outer.inner3=3" 505 expect := map[string]interface{}{ 506 "outer": map[string]interface{}{ 507 "inner1": "1", 508 "inner2": "value2", 509 "inner3": "3", 510 }, 511 } 512 513 if err := ParseIntoString(input, got); err != nil { 514 t.Fatal(err) 515 } 516 517 y1, err := yaml.Marshal(expect) 518 if err != nil { 519 t.Fatal(err) 520 } 521 y2, err := yaml.Marshal(got) 522 if err != nil { 523 t.Fatalf("Error serializing parsed value: %s", err) 524 } 525 526 if string(y1) != string(y2) { 527 t.Errorf("%s: Expected:\n%s\nGot:\n%s", input, y1, y2) 528 } 529 } 530 531 func TestParseIntoFile(t *testing.T) { 532 got := map[string]interface{}{} 533 input := "name1=path1" 534 expect := map[string]interface{}{ 535 "name1": "value1", 536 } 537 rs2v := func(rs []rune) (interface{}, error) { 538 v := string(rs) 539 if v != "path1" { 540 t.Errorf("%s: runesToVal: Expected value path1, got %s", input, v) 541 return "", nil 542 } 543 return "value1", nil 544 } 545 546 if err := ParseIntoFile(input, got, rs2v); err != nil { 547 t.Fatal(err) 548 } 549 550 y1, err := yaml.Marshal(expect) 551 if err != nil { 552 t.Fatal(err) 553 } 554 y2, err := yaml.Marshal(got) 555 if err != nil { 556 t.Fatalf("Error serializing parsed value: %s", err) 557 } 558 559 if string(y1) != string(y2) { 560 t.Errorf("%s: Expected:\n%s\nGot:\n%s", input, y1, y2) 561 } 562 } 563 564 func TestToYAML(t *testing.T) { 565 // The TestParse does the hard part. We just verify that YAML formatting is 566 // happening. 567 o, err := ToYAML("name=value") 568 if err != nil { 569 t.Fatal(err) 570 } 571 expect := "name: value\n" 572 if o != expect { 573 t.Errorf("Expected %q, got %q", expect, o) 574 } 575 }