in processor/lsmintervalprocessor/internal/data/datatest/equal.go [75:149]
func equal(tb testing.TB, want, got any, name string) bool {
tb.Helper()
require.IsType(tb, want, got)
vw := reflect.ValueOf(want)
vg := reflect.ValueOf(got)
if vw.Kind() != reflect.Struct {
ok := compare.Equal(want, got)
if !ok {
tb.Errorf("%s: %+v != %+v", name, want, got)
}
return ok
}
ok := true
// compare all "getters" of the struct
for i := 0; i < vw.NumMethod(); i++ {
mname := vw.Type().Method(i).Name
fname := strings.TrimPrefix(name+"."+mname+"()", ".")
mw := vw.Method(i)
mg := vg.Method(i)
// only compare "getters"
if mw.Type().NumIn() != 0 || mw.Type().NumOut() != 1 {
continue
}
// skip equality check for methods returning functions
ret := mw.Type().Out(0)
if ret.Kind() == reflect.Func {
continue
}
// Append(Empty) fails above heuristic, exclude it
if strings.HasPrefix(mname, "Append") || strings.HasPrefix(mname, "Clone") {
continue
}
rw := mw.Call(nil)[0].Interface()
rg := mg.Call(nil)[0].Interface()
ok = equal(tb, rw, rg, fname) && ok
}
// compare all exported fields of the struct
for i := 0; i < vw.NumField(); i++ {
if !vw.Type().Field(i).IsExported() {
continue
}
fname := name + "." + vw.Type().Field(i).Name
fw := vw.Field(i).Interface()
fg := vg.Field(i).Interface()
ok = equal(tb, fw, fg, fname) && ok
}
if !ok {
return false
}
if _, ok := want.(expo.DataPoint); ok {
err := pmetrictest.CompareExponentialHistogramDataPoint(want.(expo.DataPoint), got.(expo.DataPoint))
if err != nil {
tb.Error(err)
}
}
// fallback to a full deep-equal for rare cases (unexported fields, etc)
if diff := compare.Diff(want, got); diff != "" {
tb.Error(diff)
return false
}
return true
}