terraform: Diff.Equal and tests

This commit is contained in:
Mitchell Hashimoto 2016-10-09 10:18:38 +08:00
parent 30596ca371
commit 31f8d13678
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
2 changed files with 81 additions and 0 deletions

View File

@ -81,6 +81,25 @@ func (d *Diff) Empty() bool {
return true
}
// Equal compares two diffs for exact equality.
//
// This is different from the Same comparison that is supported which
// checks for operation equality taking into account computed values. Equal
// instead checks for exact equality.
func (d *Diff) Equal(d2 *Diff) bool {
// If one is nil, they must both be nil
if d == nil || d2 == nil {
return d == d2
}
// Sort the modules
sort.Sort(moduleDiffSort(d.Modules))
sort.Sort(moduleDiffSort(d2.Modules))
// Use DeepEqual
return reflect.DeepEqual(d, d2)
}
// DeepCopy performs a deep copy of all parts of the Diff, making the
// resulting Diff safe to use without modifying this one.
func (d *Diff) DeepCopy() *Diff {
@ -659,3 +678,21 @@ func (d *InstanceDiff) Same(d2 *InstanceDiff) (bool, string) {
return true, ""
}
// moduleDiffSort implements sort.Interface to sort module diffs by path.
type moduleDiffSort []*ModuleDiff
func (s moduleDiffSort) Len() int { return len(s) }
func (s moduleDiffSort) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s moduleDiffSort) Less(i, j int) bool {
a := s[i]
b := s[j]
// If the lengths are different, then the shorter one always wins
if len(a.Path) != len(b.Path) {
return len(a.Path) < len(b.Path)
}
// Otherwise, compare lexically
return strings.Join(a.Path, ".") < strings.Join(b.Path, ".")
}

View File

@ -40,6 +40,50 @@ func TestDiffEmpty_taintedIsNotEmpty(t *testing.T) {
}
}
func TestDiffEqual(t *testing.T) {
cases := map[string]struct {
D1, D2 *Diff
Equal bool
}{
"nil": {
nil,
new(Diff),
false,
},
"empty": {
new(Diff),
new(Diff),
true,
},
"different module order": {
&Diff{
Modules: []*ModuleDiff{
&ModuleDiff{Path: []string{"root", "foo"}},
&ModuleDiff{Path: []string{"root", "bar"}},
},
},
&Diff{
Modules: []*ModuleDiff{
&ModuleDiff{Path: []string{"root", "bar"}},
&ModuleDiff{Path: []string{"root", "foo"}},
},
},
true,
},
}
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
actual := tc.D1.Equal(tc.D2)
if actual != tc.Equal {
t.Fatalf("expected: %v\n\n%#v\n\n%#v", tc.Equal, tc.D1, tc.D2)
}
})
}
}
func TestModuleDiff_ChangeType(t *testing.T) {
cases := []struct {
Diff *ModuleDiff