github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/legacy/helper/schema/field_reader_multi_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package schema 5 6 import ( 7 "reflect" 8 "strconv" 9 "testing" 10 11 "github.com/terramate-io/tf/legacy/terraform" 12 ) 13 14 func TestMultiLevelFieldReaderReadFieldExact(t *testing.T) { 15 cases := map[string]struct { 16 Addr []string 17 Readers []FieldReader 18 Level string 19 Result FieldReadResult 20 }{ 21 "specific": { 22 Addr: []string{"foo"}, 23 24 Readers: []FieldReader{ 25 &MapFieldReader{ 26 Schema: map[string]*Schema{ 27 "foo": &Schema{Type: TypeString}, 28 }, 29 Map: BasicMapReader(map[string]string{ 30 "foo": "bar", 31 }), 32 }, 33 &MapFieldReader{ 34 Schema: map[string]*Schema{ 35 "foo": &Schema{Type: TypeString}, 36 }, 37 Map: BasicMapReader(map[string]string{ 38 "foo": "baz", 39 }), 40 }, 41 &MapFieldReader{ 42 Schema: map[string]*Schema{ 43 "foo": &Schema{Type: TypeString}, 44 }, 45 Map: BasicMapReader(map[string]string{}), 46 }, 47 }, 48 49 Level: "1", 50 Result: FieldReadResult{ 51 Value: "baz", 52 Exists: true, 53 }, 54 }, 55 } 56 57 for name, tc := range cases { 58 readers := make(map[string]FieldReader) 59 levels := make([]string, len(tc.Readers)) 60 for i, r := range tc.Readers { 61 is := strconv.FormatInt(int64(i), 10) 62 readers[is] = r 63 levels[i] = is 64 } 65 66 r := &MultiLevelFieldReader{ 67 Readers: readers, 68 Levels: levels, 69 } 70 71 out, err := r.ReadFieldExact(tc.Addr, tc.Level) 72 if err != nil { 73 t.Fatalf("%s: err: %s", name, err) 74 } 75 76 if !reflect.DeepEqual(tc.Result, out) { 77 t.Fatalf("%s: bad: %#v", name, out) 78 } 79 } 80 } 81 82 func TestMultiLevelFieldReaderReadFieldMerge(t *testing.T) { 83 cases := map[string]struct { 84 Addr []string 85 Readers []FieldReader 86 Result FieldReadResult 87 }{ 88 "stringInDiff": { 89 Addr: []string{"availability_zone"}, 90 91 Readers: []FieldReader{ 92 &DiffFieldReader{ 93 Schema: map[string]*Schema{ 94 "availability_zone": &Schema{Type: TypeString}, 95 }, 96 97 Source: &MapFieldReader{ 98 Schema: map[string]*Schema{ 99 "availability_zone": &Schema{Type: TypeString}, 100 }, 101 Map: BasicMapReader(map[string]string{ 102 "availability_zone": "foo", 103 }), 104 }, 105 106 Diff: &terraform.InstanceDiff{ 107 Attributes: map[string]*terraform.ResourceAttrDiff{ 108 "availability_zone": &terraform.ResourceAttrDiff{ 109 Old: "foo", 110 New: "bar", 111 RequiresNew: true, 112 }, 113 }, 114 }, 115 }, 116 }, 117 118 Result: FieldReadResult{ 119 Value: "bar", 120 Exists: true, 121 }, 122 }, 123 124 "lastLevelComputed": { 125 Addr: []string{"availability_zone"}, 126 127 Readers: []FieldReader{ 128 &MapFieldReader{ 129 Schema: map[string]*Schema{ 130 "availability_zone": &Schema{Type: TypeString}, 131 }, 132 133 Map: BasicMapReader(map[string]string{ 134 "availability_zone": "foo", 135 }), 136 }, 137 138 &DiffFieldReader{ 139 Schema: map[string]*Schema{ 140 "availability_zone": &Schema{Type: TypeString}, 141 }, 142 143 Source: &MapFieldReader{ 144 Schema: map[string]*Schema{ 145 "availability_zone": &Schema{Type: TypeString}, 146 }, 147 148 Map: BasicMapReader(map[string]string{ 149 "availability_zone": "foo", 150 }), 151 }, 152 153 Diff: &terraform.InstanceDiff{ 154 Attributes: map[string]*terraform.ResourceAttrDiff{ 155 "availability_zone": &terraform.ResourceAttrDiff{ 156 Old: "foo", 157 New: "bar", 158 NewComputed: true, 159 }, 160 }, 161 }, 162 }, 163 }, 164 165 Result: FieldReadResult{ 166 Value: "", 167 Exists: true, 168 Computed: true, 169 }, 170 }, 171 172 "list of maps with removal in diff": { 173 Addr: []string{"config_vars"}, 174 175 Readers: []FieldReader{ 176 &DiffFieldReader{ 177 Schema: map[string]*Schema{ 178 "config_vars": &Schema{ 179 Type: TypeList, 180 Elem: &Schema{Type: TypeMap}, 181 }, 182 }, 183 184 Source: &MapFieldReader{ 185 Schema: map[string]*Schema{ 186 "config_vars": &Schema{ 187 Type: TypeList, 188 Elem: &Schema{Type: TypeMap}, 189 }, 190 }, 191 192 Map: BasicMapReader(map[string]string{ 193 "config_vars.#": "2", 194 "config_vars.0.foo": "bar", 195 "config_vars.0.bar": "bar", 196 "config_vars.1.bar": "baz", 197 }), 198 }, 199 200 Diff: &terraform.InstanceDiff{ 201 Attributes: map[string]*terraform.ResourceAttrDiff{ 202 "config_vars.0.bar": &terraform.ResourceAttrDiff{ 203 NewRemoved: true, 204 }, 205 }, 206 }, 207 }, 208 }, 209 210 Result: FieldReadResult{ 211 Value: []interface{}{ 212 map[string]interface{}{ 213 "foo": "bar", 214 }, 215 map[string]interface{}{ 216 "bar": "baz", 217 }, 218 }, 219 Exists: true, 220 }, 221 }, 222 223 "first level only": { 224 Addr: []string{"foo"}, 225 226 Readers: []FieldReader{ 227 &MapFieldReader{ 228 Schema: map[string]*Schema{ 229 "foo": &Schema{Type: TypeString}, 230 }, 231 Map: BasicMapReader(map[string]string{ 232 "foo": "bar", 233 }), 234 }, 235 &MapFieldReader{ 236 Schema: map[string]*Schema{ 237 "foo": &Schema{Type: TypeString}, 238 }, 239 Map: BasicMapReader(map[string]string{}), 240 }, 241 }, 242 243 Result: FieldReadResult{ 244 Value: "bar", 245 Exists: true, 246 }, 247 }, 248 } 249 250 for name, tc := range cases { 251 readers := make(map[string]FieldReader) 252 levels := make([]string, len(tc.Readers)) 253 for i, r := range tc.Readers { 254 is := strconv.FormatInt(int64(i), 10) 255 readers[is] = r 256 levels[i] = is 257 } 258 259 r := &MultiLevelFieldReader{ 260 Readers: readers, 261 Levels: levels, 262 } 263 264 out, err := r.ReadFieldMerge(tc.Addr, levels[len(levels)-1]) 265 if err != nil { 266 t.Fatalf("%s: err: %s", name, err) 267 } 268 269 if !reflect.DeepEqual(tc.Result, out) { 270 t.Fatalf("%s: bad: %#v", name, out) 271 } 272 } 273 }