blob: 7410335f68dbfb7eb182f214f5698ad674898011 [file] [log] [blame]
package schema
import (
"reflect"
"strconv"
"testing"
"github.com/hashicorp/terraform/internal/legacy/terraform"
)
func TestMultiLevelFieldReaderReadFieldExact(t *testing.T) {
cases := map[string]struct {
Addr []string
Readers []FieldReader
Level string
Result FieldReadResult
}{
"specific": {
Addr: []string{"foo"},
Readers: []FieldReader{
&MapFieldReader{
Schema: map[string]*Schema{
"foo": &Schema{Type: TypeString},
},
Map: BasicMapReader(map[string]string{
"foo": "bar",
}),
},
&MapFieldReader{
Schema: map[string]*Schema{
"foo": &Schema{Type: TypeString},
},
Map: BasicMapReader(map[string]string{
"foo": "baz",
}),
},
&MapFieldReader{
Schema: map[string]*Schema{
"foo": &Schema{Type: TypeString},
},
Map: BasicMapReader(map[string]string{}),
},
},
Level: "1",
Result: FieldReadResult{
Value: "baz",
Exists: true,
},
},
}
for name, tc := range cases {
readers := make(map[string]FieldReader)
levels := make([]string, len(tc.Readers))
for i, r := range tc.Readers {
is := strconv.FormatInt(int64(i), 10)
readers[is] = r
levels[i] = is
}
r := &MultiLevelFieldReader{
Readers: readers,
Levels: levels,
}
out, err := r.ReadFieldExact(tc.Addr, tc.Level)
if err != nil {
t.Fatalf("%s: err: %s", name, err)
}
if !reflect.DeepEqual(tc.Result, out) {
t.Fatalf("%s: bad: %#v", name, out)
}
}
}
func TestMultiLevelFieldReaderReadFieldMerge(t *testing.T) {
cases := map[string]struct {
Addr []string
Readers []FieldReader
Result FieldReadResult
}{
"stringInDiff": {
Addr: []string{"availability_zone"},
Readers: []FieldReader{
&DiffFieldReader{
Schema: map[string]*Schema{
"availability_zone": &Schema{Type: TypeString},
},
Source: &MapFieldReader{
Schema: map[string]*Schema{
"availability_zone": &Schema{Type: TypeString},
},
Map: BasicMapReader(map[string]string{
"availability_zone": "foo",
}),
},
Diff: &terraform.InstanceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"availability_zone": &terraform.ResourceAttrDiff{
Old: "foo",
New: "bar",
RequiresNew: true,
},
},
},
},
},
Result: FieldReadResult{
Value: "bar",
Exists: true,
},
},
"lastLevelComputed": {
Addr: []string{"availability_zone"},
Readers: []FieldReader{
&MapFieldReader{
Schema: map[string]*Schema{
"availability_zone": &Schema{Type: TypeString},
},
Map: BasicMapReader(map[string]string{
"availability_zone": "foo",
}),
},
&DiffFieldReader{
Schema: map[string]*Schema{
"availability_zone": &Schema{Type: TypeString},
},
Source: &MapFieldReader{
Schema: map[string]*Schema{
"availability_zone": &Schema{Type: TypeString},
},
Map: BasicMapReader(map[string]string{
"availability_zone": "foo",
}),
},
Diff: &terraform.InstanceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"availability_zone": &terraform.ResourceAttrDiff{
Old: "foo",
New: "bar",
NewComputed: true,
},
},
},
},
},
Result: FieldReadResult{
Value: "",
Exists: true,
Computed: true,
},
},
"list of maps with removal in diff": {
Addr: []string{"config_vars"},
Readers: []FieldReader{
&DiffFieldReader{
Schema: map[string]*Schema{
"config_vars": &Schema{
Type: TypeList,
Elem: &Schema{Type: TypeMap},
},
},
Source: &MapFieldReader{
Schema: map[string]*Schema{
"config_vars": &Schema{
Type: TypeList,
Elem: &Schema{Type: TypeMap},
},
},
Map: BasicMapReader(map[string]string{
"config_vars.#": "2",
"config_vars.0.foo": "bar",
"config_vars.0.bar": "bar",
"config_vars.1.bar": "baz",
}),
},
Diff: &terraform.InstanceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"config_vars.0.bar": &terraform.ResourceAttrDiff{
NewRemoved: true,
},
},
},
},
},
Result: FieldReadResult{
Value: []interface{}{
map[string]interface{}{
"foo": "bar",
},
map[string]interface{}{
"bar": "baz",
},
},
Exists: true,
},
},
"first level only": {
Addr: []string{"foo"},
Readers: []FieldReader{
&MapFieldReader{
Schema: map[string]*Schema{
"foo": &Schema{Type: TypeString},
},
Map: BasicMapReader(map[string]string{
"foo": "bar",
}),
},
&MapFieldReader{
Schema: map[string]*Schema{
"foo": &Schema{Type: TypeString},
},
Map: BasicMapReader(map[string]string{}),
},
},
Result: FieldReadResult{
Value: "bar",
Exists: true,
},
},
}
for name, tc := range cases {
readers := make(map[string]FieldReader)
levels := make([]string, len(tc.Readers))
for i, r := range tc.Readers {
is := strconv.FormatInt(int64(i), 10)
readers[is] = r
levels[i] = is
}
r := &MultiLevelFieldReader{
Readers: readers,
Levels: levels,
}
out, err := r.ReadFieldMerge(tc.Addr, levels[len(levels)-1])
if err != nil {
t.Fatalf("%s: err: %s", name, err)
}
if !reflect.DeepEqual(tc.Result, out) {
t.Fatalf("%s: bad: %#v", name, out)
}
}
}