Merge pull request #15819 from hashicorp/f-schema-set-hashequal

helper/schema: Add Set.HashEqual
This commit is contained in:
Chris Marchesi 2017-08-16 09:28:42 -07:00 committed by GitHub
commit 6ecf535ed9
2 changed files with 112 additions and 0 deletions

View File

@ -153,6 +153,31 @@ func (s *Set) Equal(raw interface{}) bool {
return reflect.DeepEqual(s.m, other.m)
}
// HashEqual simply checks to the keys the top-level map to the keys in the
// other set's top-level map to see if they are equal. This obviously assumes
// you have a properly working hash function - use HashResource if in doubt.
func (s *Set) HashEqual(raw interface{}) bool {
other, ok := raw.(*Set)
if !ok {
return false
}
ks1 := make([]string, 0)
ks2 := make([]string, 0)
for k := range s.m {
ks1 = append(ks1, k)
}
for k := range other.m {
ks2 = append(ks2, k)
}
sort.Strings(ks1)
sort.Strings(ks2)
return reflect.DeepEqual(ks1, ks2)
}
func (s *Set) GoString() string {
return fmt.Sprintf("*Set(%#v)", s.m)
}

View File

@ -128,3 +128,90 @@ func TestHashResource_nil(t *testing.T) {
t.Fatalf("Expected 0 when hashing nil, given: %d", idx)
}
}
func TestHashEqual(t *testing.T) {
nested := &Resource{
Schema: map[string]*Schema{
"foo": {
Type: TypeString,
Optional: true,
},
},
}
root := &Resource{
Schema: map[string]*Schema{
"bar": {
Type: TypeString,
Optional: true,
},
"nested": {
Type: TypeSet,
Optional: true,
Elem: nested,
},
},
}
n1 := map[string]interface{}{"foo": "bar"}
n2 := map[string]interface{}{"foo": "baz"}
r1 := map[string]interface{}{
"bar": "baz",
"nested": NewSet(HashResource(nested), []interface{}{n1}),
}
r2 := map[string]interface{}{
"bar": "qux",
"nested": NewSet(HashResource(nested), []interface{}{n2}),
}
r3 := map[string]interface{}{
"bar": "baz",
"nested": NewSet(HashResource(nested), []interface{}{n2}),
}
r4 := map[string]interface{}{
"bar": "qux",
"nested": NewSet(HashResource(nested), []interface{}{n1}),
}
s1 := NewSet(HashResource(root), []interface{}{r1})
s2 := NewSet(HashResource(root), []interface{}{r2})
s3 := NewSet(HashResource(root), []interface{}{r3})
s4 := NewSet(HashResource(root), []interface{}{r4})
cases := []struct {
name string
set *Set
compare *Set
expected bool
}{
{
name: "equal",
set: s1,
compare: s1,
expected: true,
},
{
name: "not equal",
set: s1,
compare: s2,
expected: false,
},
{
name: "outer equal, should still not be equal",
set: s1,
compare: s3,
expected: false,
},
{
name: "inner equal, should still not be equal",
set: s1,
compare: s4,
expected: false,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
actual := tc.set.HashEqual(tc.compare)
if tc.expected != actual {
t.Fatalf("expected %t, got %t", tc.expected, actual)
}
})
}
}