google / go-cmp

Package for comparing Go values in tests
BSD 3-Clause "New" or "Revised" License
4.08k stars 209 forks source link

Ignore all unexported fields #313

Open dprotaso opened 1 year ago

dprotaso commented 1 year ago

Is there a way to ignore all unexported fields?

I have a library where I do comparisons and I need a generic way to skip unexported fields. ie. protobuf types.

dsnet commented 1 year ago

For unexported fields, take a look at https://pkg.go.dev/github.com/google/go-cmp/cmp/cmpopts#IgnoreUnexported.

For protobuf types, I highly recommend using https://pkg.go.dev/google.golang.org/protobuf/testing/protocmp#Transform instead.

dprotaso commented 1 year ago

I was sorta hoping for

  1. Not needing to know the type (just a global option)
  2. Not needing to pull in a protobuf dependency to ignore unexported proto fields
dsnet commented 1 year ago
  1. Not needing to know the type (just a global option)

There's currently no ability to do that and it's unclear that it's a good idea to do that. Newly added fields that are actually semantically relevant may accidentally be ignored in the future just because all unexported fields are ignored.

You could build it yourself with:

opts := cmp.FilterPath(func(p cmp.Path) bool {
    sf, ok := p.Index(-1).(cmp.StructField)
    if !ok {
        return false
    }
    r, _ := utf8.DecodeRuneInString(sf.Name())
    return !unicode.IsUpper(r)
}, cmp.Ignore())
  1. Not needing to pull in a protobuf dependency to ignore unexported proto fields

If the program has a generated protobuf message, then it already depends on the protobuf module. If you're trying to build a general purpose comparison library on top of cmp, then you have to accept that being able to correctly compare all possible types is an impossible task. Option 1 is probably the best you can hope for.

burdiyan commented 1 year ago

@dsnet Thanks for the tip! I was also looking for a way to ignore unexpected fields recursively. Maybe worth adding this filter into the library, documenting the potential problems? Despite the issues I still find it very useful in many situations.