moduledeps: Module.Equals

Compares two modules for deep equality. This is primarily provided to
enable easy testing of code that constructs module tree structures.
This commit is contained in:
Martin Atkins 2017-04-20 18:15:04 -07:00
parent cfc08ae7e3
commit c20f25a10e
1 changed files with 61 additions and 0 deletions

View File

@ -133,3 +133,64 @@ func (m *Module) AllPluginRequirements() discovery.PluginRequirements {
})
return ret
}
// Equal returns true if the receiver is the root of an identical tree
// to the other given Module. This is a deep comparison that considers
// the equality of all downstream modules too.
//
// The children are considered to be ordered, so callers may wish to use
// SortDescendents first to normalize the order of the slices of child nodes.
//
// The implementation of this function is not optimized since it is provided
// primarily for use in tests.
func (m *Module) Equal(other *Module) bool {
// take care of nils first
if m == nil && other == nil {
return true
} else if (m == nil && other != nil) || (m != nil && other == nil) {
return false
}
if m.Name != other.Name {
return false
}
if len(m.Providers) != len(other.Providers) {
return false
}
if len(m.Children) != len(other.Children) {
return false
}
// Can't use reflect.DeepEqual on this provider structure because
// the nested VersionSet objects contain function pointers that
// never compare as equal. So we'll need to walk it the long way.
for inst, dep := range m.Providers {
if _, exists := other.Providers[inst]; !exists {
return false
}
if dep.Reason != other.Providers[inst].Reason {
return false
}
// VersionSets are not too easy to compare robustly, so
// we'll just use their string representations as a proxy
// for now.
if dep.Versions.String() != other.Providers[inst].Versions.String() {
return false
}
}
// Above we already checked that we have the same number of children
// in each module, so now we just need to check that they are
// recursively equal.
for i := range m.Children {
if !m.Children[i].Equal(other.Children[i]) {
return false
}
}
// If we fall out here then they are equal
return true
}