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  }