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  }