1/* 2Copyright 2017 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package flag 18 19import ( 20 "reflect" 21 "testing" 22) 23 24func TestStringMapStringBool(t *testing.T) { 25 var nilMap map[string]bool 26 cases := []struct { 27 desc string 28 m *MapStringBool 29 expect string 30 }{ 31 {"nil", NewMapStringBool(&nilMap), ""}, 32 {"empty", NewMapStringBool(&map[string]bool{}), ""}, 33 {"one key", NewMapStringBool(&map[string]bool{"one": true}), "one=true"}, 34 {"two keys", NewMapStringBool(&map[string]bool{"one": true, "two": false}), "one=true,two=false"}, 35 } 36 for _, c := range cases { 37 t.Run(c.desc, func(t *testing.T) { 38 str := c.m.String() 39 if c.expect != str { 40 t.Fatalf("expect %q but got %q", c.expect, str) 41 } 42 }) 43 } 44} 45 46func TestSetMapStringBool(t *testing.T) { 47 var nilMap map[string]bool 48 cases := []struct { 49 desc string 50 vals []string 51 start *MapStringBool 52 expect *MapStringBool 53 err string 54 }{ 55 // we initialize the map with a default key that should be cleared by Set 56 {"clears defaults", []string{""}, 57 NewMapStringBool(&map[string]bool{"default": true}), 58 &MapStringBool{ 59 initialized: true, 60 Map: &map[string]bool{}, 61 }, ""}, 62 // make sure we still allocate for "initialized" maps where Map was initially set to a nil map 63 {"allocates map if currently nil", []string{""}, 64 &MapStringBool{initialized: true, Map: &nilMap}, 65 &MapStringBool{ 66 initialized: true, 67 Map: &map[string]bool{}, 68 }, ""}, 69 // for most cases, we just reuse nilMap, which should be allocated by Set, and is reset before each test case 70 {"empty", []string{""}, 71 NewMapStringBool(&nilMap), 72 &MapStringBool{ 73 initialized: true, 74 Map: &map[string]bool{}, 75 }, ""}, 76 {"one key", []string{"one=true"}, 77 NewMapStringBool(&nilMap), 78 &MapStringBool{ 79 initialized: true, 80 Map: &map[string]bool{"one": true}, 81 }, ""}, 82 {"two keys", []string{"one=true,two=false"}, 83 NewMapStringBool(&nilMap), 84 &MapStringBool{ 85 initialized: true, 86 Map: &map[string]bool{"one": true, "two": false}, 87 }, ""}, 88 {"two keys, multiple Set invocations", []string{"one=true", "two=false"}, 89 NewMapStringBool(&nilMap), 90 &MapStringBool{ 91 initialized: true, 92 Map: &map[string]bool{"one": true, "two": false}, 93 }, ""}, 94 {"two keys with space", []string{"one=true, two=false"}, 95 NewMapStringBool(&nilMap), 96 &MapStringBool{ 97 initialized: true, 98 Map: &map[string]bool{"one": true, "two": false}, 99 }, ""}, 100 {"empty key", []string{"=true"}, 101 NewMapStringBool(&nilMap), 102 &MapStringBool{ 103 initialized: true, 104 Map: &map[string]bool{"": true}, 105 }, ""}, 106 {"missing value", []string{"one"}, 107 NewMapStringBool(&nilMap), 108 nil, 109 "malformed pair, expect string=bool"}, 110 {"non-boolean value", []string{"one=foo"}, 111 NewMapStringBool(&nilMap), 112 nil, 113 `invalid value of one: foo, err: strconv.ParseBool: parsing "foo": invalid syntax`}, 114 {"no target", []string{"one=true"}, 115 NewMapStringBool(nil), 116 nil, 117 "no target (nil pointer to map[string]bool)"}, 118 } 119 for _, c := range cases { 120 nilMap = nil 121 t.Run(c.desc, func(t *testing.T) { 122 var err error 123 for _, val := range c.vals { 124 err = c.start.Set(val) 125 if err != nil { 126 break 127 } 128 } 129 if c.err != "" { 130 if err == nil || err.Error() != c.err { 131 t.Fatalf("expect error %s but got %v", c.err, err) 132 } 133 return 134 } else if err != nil { 135 t.Fatalf("unexpected error: %v", err) 136 } 137 if !reflect.DeepEqual(c.expect, c.start) { 138 t.Fatalf("expect %#v but got %#v", c.expect, c.start) 139 } 140 }) 141 } 142} 143 144func TestEmptyMapStringBool(t *testing.T) { 145 var nilMap map[string]bool 146 cases := []struct { 147 desc string 148 val *MapStringBool 149 expect bool 150 }{ 151 {"nil", NewMapStringBool(&nilMap), true}, 152 {"empty", NewMapStringBool(&map[string]bool{}), true}, 153 {"populated", NewMapStringBool(&map[string]bool{"foo": true}), false}, 154 } 155 for _, c := range cases { 156 t.Run(c.desc, func(t *testing.T) { 157 result := c.val.Empty() 158 if result != c.expect { 159 t.Fatalf("expect %t but got %t", c.expect, result) 160 } 161 }) 162 } 163} 164