Merge pull request #993 from hashicorp/b-getok

helper/schema: change GetOk semantics to mean non-zero
This commit is contained in:
Mitchell Hashimoto 2015-02-17 17:46:02 -08:00
commit 2edd7a4009
5 changed files with 68 additions and 29 deletions

View File

@ -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
}

View File

@ -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 {

View File

@ -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))
}
}

View File

@ -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 {

View File

@ -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.