From c20f25a10efacc816e620ad8c5039ebc76462a42 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Thu, 20 Apr 2017 18:15:04 -0700 Subject: [PATCH] moduledeps: Module.Equals Compares two modules for deep equality. This is primarily provided to enable easy testing of code that constructs module tree structures. --- moduledeps/module.go | 61 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/moduledeps/module.go b/moduledeps/module.go index 5c11f35f5..f54f06bfc 100644 --- a/moduledeps/module.go +++ b/moduledeps/module.go @@ -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 +}