Merge pull request #993 from hashicorp/b-getok
helper/schema: change GetOk semantics to mean non-zero
This commit is contained in:
commit
2edd7a4009
|
@ -77,6 +77,18 @@ func (d *ResourceData) GetChange(key string) (interface{}, interface{}) {
|
|||
func (d *ResourceData) GetOk(key string) (interface{}, bool) {
|
||||
r := d.getRaw(key, getSourceSet)
|
||||
exists := r.Exists && !r.Computed
|
||||
if exists {
|
||||
// If it exists, we also want to verify it is not the zero-value.
|
||||
value := r.Value
|
||||
zero := r.Schema.Type.Zero()
|
||||
|
||||
if eq, ok := value.(Equal); ok {
|
||||
exists = !eq.Equal(zero)
|
||||
} else {
|
||||
exists = !reflect.DeepEqual(value, zero)
|
||||
}
|
||||
}
|
||||
|
||||
return r.Value, exists
|
||||
}
|
||||
|
||||
|
|
|
@ -828,7 +828,7 @@ func TestResourceDataGetOk(t *testing.T) {
|
|||
|
||||
Key: "availability_zone",
|
||||
Value: "",
|
||||
Ok: true,
|
||||
Ok: false,
|
||||
},
|
||||
|
||||
{
|
||||
|
@ -961,6 +961,32 @@ func TestResourceDataGetOk(t *testing.T) {
|
|||
Value: 0,
|
||||
Ok: false,
|
||||
},
|
||||
|
||||
{
|
||||
Schema: map[string]*Schema{
|
||||
"ports": &Schema{
|
||||
Type: TypeSet,
|
||||
Optional: true,
|
||||
Elem: &Schema{Type: TypeInt},
|
||||
Set: func(a interface{}) int { return a.(int) },
|
||||
},
|
||||
},
|
||||
|
||||
State: nil,
|
||||
|
||||
Diff: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"ports.#": &terraform.ResourceAttrDiff{
|
||||
Old: "0",
|
||||
New: "0",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Key: "ports",
|
||||
Value: []interface{}{},
|
||||
Ok: false,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
|
|
|
@ -1084,3 +1084,29 @@ func (m schemaMap) validateType(
|
|||
return m.validatePrimitive(k, raw, schema, c)
|
||||
}
|
||||
}
|
||||
|
||||
// Zero returns the zero value for a type.
|
||||
func (t ValueType) Zero() interface{} {
|
||||
switch t {
|
||||
case TypeInvalid:
|
||||
return nil
|
||||
case TypeBool:
|
||||
return false
|
||||
case TypeInt:
|
||||
return 0
|
||||
case TypeFloat:
|
||||
return 0.0
|
||||
case TypeString:
|
||||
return ""
|
||||
case TypeList:
|
||||
return []interface{}{}
|
||||
case TypeMap:
|
||||
return map[string]interface{}{}
|
||||
case TypeSet:
|
||||
return new(Set)
|
||||
case typeObject:
|
||||
return map[string]interface{}{}
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown type %s", t))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ func TestValueType_Zero(t *testing.T) {
|
|||
{TypeString, ""},
|
||||
{TypeList, []interface{}{}},
|
||||
{TypeMap, map[string]interface{}{}},
|
||||
{TypeSet, nil},
|
||||
{TypeSet, new(Set)},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
|
|
|
@ -2,8 +2,6 @@ package schema
|
|||
|
||||
//go:generate stringer -type=ValueType valuetype.go
|
||||
|
||||
import "fmt"
|
||||
|
||||
// ValueType is an enum of the type that can be represented by a schema.
|
||||
type ValueType int
|
||||
|
||||
|
@ -19,28 +17,5 @@ const (
|
|||
typeObject
|
||||
)
|
||||
|
||||
// Zero returns the zero value for a type.
|
||||
func (t ValueType) Zero() interface{} {
|
||||
switch t {
|
||||
case TypeInvalid:
|
||||
return nil
|
||||
case TypeBool:
|
||||
return false
|
||||
case TypeInt:
|
||||
return 0
|
||||
case TypeFloat:
|
||||
return 0.0
|
||||
case TypeString:
|
||||
return ""
|
||||
case TypeList:
|
||||
return []interface{}{}
|
||||
case TypeMap:
|
||||
return map[string]interface{}{}
|
||||
case TypeSet:
|
||||
return nil
|
||||
case typeObject:
|
||||
return map[string]interface{}{}
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown type %s", t))
|
||||
}
|
||||
}
|
||||
// NOTE: ValueType has more functions defined on it in schema.go. We can't
|
||||
// put them here because we reference other files.
|
||||
|
|
Loading…
Reference in New Issue