cleanup: helper funcs for comparing slices of references

This commit is contained in:
Seth Hoenig 2022-08-13 09:13:54 -05:00
parent 0c3cfb073a
commit 47f5452825
3 changed files with 64 additions and 14 deletions

View file

@ -735,3 +735,27 @@ func IsMethodHTTP(s string) bool {
}
return true
}
// EqualsFunc represents a type implementing the Equals method.
type EqualsFunc[A any] interface {
Equals(A) bool
}
// ElementsEquals returns true if slices a and b contain the same elements (in
// no particular order) using the Equals function defined on their type for
// comparison.
func ElementsEquals[T EqualsFunc[T]](a, b []T) bool {
if len(a) != len(b) {
return false
}
OUTER:
for _, item := range a {
for _, other := range b {
if item.Equals(other) {
continue OUTER
}
}
return false
}
return true
}

View file

@ -574,3 +574,42 @@ func Test_IsMethodHTTP(t *testing.T) {
}
})
}
type employee struct {
id int
name string
}
func (e *employee) Equals(o *employee) bool {
return e.id == o.id // name can be different
}
func Test_ElementsEquals(t *testing.T) {
t.Run("empty", func(t *testing.T) {
a := []*employee(nil)
var b []*employee
must.True(t, ElementsEquals(a, b))
must.True(t, ElementsEquals(b, a))
})
t.Run("different sizes", func(t *testing.T) {
a := []*employee{{1, "mitchell"}, {2, "armon"}, {3, "jack"}}
b := []*employee{{1, "mitchell"}, {2, "armon"}}
must.False(t, ElementsEquals(a, b))
must.False(t, ElementsEquals(b, a))
})
t.Run("equal", func(t *testing.T) {
a := []*employee{{1, "mitchell"}, {2, "armon"}, {3, "jack"}}
b := []*employee{{1, "M.H."}, {2, "A.D."}, {3, "J.P."}}
must.True(t, ElementsEquals(a, b))
must.True(t, ElementsEquals(b, a))
})
t.Run("different", func(t *testing.T) {
a := []*employee{{1, "mitchell"}, {2, "armon"}, {3, "jack"}}
b := []*employee{{0, "mitchell."}, {2, "armon"}, {3, "jack"}}
must.False(t, ElementsEquals(a, b))
must.False(t, ElementsEquals(b, a))
})
}

View file

@ -905,20 +905,7 @@ func (s *Service) Equals(o *Service) bool {
return false
}
if len(s.Checks) != len(o.Checks) {
return false
}
OUTER:
for i := range s.Checks {
for ii := range o.Checks {
if s.Checks[i].Equals(o.Checks[ii]) {
// Found match; continue with next check
continue OUTER
}
}
// No match
if !helper.ElementsEquals(s.Checks, o.Checks) {
return false
}