tests: replace godebug by go-cmp for structure diffs

go-cmp is stricter and allow to catch more problems. Moreover, the
output is a bit nicer.
This commit is contained in:
Vincent Bernat
2025-08-23 08:28:38 +02:00
parent 1a09ba9e7c
commit e2f1df9add
45 changed files with 852 additions and 710 deletions

View File

@@ -6,85 +6,28 @@
package helpers
import (
"fmt"
"net"
"net/netip"
"reflect"
"time"
"github.com/kylelemons/godebug/pretty"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
)
var prettyC = pretty.Config{
Diffable: true,
PrintStringers: false,
SkipZeroFields: true,
IncludeUnexported: false,
}
var diffCmpOptions cmp.Options
func formatByte(v any) string {
return fmt.Sprintf("0x%x", v)
}
func defaultPrettyFormatters() map[reflect.Type]any {
result := map[reflect.Type]any{
reflect.TypeOf(net.IP{}): fmt.Sprint,
reflect.TypeOf(netip.Addr{}): fmt.Sprint,
reflect.TypeOf(netip.Prefix{}): fmt.Sprint,
reflect.TypeOf(time.Time{}): fmt.Sprint,
reflect.TypeOf(SubnetMap[string]{}): fmt.Sprint,
reflect.TypeOf(SubnetMap[uint]{}): fmt.Sprint,
reflect.TypeOf(SubnetMap[uint16]{}): fmt.Sprint,
reflect.TypeOf(byte(0)): formatByte,
}
for t, fn := range nonDefaultPrettyFormatters {
result[t] = fn
}
return result
}
var nonDefaultPrettyFormatters = map[reflect.Type]any{}
// AddPrettyFormatter add a global pretty formatter. We cannot put everything in
// the default map due to cycles.
func AddPrettyFormatter(t reflect.Type, fn any) {
nonDefaultPrettyFormatters[t] = fn
}
// DiffOption changes the behavior of the Diff function.
type DiffOption struct {
kind int
// When this is a formatter
t reflect.Type
fn any
// RegisterCmpOption adds an option that will be used in all call to Diff().
func RegisterCmpOption(option cmp.Option) {
diffCmpOptions = append(diffCmpOptions, option)
}
// Diff return a diff of two objects. If no diff, an empty string is
// returned.
func Diff(a, b any, options ...DiffOption) string {
prettyC := prettyC
prettyC.Formatter = defaultPrettyFormatters()
for _, option := range options {
switch option.kind {
case DiffUnexported.kind:
prettyC.IncludeUnexported = true
case DiffZero.kind:
prettyC.SkipZeroFields = false
case DiffFormatter(nil, nil).kind:
prettyC.Formatter[option.t] = option.fn
}
}
return prettyC.Compare(a, b)
func Diff(a, b any, options ...cmp.Option) string {
options = append(options, diffCmpOptions...)
return cmp.Diff(a, b, options...)
}
var (
// DiffUnexported will display diff of unexported fields too.
DiffUnexported = DiffOption{kind: 1}
// DiffZero will include zero-field in diff
DiffZero = DiffOption{kind: 2}
)
// DiffFormatter adds a new formatter
func DiffFormatter(t reflect.Type, fn any) DiffOption {
return DiffOption{kind: 3, t: t, fn: fn}
func init() {
RegisterCmpOption(cmpopts.EquateComparable(netip.Addr{}))
RegisterCmpOption(cmpopts.EquateComparable(netip.Prefix{}))
RegisterCmpOption(cmpopts.EquateErrors())
}