...

Source file src/k8s.io/component-base/cli/flag/colon_separated_multimap_string_string_test.go

Documentation: k8s.io/component-base/cli/flag

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package flag
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  )
    23  
    24  func TestStringColonSeparatedMultimapStringString(t *testing.T) {
    25  	var nilMap map[string][]string
    26  	cases := []struct {
    27  		desc   string
    28  		m      *ColonSeparatedMultimapStringString
    29  		expect string
    30  	}{
    31  		{"nil", NewColonSeparatedMultimapStringString(&nilMap), ""},
    32  		{"empty", NewColonSeparatedMultimapStringString(&map[string][]string{}), ""},
    33  		{"empty key", NewColonSeparatedMultimapStringString(
    34  			&map[string][]string{
    35  				"": {"foo"},
    36  			}),
    37  			":foo"},
    38  		{"one key", NewColonSeparatedMultimapStringString(
    39  			&map[string][]string{
    40  				"one": {"foo"},
    41  			}),
    42  			"one:foo"},
    43  		{"two keys", NewColonSeparatedMultimapStringString(
    44  			&map[string][]string{
    45  				"one": {"foo"},
    46  				"two": {"bar"},
    47  			}),
    48  			"one:foo,two:bar"},
    49  		{"two keys, multiple items in one key", NewColonSeparatedMultimapStringString(
    50  			&map[string][]string{
    51  				"one": {"foo", "baz"},
    52  				"two": {"bar"},
    53  			}),
    54  			"one:foo,one:baz,two:bar"},
    55  		{"three keys, multiple items in one key", NewColonSeparatedMultimapStringString(
    56  			&map[string][]string{
    57  				"a": {"hello"},
    58  				"b": {"again", "beautiful"},
    59  				"c": {"world"},
    60  			}),
    61  			"a:hello,b:again,b:beautiful,c:world"},
    62  	}
    63  	for _, c := range cases {
    64  		t.Run(c.desc, func(t *testing.T) {
    65  			str := c.m.String()
    66  			if c.expect != str {
    67  				t.Fatalf("expect %q but got %q", c.expect, str)
    68  			}
    69  		})
    70  	}
    71  }
    72  
    73  func TestSetColonSeparatedMultimapStringString(t *testing.T) {
    74  	var nilMap map[string][]string
    75  	cases := []struct {
    76  		desc   string
    77  		vals   []string
    78  		start  *ColonSeparatedMultimapStringString
    79  		expect *ColonSeparatedMultimapStringString
    80  		err    string
    81  	}{
    82  		// we initialize the map with a default key that should be cleared by Set
    83  		{"clears defaults", []string{""},
    84  			NewColonSeparatedMultimapStringString(&map[string][]string{"default": {}}),
    85  			&ColonSeparatedMultimapStringString{
    86  				initialized: true,
    87  				Multimap:    &map[string][]string{}}, ""},
    88  		// make sure we still allocate for "initialized" multimaps where Multimap was initially set to a nil map
    89  		{"allocates map if currently nil", []string{""},
    90  			&ColonSeparatedMultimapStringString{initialized: true, Multimap: &nilMap},
    91  			&ColonSeparatedMultimapStringString{
    92  				initialized: true,
    93  				Multimap:    &map[string][]string{},
    94  			}, ""},
    95  		// for most cases, we just reuse nilMap, which should be allocated by Set, and is reset before each test case
    96  		{"empty", []string{""},
    97  			NewColonSeparatedMultimapStringString(&nilMap),
    98  			&ColonSeparatedMultimapStringString{
    99  				initialized: true,
   100  				Multimap:    &map[string][]string{}}, ""},
   101  		{"empty key", []string{":foo"},
   102  			NewColonSeparatedMultimapStringString(&nilMap),
   103  			&ColonSeparatedMultimapStringString{
   104  				initialized: true,
   105  				Multimap: &map[string][]string{
   106  					"": {"foo"},
   107  				}}, ""},
   108  		{"one key", []string{"one:foo"},
   109  			NewColonSeparatedMultimapStringString(&nilMap),
   110  			&ColonSeparatedMultimapStringString{
   111  				initialized: true,
   112  				Multimap: &map[string][]string{
   113  					"one": {"foo"},
   114  				}}, ""},
   115  		{"two keys", []string{"one:foo,two:bar"},
   116  			NewColonSeparatedMultimapStringString(&nilMap),
   117  			&ColonSeparatedMultimapStringString{
   118  				initialized: true,
   119  				Multimap: &map[string][]string{
   120  					"one": {"foo"},
   121  					"two": {"bar"},
   122  				}}, ""},
   123  		{"two keys with space", []string{"one:foo, two:bar"},
   124  			NewColonSeparatedMultimapStringString(&nilMap),
   125  			&ColonSeparatedMultimapStringString{
   126  				initialized: true,
   127  				Multimap: &map[string][]string{
   128  					"one": {"foo"},
   129  					"two": {"bar"},
   130  				}}, ""},
   131  		{"two keys, multiple items in one key", []string{"one: foo, two:bar, one:baz"},
   132  			NewColonSeparatedMultimapStringString(&nilMap),
   133  			&ColonSeparatedMultimapStringString{
   134  				initialized: true,
   135  				Multimap: &map[string][]string{
   136  					"one": {"foo", "baz"},
   137  					"two": {"bar"},
   138  				}}, ""},
   139  		{"three keys, multiple items in one key", []string{"a:hello,b:again,c:world,b:beautiful"},
   140  			NewColonSeparatedMultimapStringString(&nilMap),
   141  			&ColonSeparatedMultimapStringString{
   142  				initialized: true,
   143  				Multimap: &map[string][]string{
   144  					"a": {"hello"},
   145  					"b": {"again", "beautiful"},
   146  					"c": {"world"},
   147  				}}, ""},
   148  		{"three keys, multiple items in one key, multiple Set invocations", []string{"a:hello,b:again", "c:world", "b:beautiful"},
   149  			NewColonSeparatedMultimapStringString(&nilMap),
   150  			&ColonSeparatedMultimapStringString{
   151  				initialized: true,
   152  				Multimap: &map[string][]string{
   153  					"a": {"hello"},
   154  					"b": {"again", "beautiful"},
   155  					"c": {"world"},
   156  				}}, ""},
   157  		{"missing value", []string{"a"},
   158  			NewColonSeparatedMultimapStringString(&nilMap),
   159  			nil,
   160  			"malformed pair, expect string:string"},
   161  		{"no target", []string{"a:foo"},
   162  			NewColonSeparatedMultimapStringString(nil),
   163  			nil,
   164  			"no target (nil pointer to map[string][]string)"},
   165  	}
   166  
   167  	for _, c := range cases {
   168  		nilMap = nil
   169  		t.Run(c.desc, func(t *testing.T) {
   170  			var err error
   171  			for _, val := range c.vals {
   172  				err = c.start.Set(val)
   173  				if err != nil {
   174  					break
   175  				}
   176  			}
   177  			if c.err != "" {
   178  				if err == nil || err.Error() != c.err {
   179  					t.Fatalf("expect error %s but got %v", c.err, err)
   180  				}
   181  				return
   182  			} else if err != nil {
   183  				t.Fatalf("unexpected error: %v", err)
   184  			}
   185  			if !reflect.DeepEqual(c.expect, c.start) {
   186  				t.Fatalf("expect %#v but got %#v", c.expect, c.start)
   187  			}
   188  		})
   189  	}
   190  }
   191  
   192  func TestRoundTripColonSeparatedMultimapStringString(t *testing.T) {
   193  	cases := []struct {
   194  		desc   string
   195  		vals   []string
   196  		expect string
   197  	}{
   198  		{"empty", []string{""}, ""},
   199  		{"empty key", []string{":foo"}, ":foo"},
   200  		{"one key", []string{"one:foo"}, "one:foo"},
   201  		{"two keys", []string{"one:foo,two:bar"}, "one:foo,two:bar"},
   202  		{"two keys, multiple items in one key", []string{"one:foo, two:bar, one:baz"}, "one:foo,one:baz,two:bar"},
   203  		{"three keys, multiple items in one key", []string{"a:hello,b:again,c:world,b:beautiful"}, "a:hello,b:again,b:beautiful,c:world"},
   204  		{"three keys, multiple items in one key, multiple Set invocations", []string{"a:hello,b:again", "c:world", "b:beautiful"}, "a:hello,b:again,b:beautiful,c:world"},
   205  	}
   206  
   207  	for _, c := range cases {
   208  		t.Run(c.desc, func(t *testing.T) {
   209  			m := NewColonSeparatedMultimapStringString(&map[string][]string{})
   210  			for _, val := range c.vals {
   211  				if err := m.Set(val); err != nil {
   212  					t.Fatalf("unexpected error: %v", err)
   213  				}
   214  			}
   215  			str := m.String()
   216  			if c.expect != str {
   217  				t.Fatalf("expect %q but got %q", c.expect, str)
   218  			}
   219  		})
   220  	}
   221  }
   222  
   223  func TestEmptyColonSeparatedMultimapStringString(t *testing.T) {
   224  	var nilMap map[string][]string
   225  	cases := []struct {
   226  		desc   string
   227  		val    *ColonSeparatedMultimapStringString
   228  		expect bool
   229  	}{
   230  		{"nil", NewColonSeparatedMultimapStringString(&nilMap), true},
   231  		{"empty", NewColonSeparatedMultimapStringString(&map[string][]string{}), true},
   232  		{"populated", NewColonSeparatedMultimapStringString(&map[string][]string{"foo": {}}), false},
   233  	}
   234  	for _, c := range cases {
   235  		t.Run(c.desc, func(t *testing.T) {
   236  			result := c.val.Empty()
   237  			if result != c.expect {
   238  				t.Fatalf("expect %t but got %t", c.expect, result)
   239  			}
   240  		})
   241  	}
   242  }
   243  

View as plain text