1
15
16 package strvals
17
18 import (
19 "fmt"
20 "testing"
21
22 "sigs.k8s.io/yaml"
23 )
24
25 func TestSetIndex(t *testing.T) {
26 tests := []struct {
27 name string
28 initial []interface{}
29 expect []interface{}
30 add int
31 val int
32 err bool
33 }{
34 {
35 name: "short",
36 initial: []interface{}{0, 1},
37 expect: []interface{}{0, 1, 2},
38 add: 2,
39 val: 2,
40 err: false,
41 },
42 {
43 name: "equal",
44 initial: []interface{}{0, 1},
45 expect: []interface{}{0, 2},
46 add: 1,
47 val: 2,
48 err: false,
49 },
50 {
51 name: "long",
52 initial: []interface{}{0, 1, 2, 3, 4, 5},
53 expect: []interface{}{0, 1, 2, 4, 4, 5},
54 add: 3,
55 val: 4,
56 err: false,
57 },
58 {
59 name: "negative",
60 initial: []interface{}{0, 1, 2, 3, 4, 5},
61 expect: []interface{}{0, 1, 2, 3, 4, 5},
62 add: -1,
63 val: 4,
64 err: true,
65 },
66 {
67 name: "large",
68 initial: []interface{}{0, 1, 2, 3, 4, 5},
69 expect: []interface{}{0, 1, 2, 3, 4, 5},
70 add: MaxIndex + 1,
71 val: 4,
72 err: true,
73 },
74 }
75
76 for _, tt := range tests {
77 got, err := setIndex(tt.initial, tt.add, tt.val)
78
79 if err != nil && tt.err == false {
80 t.Fatalf("%s: Expected no error but error returned", tt.name)
81 } else if err == nil && tt.err == true {
82 t.Fatalf("%s: Expected error but no error returned", tt.name)
83 }
84
85 if len(got) != len(tt.expect) {
86 t.Fatalf("%s: Expected length %d, got %d", tt.name, len(tt.expect), len(got))
87 }
88
89 if !tt.err {
90 if gg := got[tt.add].(int); gg != tt.val {
91 t.Errorf("%s, Expected value %d, got %d", tt.name, tt.val, gg)
92 }
93 }
94
95 for k, v := range got {
96 if v != tt.expect[k] {
97 t.Errorf("%s, Expected value %d, got %d", tt.name, tt.expect[k], v)
98 }
99 }
100 }
101 }
102
103 func TestParseSet(t *testing.T) {
104 testsString := []struct {
105 str string
106 expect map[string]interface{}
107 err bool
108 }{
109 {
110 str: "long_int_string=1234567890",
111 expect: map[string]interface{}{"long_int_string": "1234567890"},
112 err: false,
113 },
114 {
115 str: "boolean=true",
116 expect: map[string]interface{}{"boolean": "true"},
117 err: false,
118 },
119 {
120 str: "is_null=null",
121 expect: map[string]interface{}{"is_null": "null"},
122 err: false,
123 },
124 {
125 str: "zero=0",
126 expect: map[string]interface{}{"zero": "0"},
127 err: false,
128 },
129 }
130 tests := []struct {
131 str string
132 expect map[string]interface{}
133 err bool
134 }{
135 {
136 "name1=null,f=false,t=true",
137 map[string]interface{}{"name1": nil, "f": false, "t": true},
138 false,
139 },
140 {
141 "name1=value1",
142 map[string]interface{}{"name1": "value1"},
143 false,
144 },
145 {
146 "name1=value1,name2=value2",
147 map[string]interface{}{"name1": "value1", "name2": "value2"},
148 false,
149 },
150 {
151 "name1=value1,name2=value2,",
152 map[string]interface{}{"name1": "value1", "name2": "value2"},
153 false,
154 },
155 {
156 str: "name1=value1,,,,name2=value2,",
157 err: true,
158 },
159 {
160 str: "name1=,name2=value2",
161 expect: map[string]interface{}{"name1": "", "name2": "value2"},
162 },
163 {
164 str: "leading_zeros=00009",
165 expect: map[string]interface{}{"leading_zeros": "00009"},
166 },
167 {
168 str: "zero_int=0",
169 expect: map[string]interface{}{"zero_int": 0},
170 },
171 {
172 str: "long_int=1234567890",
173 expect: map[string]interface{}{"long_int": 1234567890},
174 },
175 {
176 str: "boolean=true",
177 expect: map[string]interface{}{"boolean": true},
178 },
179 {
180 str: "is_null=null",
181 expect: map[string]interface{}{"is_null": nil},
182 err: false,
183 },
184 {
185 str: "name1,name2=",
186 err: true,
187 },
188 {
189 str: "name1,name2=value2",
190 err: true,
191 },
192 {
193 str: "name1,name2=value2\\",
194 err: true,
195 },
196 {
197 str: "name1,name2",
198 err: true,
199 },
200 {
201 "name1=one\\,two,name2=three\\,four",
202 map[string]interface{}{"name1": "one,two", "name2": "three,four"},
203 false,
204 },
205 {
206 "name1=one\\=two,name2=three\\=four",
207 map[string]interface{}{"name1": "one=two", "name2": "three=four"},
208 false,
209 },
210 {
211 "name1=one two three,name2=three two one",
212 map[string]interface{}{"name1": "one two three", "name2": "three two one"},
213 false,
214 },
215 {
216 "outer.inner=value",
217 map[string]interface{}{"outer": map[string]interface{}{"inner": "value"}},
218 false,
219 },
220 {
221 "outer.middle.inner=value",
222 map[string]interface{}{"outer": map[string]interface{}{"middle": map[string]interface{}{"inner": "value"}}},
223 false,
224 },
225 {
226 "outer.inner1=value,outer.inner2=value2",
227 map[string]interface{}{"outer": map[string]interface{}{"inner1": "value", "inner2": "value2"}},
228 false,
229 },
230 {
231 "outer.inner1=value,outer.middle.inner=value",
232 map[string]interface{}{
233 "outer": map[string]interface{}{
234 "inner1": "value",
235 "middle": map[string]interface{}{
236 "inner": "value",
237 },
238 },
239 },
240 false,
241 },
242 {
243 str: "name1.name2",
244 err: true,
245 },
246 {
247 str: "name1.name2,name1.name3",
248 err: true,
249 },
250 {
251 str: "name1.name2=",
252 expect: map[string]interface{}{"name1": map[string]interface{}{"name2": ""}},
253 },
254 {
255 str: "name1.=name2",
256 err: true,
257 },
258 {
259 str: "name1.,name2",
260 err: true,
261 },
262 {
263 "name1={value1,value2}",
264 map[string]interface{}{"name1": []string{"value1", "value2"}},
265 false,
266 },
267 {
268 "name1={value1,value2},name2={value1,value2}",
269 map[string]interface{}{
270 "name1": []string{"value1", "value2"},
271 "name2": []string{"value1", "value2"},
272 },
273 false,
274 },
275 {
276 "name1={1021,902}",
277 map[string]interface{}{"name1": []int{1021, 902}},
278 false,
279 },
280 {
281 "name1.name2={value1,value2}",
282 map[string]interface{}{"name1": map[string]interface{}{"name2": []string{"value1", "value2"}}},
283 false,
284 },
285 {
286 str: "name1={1021,902",
287 err: true,
288 },
289
290 {
291 str: "list[0]=foo",
292 expect: map[string]interface{}{"list": []string{"foo"}},
293 },
294 {
295 str: "list[0].foo=bar",
296 expect: map[string]interface{}{
297 "list": []interface{}{
298 map[string]interface{}{"foo": "bar"},
299 },
300 },
301 },
302 {
303 str: "list[0].foo=bar,list[0].hello=world",
304 expect: map[string]interface{}{
305 "list": []interface{}{
306 map[string]interface{}{"foo": "bar", "hello": "world"},
307 },
308 },
309 },
310 {
311 str: "list[0].foo=bar,list[-30].hello=world",
312 err: true,
313 },
314 {
315 str: "list[0]=foo,list[1]=bar",
316 expect: map[string]interface{}{"list": []string{"foo", "bar"}},
317 },
318 {
319 str: "list[0]=foo,list[1]=bar,",
320 expect: map[string]interface{}{"list": []string{"foo", "bar"}},
321 },
322 {
323 str: "list[0]=foo,list[3]=bar",
324 expect: map[string]interface{}{"list": []interface{}{"foo", nil, nil, "bar"}},
325 },
326 {
327 str: "list[0]=foo,list[-20]=bar",
328 err: true,
329 },
330 {
331 str: "illegal[0]name.foo=bar",
332 err: true,
333 },
334 {
335 str: "noval[0]",
336 expect: map[string]interface{}{"noval": []interface{}{}},
337 },
338 {
339 str: "noval[0]=",
340 expect: map[string]interface{}{"noval": []interface{}{""}},
341 },
342 {
343 str: "nested[0][0]=1",
344 expect: map[string]interface{}{"nested": []interface{}{[]interface{}{1}}},
345 },
346 {
347 str: "nested[1][1]=1",
348 expect: map[string]interface{}{"nested": []interface{}{nil, []interface{}{nil, 1}}},
349 },
350 {
351 str: "name1.name2[0].foo=bar,name1.name2[1].foo=bar",
352 expect: map[string]interface{}{
353 "name1": map[string]interface{}{
354 "name2": []map[string]interface{}{{"foo": "bar"}, {"foo": "bar"}},
355 },
356 },
357 },
358 {
359 str: "name1.name2[1].foo=bar,name1.name2[0].foo=bar",
360 expect: map[string]interface{}{
361 "name1": map[string]interface{}{
362 "name2": []map[string]interface{}{{"foo": "bar"}, {"foo": "bar"}},
363 },
364 },
365 },
366 {
367 str: "name1.name2[1].foo=bar",
368 expect: map[string]interface{}{
369 "name1": map[string]interface{}{
370 "name2": []map[string]interface{}{nil, {"foo": "bar"}},
371 },
372 },
373 },
374 {
375 str: "]={}].",
376 err: true,
377 },
378 }
379
380 for _, tt := range tests {
381 got, err := Parse(tt.str)
382 if err != nil {
383 if tt.err {
384 continue
385 }
386 t.Fatalf("%s: %s", tt.str, err)
387 }
388 if tt.err {
389 t.Errorf("%s: Expected error. Got nil", tt.str)
390 }
391
392 y1, err := yaml.Marshal(tt.expect)
393 if err != nil {
394 t.Fatal(err)
395 }
396 y2, err := yaml.Marshal(got)
397 if err != nil {
398 t.Fatalf("Error serializing parsed value: %s", err)
399 }
400
401 if string(y1) != string(y2) {
402 t.Errorf("%s: Expected:\n%s\nGot:\n%s", tt.str, y1, y2)
403 }
404 }
405 for _, tt := range testsString {
406 got, err := ParseString(tt.str)
407 if err != nil {
408 if tt.err {
409 continue
410 }
411 t.Fatalf("%s: %s", tt.str, err)
412 }
413 if tt.err {
414 t.Errorf("%s: Expected error. Got nil", tt.str)
415 }
416
417 y1, err := yaml.Marshal(tt.expect)
418 if err != nil {
419 t.Fatal(err)
420 }
421 y2, err := yaml.Marshal(got)
422 if err != nil {
423 t.Fatalf("Error serializing parsed value: %s", err)
424 }
425
426 if string(y1) != string(y2) {
427 t.Errorf("%s: Expected:\n%s\nGot:\n%s", tt.str, y1, y2)
428 }
429 }
430 }
431
432 func TestParseInto(t *testing.T) {
433 tests := []struct {
434 input string
435 input2 string
436 got map[string]interface{}
437 expect map[string]interface{}
438 err bool
439 }{
440 {
441 input: "outer.inner1=value1,outer.inner3=value3,outer.inner4=4",
442 got: map[string]interface{}{
443 "outer": map[string]interface{}{
444 "inner1": "overwrite",
445 "inner2": "value2",
446 },
447 },
448 expect: map[string]interface{}{
449 "outer": map[string]interface{}{
450 "inner1": "value1",
451 "inner2": "value2",
452 "inner3": "value3",
453 "inner4": 4,
454 }},
455 err: false,
456 },
457 {
458 input: "listOuter[0][0].type=listValue",
459 input2: "listOuter[0][0].status=alive",
460 got: map[string]interface{}{},
461 expect: map[string]interface{}{
462 "listOuter": [][]interface{}{{map[string]string{
463 "type": "listValue",
464 "status": "alive",
465 }}},
466 },
467 err: false,
468 },
469 {
470 input: "listOuter[0][0].type=listValue",
471 input2: "listOuter[1][0].status=alive",
472 got: map[string]interface{}{},
473 expect: map[string]interface{}{
474 "listOuter": [][]interface{}{
475 {
476 map[string]string{"type": "listValue"},
477 },
478 {
479 map[string]string{"status": "alive"},
480 },
481 },
482 },
483 err: false,
484 },
485 {
486 input: "listOuter[0][1][0].type=listValue",
487 input2: "listOuter[0][0][1].status=alive",
488 got: map[string]interface{}{
489 "listOuter": []interface{}{
490 []interface{}{
491 []interface{}{
492 map[string]string{"exited": "old"},
493 },
494 },
495 },
496 },
497 expect: map[string]interface{}{
498 "listOuter": [][][]interface{}{
499 {
500 {
501 map[string]string{"exited": "old"},
502 map[string]string{"status": "alive"},
503 },
504 {
505 map[string]string{"type": "listValue"},
506 },
507 },
508 },
509 },
510 err: false,
511 },
512 }
513 for _, tt := range tests {
514 if err := ParseInto(tt.input, tt.got); err != nil {
515 t.Fatal(err)
516 }
517 if tt.err {
518 t.Errorf("%s: Expected error. Got nil", tt.input)
519 }
520
521 if tt.input2 != "" {
522 if err := ParseInto(tt.input2, tt.got); err != nil {
523 t.Fatal(err)
524 }
525 if tt.err {
526 t.Errorf("%s: Expected error. Got nil", tt.input2)
527 }
528 }
529
530 y1, err := yaml.Marshal(tt.expect)
531 if err != nil {
532 t.Fatal(err)
533 }
534 y2, err := yaml.Marshal(tt.got)
535 if err != nil {
536 t.Fatalf("Error serializing parsed value: %s", err)
537 }
538
539 if string(y1) != string(y2) {
540 t.Errorf("%s: Expected:\n%s\nGot:\n%s", tt.input, y1, y2)
541 }
542 }
543 }
544
545 func TestParseIntoString(t *testing.T) {
546 got := map[string]interface{}{
547 "outer": map[string]interface{}{
548 "inner1": "overwrite",
549 "inner2": "value2",
550 },
551 }
552 input := "outer.inner1=1,outer.inner3=3"
553 expect := map[string]interface{}{
554 "outer": map[string]interface{}{
555 "inner1": "1",
556 "inner2": "value2",
557 "inner3": "3",
558 },
559 }
560
561 if err := ParseIntoString(input, got); err != nil {
562 t.Fatal(err)
563 }
564
565 y1, err := yaml.Marshal(expect)
566 if err != nil {
567 t.Fatal(err)
568 }
569 y2, err := yaml.Marshal(got)
570 if err != nil {
571 t.Fatalf("Error serializing parsed value: %s", err)
572 }
573
574 if string(y1) != string(y2) {
575 t.Errorf("%s: Expected:\n%s\nGot:\n%s", input, y1, y2)
576 }
577 }
578
579 func TestParseJSON(t *testing.T) {
580 tests := []struct {
581 input string
582 got map[string]interface{}
583 expect map[string]interface{}
584 err bool
585 }{
586 {
587 input: "outer.inner1=\"1\",outer.inner3=3,outer.inner4=true,outer.inner5=\"true\"",
588 got: map[string]interface{}{
589 "outer": map[string]interface{}{
590 "inner1": "overwrite",
591 "inner2": "value2",
592 },
593 },
594 expect: map[string]interface{}{
595 "outer": map[string]interface{}{
596 "inner1": "1",
597 "inner2": "value2",
598 "inner3": 3,
599 "inner4": true,
600 "inner5": "true",
601 },
602 },
603 err: false,
604 },
605 {
606 input: "outer.inner1={\"a\":\"1\",\"b\":2,\"c\":[1,2,3]},outer.inner3=[\"new value 1\",\"new value 2\"],outer.inner4={\"aa\":\"1\",\"bb\":2,\"cc\":[1,2,3]},outer.inner5=[{\"A\":\"1\",\"B\":2,\"C\":[1,2,3]}]",
607 got: map[string]interface{}{
608 "outer": map[string]interface{}{
609 "inner1": map[string]interface{}{
610 "x": "overwrite",
611 },
612 "inner2": "value2",
613 "inner3": []interface{}{
614 "overwrite",
615 },
616 },
617 },
618 expect: map[string]interface{}{
619 "outer": map[string]interface{}{
620 "inner1": map[string]interface{}{"a": "1", "b": 2, "c": []interface{}{1, 2, 3}},
621 "inner2": "value2",
622 "inner3": []interface{}{"new value 1", "new value 2"},
623 "inner4": map[string]interface{}{"aa": "1", "bb": 2, "cc": []interface{}{1, 2, 3}},
624 "inner5": []interface{}{map[string]interface{}{"A": "1", "B": 2, "C": []interface{}{1, 2, 3}}},
625 },
626 },
627 err: false,
628 },
629 {
630 input: "outer.inner1=,outer.inner3={\"aa\":\"1\",\"bb\":2,\"cc\":[1,2,3]},outer.inner3.cc[1]=null",
631 got: map[string]interface{}{
632 "outer": map[string]interface{}{
633 "inner1": map[string]interface{}{
634 "x": "overwrite",
635 },
636 "inner2": "value2",
637 },
638 },
639 expect: map[string]interface{}{
640 "outer": map[string]interface{}{
641 "inner1": nil,
642 "inner2": "value2",
643 "inner3": map[string]interface{}{"aa": "1", "bb": 2, "cc": []interface{}{1, nil, 3}},
644 },
645 },
646 err: false,
647 },
648 {
649 input: "outer.inner1={\"a\":\"1\",\"b\":2,\"c\":[1,2,3]},outer.inner3=[\"new value 1\",\"new value 2\"],outer.inner4={\"aa\":\"1\",\"bb\":2,\"cc\":[1,2,3]},outer.inner5={\"A\":\"1\",\"B\":2,\"C\":[1,2,3]}]",
650 got: nil,
651 expect: nil,
652 err: true,
653 },
654 }
655 for _, tt := range tests {
656 if err := ParseJSON(tt.input, tt.got); err != nil {
657 if tt.err {
658 continue
659 }
660 t.Fatalf("%s: %s", tt.input, err)
661 }
662 if tt.err {
663 t.Fatalf("%s: Expected error. Got nil", tt.input)
664 }
665 y1, err := yaml.Marshal(tt.expect)
666 if err != nil {
667 t.Fatalf("Error serializing expected value: %s", err)
668 }
669 y2, err := yaml.Marshal(tt.got)
670 if err != nil {
671 t.Fatalf("Error serializing parsed value: %s", err)
672 }
673
674 if string(y1) != string(y2) {
675 t.Errorf("%s: Expected:\n%s\nGot:\n%s", tt.input, y1, y2)
676 }
677 }
678 }
679
680 func TestParseFile(t *testing.T) {
681 input := "name1=path1"
682 expect := map[string]interface{}{
683 "name1": "value1",
684 }
685 rs2v := func(rs []rune) (interface{}, error) {
686 v := string(rs)
687 if v != "path1" {
688 t.Errorf("%s: runesToVal: Expected value path1, got %s", input, v)
689 return "", nil
690 }
691 return "value1", nil
692 }
693
694 got, err := ParseFile(input, rs2v)
695 if err != nil {
696 t.Fatal(err)
697 }
698
699 y1, err := yaml.Marshal(expect)
700 if err != nil {
701 t.Fatal(err)
702 }
703 y2, err := yaml.Marshal(got)
704 if err != nil {
705 t.Fatalf("Error serializing parsed value: %s", err)
706 }
707
708 if string(y1) != string(y2) {
709 t.Errorf("%s: Expected:\n%s\nGot:\n%s", input, y1, y2)
710 }
711 }
712
713 func TestParseIntoFile(t *testing.T) {
714 got := map[string]interface{}{}
715 input := "name1=path1"
716 expect := map[string]interface{}{
717 "name1": "value1",
718 }
719 rs2v := func(rs []rune) (interface{}, error) {
720 v := string(rs)
721 if v != "path1" {
722 t.Errorf("%s: runesToVal: Expected value path1, got %s", input, v)
723 return "", nil
724 }
725 return "value1", nil
726 }
727
728 if err := ParseIntoFile(input, got, rs2v); err != nil {
729 t.Fatal(err)
730 }
731
732 y1, err := yaml.Marshal(expect)
733 if err != nil {
734 t.Fatal(err)
735 }
736 y2, err := yaml.Marshal(got)
737 if err != nil {
738 t.Fatalf("Error serializing parsed value: %s", err)
739 }
740
741 if string(y1) != string(y2) {
742 t.Errorf("%s: Expected:\n%s\nGot:\n%s", input, y1, y2)
743 }
744 }
745
746 func TestToYAML(t *testing.T) {
747
748
749 o, err := ToYAML("name=value")
750 if err != nil {
751 t.Fatal(err)
752 }
753 expect := "name: value"
754 if o != expect {
755 t.Errorf("Expected %q, got %q", expect, o)
756 }
757 }
758
759 func TestParseSetNestedLevels(t *testing.T) {
760 var keyMultipleNestedLevels string
761 for i := 1; i <= MaxNestedNameLevel+2; i++ {
762 tmpStr := fmt.Sprintf("name%d", i)
763 if i <= MaxNestedNameLevel+1 {
764 tmpStr = tmpStr + "."
765 }
766 keyMultipleNestedLevels += tmpStr
767 }
768 tests := []struct {
769 str string
770 expect map[string]interface{}
771 err bool
772 errStr string
773 }{
774 {
775 "outer.middle.inner=value",
776 map[string]interface{}{"outer": map[string]interface{}{"middle": map[string]interface{}{"inner": "value"}}},
777 false,
778 "",
779 },
780 {
781 str: keyMultipleNestedLevels + "=value",
782 err: true,
783 errStr: fmt.Sprintf("value name nested level is greater than maximum supported nested level of %d",
784 MaxNestedNameLevel),
785 },
786 }
787
788 for _, tt := range tests {
789 got, err := Parse(tt.str)
790 if err != nil {
791 if tt.err {
792 if tt.errStr != "" {
793 if err.Error() != tt.errStr {
794 t.Errorf("Expected error: %s. Got error: %s", tt.errStr, err.Error())
795 }
796 }
797 continue
798 }
799 t.Fatalf("%s: %s", tt.str, err)
800 }
801 if tt.err {
802 t.Errorf("%s: Expected error. Got nil", tt.str)
803 }
804
805 y1, err := yaml.Marshal(tt.expect)
806 if err != nil {
807 t.Fatal(err)
808 }
809 y2, err := yaml.Marshal(got)
810 if err != nil {
811 t.Fatalf("Error serializing parsed value: %s", err)
812 }
813
814 if string(y1) != string(y2) {
815 t.Errorf("%s: Expected:\n%s\nGot:\n%s", tt.str, y1, y2)
816 }
817 }
818 }
819
View as plain text