github.com/pmcatominey/terraform@v0.7.0-rc2.0.20160708105029-1401a52a5cc5/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 215 // Sets 216 "set": &Schema{ 217 Type: TypeSet, 218 Elem: &Schema{Type: TypeInt}, 219 Set: func(a interface{}) int { 220 return a.(int) 221 }, 222 }, 223 "setDeep": &Schema{ 224 Type: TypeSet, 225 Elem: &Resource{ 226 Schema: map[string]*Schema{ 227 "index": &Schema{Type: TypeInt}, 228 "value": &Schema{Type: TypeString}, 229 }, 230 }, 231 Set: func(a interface{}) int { 232 return a.(map[string]interface{})["index"].(int) 233 }, 234 }, 235 "setEmpty": &Schema{ 236 Type: TypeSet, 237 Elem: &Schema{Type: TypeInt}, 238 Set: func(a interface{}) int { 239 return a.(int) 240 }, 241 }, 242 } 243 244 cases := map[string]struct { 245 Addr []string 246 Result FieldReadResult 247 Err bool 248 }{ 249 "noexist": { 250 []string{"boolNOPE"}, 251 FieldReadResult{ 252 Value: nil, 253 Exists: false, 254 Computed: false, 255 }, 256 false, 257 }, 258 259 "bool": { 260 []string{"bool"}, 261 FieldReadResult{ 262 Value: true, 263 Exists: true, 264 Computed: false, 265 }, 266 false, 267 }, 268 269 "float": { 270 []string{"float"}, 271 FieldReadResult{ 272 Value: 3.1415, 273 Exists: true, 274 Computed: false, 275 }, 276 false, 277 }, 278 279 "int": { 280 []string{"int"}, 281 FieldReadResult{ 282 Value: 42, 283 Exists: true, 284 Computed: false, 285 }, 286 false, 287 }, 288 289 "string": { 290 []string{"string"}, 291 FieldReadResult{ 292 Value: "string", 293 Exists: true, 294 Computed: false, 295 }, 296 false, 297 }, 298 299 "list": { 300 []string{"list"}, 301 FieldReadResult{ 302 Value: []interface{}{ 303 "foo", 304 "bar", 305 }, 306 Exists: true, 307 Computed: false, 308 }, 309 false, 310 }, 311 312 "listInt": { 313 []string{"listInt"}, 314 FieldReadResult{ 315 Value: []interface{}{ 316 21, 317 42, 318 }, 319 Exists: true, 320 Computed: false, 321 }, 322 false, 323 }, 324 325 "map": { 326 []string{"map"}, 327 FieldReadResult{ 328 Value: map[string]interface{}{ 329 "foo": "bar", 330 "bar": "baz", 331 }, 332 Exists: true, 333 Computed: false, 334 }, 335 false, 336 }, 337 338 "mapelem": { 339 []string{"map", "foo"}, 340 FieldReadResult{ 341 Value: "bar", 342 Exists: true, 343 Computed: false, 344 }, 345 false, 346 }, 347 348 "set": { 349 []string{"set"}, 350 FieldReadResult{ 351 Value: []interface{}{10, 50}, 352 Exists: true, 353 Computed: false, 354 }, 355 false, 356 }, 357 358 "setDeep": { 359 []string{"setDeep"}, 360 FieldReadResult{ 361 Value: []interface{}{ 362 map[string]interface{}{ 363 "index": 10, 364 "value": "foo", 365 }, 366 map[string]interface{}{ 367 "index": 50, 368 "value": "bar", 369 }, 370 }, 371 Exists: true, 372 Computed: false, 373 }, 374 false, 375 }, 376 377 "setEmpty": { 378 []string{"setEmpty"}, 379 FieldReadResult{ 380 Value: []interface{}{}, 381 Exists: false, 382 }, 383 false, 384 }, 385 } 386 387 for name, tc := range cases { 388 r := f(schema) 389 out, err := r.ReadField(tc.Addr) 390 if err != nil != tc.Err { 391 t.Fatalf("%s: err: %s", name, err) 392 } 393 if s, ok := out.Value.(*Set); ok { 394 // If it is a set, convert to a list so its more easily checked. 395 out.Value = s.List() 396 } 397 if !reflect.DeepEqual(tc.Result, out) { 398 t.Fatalf("%s: bad: %#v", name, out) 399 } 400 } 401 }