github.com/Hashicorp/terraform@v0.11.12-beta1/helper/schema/field_reader_test.go (about) 1 package schema 2 3 import ( 4 "reflect" 5 "testing" 6 ) 7 8 func TestAddrToSchema(t *testing.T) { 9 cases := map[string]struct { 10 Addr []string 11 Schema map[string]*Schema 12 Result []ValueType 13 }{ 14 "full object": { 15 []string{}, 16 map[string]*Schema{ 17 "list": &Schema{ 18 Type: TypeList, 19 Elem: &Schema{Type: TypeInt}, 20 }, 21 }, 22 []ValueType{typeObject}, 23 }, 24 25 "list": { 26 []string{"list"}, 27 map[string]*Schema{ 28 "list": &Schema{ 29 Type: TypeList, 30 Elem: &Schema{Type: TypeInt}, 31 }, 32 }, 33 []ValueType{TypeList}, 34 }, 35 36 "list.#": { 37 []string{"list", "#"}, 38 map[string]*Schema{ 39 "list": &Schema{ 40 Type: TypeList, 41 Elem: &Schema{Type: TypeInt}, 42 }, 43 }, 44 []ValueType{TypeList, TypeInt}, 45 }, 46 47 "list.0": { 48 []string{"list", "0"}, 49 map[string]*Schema{ 50 "list": &Schema{ 51 Type: TypeList, 52 Elem: &Schema{Type: TypeInt}, 53 }, 54 }, 55 []ValueType{TypeList, TypeInt}, 56 }, 57 58 "list.0 with resource": { 59 []string{"list", "0"}, 60 map[string]*Schema{ 61 "list": &Schema{ 62 Type: TypeList, 63 Elem: &Resource{ 64 Schema: map[string]*Schema{ 65 "field": &Schema{Type: TypeString}, 66 }, 67 }, 68 }, 69 }, 70 []ValueType{TypeList, typeObject}, 71 }, 72 73 "list.0.field": { 74 []string{"list", "0", "field"}, 75 map[string]*Schema{ 76 "list": &Schema{ 77 Type: TypeList, 78 Elem: &Resource{ 79 Schema: map[string]*Schema{ 80 "field": &Schema{Type: TypeString}, 81 }, 82 }, 83 }, 84 }, 85 []ValueType{TypeList, typeObject, TypeString}, 86 }, 87 88 "set": { 89 []string{"set"}, 90 map[string]*Schema{ 91 "set": &Schema{ 92 Type: TypeSet, 93 Elem: &Schema{Type: TypeInt}, 94 Set: func(a interface{}) int { 95 return a.(int) 96 }, 97 }, 98 }, 99 []ValueType{TypeSet}, 100 }, 101 102 "set.#": { 103 []string{"set", "#"}, 104 map[string]*Schema{ 105 "set": &Schema{ 106 Type: TypeSet, 107 Elem: &Schema{Type: TypeInt}, 108 Set: func(a interface{}) int { 109 return a.(int) 110 }, 111 }, 112 }, 113 []ValueType{TypeSet, TypeInt}, 114 }, 115 116 "set.0": { 117 []string{"set", "0"}, 118 map[string]*Schema{ 119 "set": &Schema{ 120 Type: TypeSet, 121 Elem: &Schema{Type: TypeInt}, 122 Set: func(a interface{}) int { 123 return a.(int) 124 }, 125 }, 126 }, 127 []ValueType{TypeSet, TypeInt}, 128 }, 129 130 "set.0 with resource": { 131 []string{"set", "0"}, 132 map[string]*Schema{ 133 "set": &Schema{ 134 Type: TypeSet, 135 Elem: &Resource{ 136 Schema: map[string]*Schema{ 137 "field": &Schema{Type: TypeString}, 138 }, 139 }, 140 }, 141 }, 142 []ValueType{TypeSet, typeObject}, 143 }, 144 145 "mapElem": { 146 []string{"map", "foo"}, 147 map[string]*Schema{ 148 "map": &Schema{Type: TypeMap}, 149 }, 150 []ValueType{TypeMap, TypeString}, 151 }, 152 153 "setDeep": { 154 []string{"set", "50", "index"}, 155 map[string]*Schema{ 156 "set": &Schema{ 157 Type: TypeSet, 158 Elem: &Resource{ 159 Schema: map[string]*Schema{ 160 "index": &Schema{Type: TypeInt}, 161 "value": &Schema{Type: TypeString}, 162 }, 163 }, 164 Set: func(a interface{}) int { 165 return a.(map[string]interface{})["index"].(int) 166 }, 167 }, 168 }, 169 []ValueType{TypeSet, typeObject, TypeInt}, 170 }, 171 } 172 173 for name, tc := range cases { 174 result := addrToSchema(tc.Addr, tc.Schema) 175 types := make([]ValueType, len(result)) 176 for i, v := range result { 177 types[i] = v.Type 178 } 179 180 if !reflect.DeepEqual(types, tc.Result) { 181 t.Fatalf("%s: %#v", name, types) 182 } 183 } 184 } 185 186 // testFieldReader is a helper that should be used to verify that 187 // a FieldReader behaves properly in all the common cases. 188 func testFieldReader(t *testing.T, f func(map[string]*Schema) FieldReader) { 189 schema := map[string]*Schema{ 190 // Primitives 191 "bool": &Schema{Type: TypeBool}, 192 "float": &Schema{Type: TypeFloat}, 193 "int": &Schema{Type: TypeInt}, 194 "string": &Schema{Type: TypeString}, 195 196 // Lists 197 "list": &Schema{ 198 Type: TypeList, 199 Elem: &Schema{Type: TypeString}, 200 }, 201 "listInt": &Schema{ 202 Type: TypeList, 203 Elem: &Schema{Type: TypeInt}, 204 }, 205 "listMap": &Schema{ 206 Type: TypeList, 207 Elem: &Schema{ 208 Type: TypeMap, 209 }, 210 }, 211 212 // Maps 213 "map": &Schema{Type: TypeMap}, 214 "mapInt": &Schema{ 215 Type: TypeMap, 216 Elem: TypeInt, 217 }, 218 219 // This is used to verify that the type of a Map can be specified using the 220 // same syntax as for lists (as a nested *Schema passed to Elem) 221 "mapIntNestedSchema": &Schema{ 222 Type: TypeMap, 223 Elem: &Schema{Type: TypeInt}, 224 }, 225 "mapFloat": &Schema{ 226 Type: TypeMap, 227 Elem: TypeFloat, 228 }, 229 "mapBool": &Schema{ 230 Type: TypeMap, 231 Elem: TypeBool, 232 }, 233 234 // Sets 235 "set": &Schema{ 236 Type: TypeSet, 237 Elem: &Schema{Type: TypeInt}, 238 Set: func(a interface{}) int { 239 return a.(int) 240 }, 241 }, 242 "setDeep": &Schema{ 243 Type: TypeSet, 244 Elem: &Resource{ 245 Schema: map[string]*Schema{ 246 "index": &Schema{Type: TypeInt}, 247 "value": &Schema{Type: TypeString}, 248 }, 249 }, 250 Set: func(a interface{}) int { 251 return a.(map[string]interface{})["index"].(int) 252 }, 253 }, 254 "setEmpty": &Schema{ 255 Type: TypeSet, 256 Elem: &Schema{Type: TypeInt}, 257 Set: func(a interface{}) int { 258 return a.(int) 259 }, 260 }, 261 } 262 263 cases := map[string]struct { 264 Addr []string 265 Result FieldReadResult 266 Err bool 267 }{ 268 "noexist": { 269 []string{"boolNOPE"}, 270 FieldReadResult{ 271 Value: nil, 272 Exists: false, 273 Computed: false, 274 }, 275 false, 276 }, 277 278 "bool": { 279 []string{"bool"}, 280 FieldReadResult{ 281 Value: true, 282 Exists: true, 283 Computed: false, 284 }, 285 false, 286 }, 287 288 "float": { 289 []string{"float"}, 290 FieldReadResult{ 291 Value: 3.1415, 292 Exists: true, 293 Computed: false, 294 }, 295 false, 296 }, 297 298 "int": { 299 []string{"int"}, 300 FieldReadResult{ 301 Value: 42, 302 Exists: true, 303 Computed: false, 304 }, 305 false, 306 }, 307 308 "string": { 309 []string{"string"}, 310 FieldReadResult{ 311 Value: "string", 312 Exists: true, 313 Computed: false, 314 }, 315 false, 316 }, 317 318 "list": { 319 []string{"list"}, 320 FieldReadResult{ 321 Value: []interface{}{ 322 "foo", 323 "bar", 324 }, 325 Exists: true, 326 Computed: false, 327 }, 328 false, 329 }, 330 331 "listInt": { 332 []string{"listInt"}, 333 FieldReadResult{ 334 Value: []interface{}{ 335 21, 336 42, 337 }, 338 Exists: true, 339 Computed: false, 340 }, 341 false, 342 }, 343 344 "map": { 345 []string{"map"}, 346 FieldReadResult{ 347 Value: map[string]interface{}{ 348 "foo": "bar", 349 "bar": "baz", 350 }, 351 Exists: true, 352 Computed: false, 353 }, 354 false, 355 }, 356 357 "mapInt": { 358 []string{"mapInt"}, 359 FieldReadResult{ 360 Value: map[string]interface{}{ 361 "one": 1, 362 "two": 2, 363 }, 364 Exists: true, 365 Computed: false, 366 }, 367 false, 368 }, 369 370 "mapIntNestedSchema": { 371 []string{"mapIntNestedSchema"}, 372 FieldReadResult{ 373 Value: map[string]interface{}{ 374 "one": 1, 375 "two": 2, 376 }, 377 Exists: true, 378 Computed: false, 379 }, 380 false, 381 }, 382 383 "mapFloat": { 384 []string{"mapFloat"}, 385 FieldReadResult{ 386 Value: map[string]interface{}{ 387 "oneDotTwo": 1.2, 388 }, 389 Exists: true, 390 Computed: false, 391 }, 392 false, 393 }, 394 395 "mapBool": { 396 []string{"mapBool"}, 397 FieldReadResult{ 398 Value: map[string]interface{}{ 399 "True": true, 400 "False": false, 401 }, 402 Exists: true, 403 Computed: false, 404 }, 405 false, 406 }, 407 408 "mapelem": { 409 []string{"map", "foo"}, 410 FieldReadResult{ 411 Value: "bar", 412 Exists: true, 413 Computed: false, 414 }, 415 false, 416 }, 417 418 "set": { 419 []string{"set"}, 420 FieldReadResult{ 421 Value: []interface{}{10, 50}, 422 Exists: true, 423 Computed: false, 424 }, 425 false, 426 }, 427 428 "setDeep": { 429 []string{"setDeep"}, 430 FieldReadResult{ 431 Value: []interface{}{ 432 map[string]interface{}{ 433 "index": 10, 434 "value": "foo", 435 }, 436 map[string]interface{}{ 437 "index": 50, 438 "value": "bar", 439 }, 440 }, 441 Exists: true, 442 Computed: false, 443 }, 444 false, 445 }, 446 447 "setEmpty": { 448 []string{"setEmpty"}, 449 FieldReadResult{ 450 Value: []interface{}{}, 451 Exists: false, 452 }, 453 false, 454 }, 455 } 456 457 for name, tc := range cases { 458 r := f(schema) 459 out, err := r.ReadField(tc.Addr) 460 if err != nil != tc.Err { 461 t.Fatalf("%s: err: %s", name, err) 462 } 463 if s, ok := out.Value.(*Set); ok { 464 // If it is a set, convert to a list so its more easily checked. 465 out.Value = s.List() 466 } 467 if !reflect.DeepEqual(tc.Result, out) { 468 t.Fatalf("%s: bad: %#v", name, out) 469 } 470 } 471 }