github.com/jpedro/terraform@v0.11.12-beta1/helper/variables/flag_any_test.go (about) 1 package variables 2 3 import ( 4 "flag" 5 "fmt" 6 "io/ioutil" 7 "reflect" 8 "testing" 9 10 "github.com/davecgh/go-spew/spew" 11 ) 12 13 func TestFlagAny_impl(t *testing.T) { 14 var _ flag.Value = new(FlagAny) 15 } 16 17 func TestFlagAny(t *testing.T) { 18 cases := []struct { 19 Input interface{} 20 Output map[string]interface{} 21 Error bool 22 }{ 23 { 24 "=value", 25 nil, 26 true, 27 }, 28 29 { 30 " =value", 31 nil, 32 true, 33 }, 34 35 { 36 "key=value", 37 map[string]interface{}{"key": "value"}, 38 false, 39 }, 40 41 { 42 "key=", 43 map[string]interface{}{"key": ""}, 44 false, 45 }, 46 47 { 48 "key=foo=bar", 49 map[string]interface{}{"key": "foo=bar"}, 50 false, 51 }, 52 53 { 54 "key=false", 55 map[string]interface{}{"key": "false"}, 56 false, 57 }, 58 59 { 60 "key =value", 61 map[string]interface{}{"key": "value"}, 62 false, 63 }, 64 65 { 66 "key = value", 67 map[string]interface{}{"key": " value"}, 68 false, 69 }, 70 71 { 72 `key = "value"`, 73 map[string]interface{}{"key": "value"}, 74 false, 75 }, 76 77 { 78 "map.key=foo", 79 map[string]interface{}{"map.key": "foo"}, 80 false, 81 }, 82 83 { 84 "key", 85 nil, 86 true, 87 }, 88 89 { 90 `key=["hello", "world"]`, 91 map[string]interface{}{"key": []interface{}{"hello", "world"}}, 92 false, 93 }, 94 95 { 96 `key={"hello" = "world", "foo" = "bar"}`, 97 map[string]interface{}{ 98 "key": map[string]interface{}{ 99 "hello": "world", 100 "foo": "bar", 101 }, 102 }, 103 false, 104 }, 105 106 { 107 `key={"hello" = "world", "foo" = "bar"}\nkey2="invalid"`, 108 nil, 109 true, 110 }, 111 112 { 113 "key=/path", 114 map[string]interface{}{"key": "/path"}, 115 false, 116 }, 117 118 { 119 "key=1234.dkr.ecr.us-east-1.amazonaws.com/proj:abcdef", 120 map[string]interface{}{"key": "1234.dkr.ecr.us-east-1.amazonaws.com/proj:abcdef"}, 121 false, 122 }, 123 124 // simple values that can parse as numbers should remain strings 125 { 126 "key=1", 127 map[string]interface{}{ 128 "key": "1", 129 }, 130 false, 131 }, 132 { 133 "key=1.0", 134 map[string]interface{}{ 135 "key": "1.0", 136 }, 137 false, 138 }, 139 { 140 "key=0x10", 141 map[string]interface{}{ 142 "key": "0x10", 143 }, 144 false, 145 }, 146 147 // Test setting multiple times 148 { 149 []string{ 150 "foo=bar", 151 "bar=baz", 152 }, 153 map[string]interface{}{ 154 "foo": "bar", 155 "bar": "baz", 156 }, 157 false, 158 }, 159 160 // Test map merging 161 { 162 []string{ 163 `foo={ foo = "bar" }`, 164 `foo={ bar = "baz" }`, 165 }, 166 map[string]interface{}{ 167 "foo": map[string]interface{}{ 168 "foo": "bar", 169 "bar": "baz", 170 }, 171 }, 172 false, 173 }, 174 } 175 176 for i, tc := range cases { 177 t.Run(fmt.Sprintf("%d-%s", i, tc.Input), func(t *testing.T) { 178 var input []string 179 switch v := tc.Input.(type) { 180 case string: 181 input = []string{v} 182 case []string: 183 input = v 184 default: 185 t.Fatalf("bad input type: %T", tc.Input) 186 } 187 188 f := new(FlagAny) 189 for i, single := range input { 190 err := f.Set(single) 191 192 // Only check for expected errors on the final input 193 expected := tc.Error && i == len(input)-1 194 if err != nil != expected { 195 t.Fatalf("bad error. Input: %#v\n\nError: %s", single, err) 196 } 197 } 198 199 actual := map[string]interface{}(*f) 200 if !reflect.DeepEqual(actual, tc.Output) { 201 t.Fatalf("bad:\nexpected: %s\n\n got: %s\n", spew.Sdump(tc.Output), spew.Sdump(actual)) 202 } 203 }) 204 } 205 } 206 207 func TestFlagAny_file(t *testing.T) { 208 inputLibucl := ` 209 foo = "bar" 210 ` 211 inputMap := ` 212 foo = { 213 k = "v" 214 }` 215 216 inputJson := `{ 217 "foo": "bar"}` 218 219 cases := []struct { 220 Input interface{} 221 Output map[string]interface{} 222 Error bool 223 }{ 224 { 225 inputLibucl, 226 map[string]interface{}{"foo": "bar"}, 227 false, 228 }, 229 230 { 231 inputJson, 232 map[string]interface{}{"foo": "bar"}, 233 false, 234 }, 235 236 { 237 `map.key = "foo"`, 238 map[string]interface{}{"map.key": "foo"}, 239 false, 240 }, 241 242 { 243 inputMap, 244 map[string]interface{}{ 245 "foo": map[string]interface{}{ 246 "k": "v", 247 }, 248 }, 249 false, 250 }, 251 252 { 253 []string{ 254 `foo = { "k" = "v"}`, 255 `foo = { "j" = "v" }`, 256 }, 257 map[string]interface{}{ 258 "foo": map[string]interface{}{ 259 "k": "v", 260 "j": "v", 261 }, 262 }, 263 false, 264 }, 265 } 266 267 path := testTempFile(t) 268 269 for i, tc := range cases { 270 t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { 271 var input []string 272 switch i := tc.Input.(type) { 273 case string: 274 input = []string{i} 275 case []string: 276 input = i 277 default: 278 t.Fatalf("bad input type: %T", i) 279 } 280 281 f := new(FlagAny) 282 for _, input := range input { 283 if err := ioutil.WriteFile(path, []byte(input), 0644); err != nil { 284 t.Fatalf("err: %s", err) 285 } 286 287 err := f.Set(path) 288 if err != nil != tc.Error { 289 t.Fatalf("bad error. Input: %#v, err: %s", input, err) 290 } 291 } 292 293 actual := map[string]interface{}(*f) 294 if !reflect.DeepEqual(actual, tc.Output) { 295 t.Fatalf("bad: %#v", actual) 296 } 297 }) 298 } 299 }