Merge pull request #7091 from hashicorp/jbardin/serialize

Serialization for hash panics on TypeMap
This commit is contained in:
James Bardin 2016-06-09 16:16:41 -04:00
commit 2c7b702d1f
2 changed files with 44 additions and 3 deletions

View File

@ -2,6 +2,7 @@ package schema
import ( import (
"bytes" "bytes"
"fmt"
"sort" "sort"
"strconv" "strconv"
) )
@ -33,6 +34,7 @@ func SerializeValueForHash(buf *bytes.Buffer, val interface{}, schema *Schema) {
} }
buf.WriteRune(')') buf.WriteRune(')')
case TypeMap: case TypeMap:
m := val.(map[string]interface{}) m := val.(map[string]interface{})
var keys []string var keys []string
for k := range m { for k := range m {
@ -42,9 +44,24 @@ func SerializeValueForHash(buf *bytes.Buffer, val interface{}, schema *Schema) {
buf.WriteRune('[') buf.WriteRune('[')
for _, k := range keys { for _, k := range keys {
innerVal := m[k] innerVal := m[k]
if innerVal == nil {
continue
}
buf.WriteString(k) buf.WriteString(k)
buf.WriteRune(':') buf.WriteRune(':')
serializeCollectionMemberForHash(buf, innerVal, schema.Elem)
switch innerVal := innerVal.(type) {
case int:
buf.WriteString(strconv.Itoa(innerVal))
case float64:
buf.WriteString(strconv.FormatFloat(innerVal, 'g', -1, 64))
case string:
buf.WriteString(innerVal)
default:
panic(fmt.Sprintf("unknown value type in TypeMap %T", innerVal))
}
buf.WriteRune(';')
} }
buf.WriteRune(']') buf.WriteRune(']')
case TypeSet: case TypeSet:
@ -100,6 +117,6 @@ func serializeCollectionMemberForHash(buf *bytes.Buffer, val interface{}, elem i
SerializeResourceForHash(buf, val, tElem) SerializeResourceForHash(buf, val, tElem)
buf.WriteString(">;") buf.WriteString(">;")
default: default:
panic("invalid element type") panic(fmt.Sprintf("invalid element type: %T", tElem))
} }
} }

View File

@ -13,7 +13,6 @@ func TestSerializeForHash(t *testing.T) {
} }
tests := []testCase{ tests := []testCase{
testCase{ testCase{
Schema: &Schema{ Schema: &Schema{
Type: TypeInt, Type: TypeInt,
@ -193,6 +192,31 @@ func TestSerializeForHash(t *testing.T) {
}, },
Expected: "green:1;name:my-fun-database;size:12;", Expected: "green:1;name:my-fun-database;size:12;",
}, },
// test TypeMap nested in Schema: GH-7091
testCase{
Schema: &Resource{
Schema: map[string]*Schema{
"outer": &Schema{
Type: TypeSet,
Required: true,
Elem: &Schema{
Type: TypeMap,
Optional: true,
},
},
},
},
Value: map[string]interface{}{
"outer": NewSet(func(i interface{}) int { return 42 }, []interface{}{
map[string]interface{}{
"foo": "bar",
"baz": "foo",
},
}),
},
Expected: "outer:{[baz:foo;foo:bar;];};",
},
} }
for _, test := range tests { for _, test := range tests {