Is there any support for matching the rest of the key for map?
rickyson96 opened this issue · comments
Hi!
My usecase for this is to have a default matching value for map's key.
tc := map[string][]string{
"test_key": {"aaa"},
"other_key": {},
"ignore": {},
}
Expect(tc).To(HaveKeyWithValue("test_key", "aaa"))
Now, the test case is that, other than test_key
, it should be empty or not exists.
if I try something like this Expect(tc).To(HaveKeyWithValue(Not(Equal("test_key")), BeEmpty()))
, it will not match if there is no other key than the test key.
Currently I'm using this matcher for that case
Expect(tc).To(WithTransform(
func(m map[string]string) map[string]string {
delete(m, "test_key")
return m
},
Or(BeEmpty(), HaveEach(BeEmpty())),
))
Currently, I'm doing this for a composed matcher, so, that solution seems good enough. But I think I'll ask anyway to see if there is anything I miss or that might be a possible improvement.
Thanks!
hey is this a one-off? or are you wanting a reusable matcher that will allow you to make this assertion all over the place?
If it's a one off I'd keep it simple:
Expect(tc).To(HaveKeyWithValue("test_key", "aaa"))
for k, v := range tc {
if k != "test_key" {
Expect(tc).To(HaveKeyWithValue(k, BeEmpty()))
}
}
If you want something reusable I can share a few ideas. There are lots of options, including a simple helper function:
func MapHasKeyWithValueAndOthersEmpty(tc map[string][]string, key string, value, string) {
GinkgoHelper()
Expect(tc).To(HaveKeyWithValue(key, value))
for k, v := range tc {
if k != key {
Expect(tc).To(HaveKeyWithValue(k, BeEmpty()))
}
}
}
which lets you just write
MapHasKeyWithValueAndOthersEmpty(tc, "test_key", "aaa")
in your specs.
Can also show you what it looks like to make a custom matcher for this using gcustom
, or to have a matcher that wraps gstruct
.
Actually, I'm writing custom matcher so that I can abstract away the matcher's details.
type MyStruct struct {
ValuesMap map[string][]string
}
func HavePendingValue(key string, pendingValues []string) types.GomegaMatcher {
return WithTransform(
func(s MyStruct) map[string][]string {
return s.ValuesMap
},
SatisfyAll(
HaveKeyWithValue(key, ConsistOf(pendingValues)),
WithTransform(func(pv map[string][]string) map[string][]string {
delete(pv, key)
return pv
}, Or(BeEmpty(), HaveEach(BeEmpty()))),
),
)
}
// and on the test case
Expect(myStruct).To(HavePendingValue("test_key", []string{"abc"}))