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