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  }