onsi / gomega

Ginkgo's Preferred Matcher Library
http://onsi.github.io/gomega/
MIT License
2.13k stars 282 forks source link

Slice comparison matchers like `HaveExactElements` with a custom matcher #724

Open michaelbeaumont opened 6 months ago

michaelbeaumont commented 6 months ago

Probably I'm missing something obvious from the docs but say I have two slices of structs that I want to compare but only on one field.

I want to write something like:

Expect(actual).To(HaveExactElements(
    expected, 
    gstruct.MatchFields(gstruct.IgnoreExtra, Fields{"FieldName": Equal}),
))

But the values in Fields have to be already instantiated matchers. But what do I call Equal(??) with?

or something like

Expect(actual).To(HaveExactElements(expected, EqualOnFields("FieldName")))

I can see that HaveExactElements dynamically creates its default Equal() matcher from the expected elements but it wants a given custom matcher to already exist.

This is ultimately so painful because it's so painful to map values in go but it feels like this is something Gomega is in a good position to solve.

onsi commented 6 months ago

hey @michaelbeaumont there actually isn’t anything that supports this formally. when faced with situations like this I usually write a quick helper to pluck the fields for me or construct an array of matchers. In fact, I often end up with a mini-DSL tailored to the domain when I’m testing some complex behavior. For example:

Expect(PluckFoo(actual)).To(HaveExactElements(PluckFoo(expected))

With that said, I could imagine adding generic functional helpers like that to Gomega (or perhaps a subpackage of Gomega) that could implement the basic elements of Map, Pluck,Find`, etc. that play well with the Gomega ecosystem of matchers.

onsi commented 6 months ago

(I should add - there are probably functional-esque libraries out there that do this well. are you familiar with any?)

thediveo commented 6 months ago

I'm coming too across such situation from time to time, so I would be interested too.

thediveo commented 6 months ago

something along this here: https://github.com/repeale/fp-go/blob/main/map.go? Albeit not returning the fn, but the final outcome...?

onsi commented 6 months ago

yep something like that.