gomega icon indicating copy to clipboard operation
gomega copied to clipboard

DeepEqual comparison should tell you what's not equal

Open benmoss opened this issue 7 years ago • 19 comments

Right now when you use Expect(..).To(Equal(...)) and it uses go's DeepEqual function, it doesn't really help you find what is not equal. I just spent a bunch of time trying to figure out that an interface field was using a value type instead of a pointer.

Along the way I found https://godoc.org/github.com/juju/testing/checkers#DeepEqual, which is an alternate implementation of DeepEqual that actually will show you the differences. Would you consider a PR that changed gomega Equal to use this instead?

benmoss avatar Jun 06 '17 15:06 benmoss

@benmoss would that introduce a new, third-party dependency to Gomega? If so, I foresee this causing pain for consumers of this library.

Is it better to re-implement that logic inside gomega than pull in a dependency?

robdimsdale avatar Jun 06 '17 16:06 robdimsdale

+1 to reimplementing. This is dangerous territory... asserting equality can be tricky business in Go and relying on DeepEqual is a safe way to do so. Maintaining control over the code would be key.

onsi avatar Jun 06 '17 19:06 onsi

My response wasn't very clear. I would love to have improved diff identification in Gomega. I'd want the code that does equality to be:

  • a part of Gomega so we can be more responsive to issues
  • forked off of Golang's deep equal
  • super well-tested. I'd want to at least use Go's own tests as a starting point
  • in it's own package under Gomega so it can be used as a standalone thing

Does that make sense?

onsi avatar Jun 07 '17 12:06 onsi

Yup, I'm gonna try to work on this now!

benmoss avatar Jun 07 '17 21:06 benmoss

ok after looking at this for a lil bit it seems way too hard to reimplement, my reflect-fu is far too lacking

benmoss avatar Jun 07 '17 23:06 benmoss

I ended up making my own lib for this, in case anyone wants it: https://github.com/benmoss/matchers/

The burden of the criteria needed to be included in Gomega itself was just too high, so it's better to be a buyer-beware third party thing :).

benmoss avatar Jun 08 '17 17:06 benmoss

Did you ever consider to depend on https://github.com/google/go-cmp?

alculquicondor avatar Feb 28 '22 19:02 alculquicondor

hey go-cmp looks pretty good. I can imagine a Compare or BeComparableTo matcher that can accept go-cmp options and simply runs go-cmp in the background. I don't have a lot of bandwidth to work on that right now but would be open to a PR.

I hesitate to change the Equal matcher, though. Not without bumping the major version of Gomega...

onsi avatar Mar 14 '22 15:03 onsi

A separate comparer sounds good. We have set it up like this for now:

https://github.com/kubernetes-sigs/kueue/blob/main/pkg/util/testing/equal_cmp.go

alculquicondor avatar Mar 14 '22 15:03 alculquicondor

/reopen Edit: Oops, this doesn't work in this repo :)

alculquicondor avatar Mar 14 '22 15:03 alculquicondor

yes, exactly like that. I could also imagine a configurable flag on Gomega that would cause Equal to behave like go-cmp and so folks could try switching over more incrementally.

onsi avatar Mar 14 '22 18:03 onsi

Hey, the Gomega equality operation still fails on time comparison as @sedyh noted on https://github.com/onsi/gomega/issues/264#issuecomment-985317474. @onsi Might be another incentive to use the Google comparison package to fix this bug.

YuviGold avatar Mar 21 '22 17:03 YuviGold

I'm on board with moving in this direction - but I'm a bit underwater with other projects at the moment. If there's anyone with bandwidth and interest to work on a PR I'd be happy to talk through a design that would allow users to use go-cmp with a new matcher and optionally configure Gomega's Equal matcher (and anywhere that Gomega uses Equal under the hood for comparisons - e.g. ContainElement) to use go-cmp. I think that would give folks an onramp to switch to go-cmp.

onsi avatar Mar 25 '22 14:03 onsi

@xiantank just added BeComparableTo - it'll be in the next release of Gomega.

onsi avatar Apr 27 '22 02:04 onsi

@onsi I find the description of BeComparableTo to be quite confusing. Is it capable of deep comparison of two structs?

ilearnio avatar Oct 29 '22 00:10 ilearnio

Hey @ilearnio - which description are you referring to? The godocs are simply trying to say "this matcher uses gocmp.Equal to make comparisons."

onsi avatar Oct 29 '22 01:10 onsi

@onsi Yeah, I'm referring to that description. It took me a while to understand that gocmp is a separate go module (though it was something from gomega)

ilearnio avatar Oct 29 '22 03:10 ilearnio

Thanks @ilearnio - I've updated the docs to try and make it a bit clearer and pushed out a change.

onsi avatar Oct 29 '22 15:10 onsi

@onsi Awesome! Thanks a lot bro

ilearnio avatar Oct 30 '22 13:10 ilearnio