How to implement jests.js's `expect.any(String)` like functionality?
safareli opened this issue · 1 comments
I'm comparing 2 maps one is from http response and one expected response. As response contains id which is random I want to ignore that property, of course I can delete that property from response and do comparison that way but there are other similar usecases, what if we have id's deeper in an object. deleting things is cumbersome .
I want to basically implement somehow some value anyString
such that this will "pass":
diff(
map[string]any{
"fname": "jo",
"lname": "do,
"id": "asd-ad12-3rfs-ad4"
},
map[string]any{
"fname": "jo",
"lname": "do,
"id": anyString
},
)
Jest.js has something similar expect.any(constructor)
expect(val).toEqual({
data: expect.any(Array),
active: true,
ID: expect.any(String),
})
This expect.any(constructor) returns special value that is used during diffing to only check constructors of values.
I tried to implement anyString:
type AnyString struct {
value string
isInput bool
}
var anyString = AnyString{}
func TestAnyString(t *testing.T) {
// Example usage
x := map[string]any{
"foo": "12",
}
y := map[string]any{
"foo": anyString,
}
optTrans := cmp.Transformer("strinany", func(input string) AnyString {
return AnyString{value: input, isInput: true}
})
optComp := cmp.Comparer(func(x, y AnyString) bool {
// if one is input string and one is anyString we match
if x.isInput == !y.isInput {
return true
}
return x == y
})
if diff := cmp.Diff(x, y, optTrans, optComp); diff != "" {
fmt.Printf("Mismatch (-x +y):\n%s", diff)
t.Fail()
} else {
fmt.Println("Match")
}
}
but I am getting:
map[string]any{
- "foo": string("12"),
+ "foo": testz.AnyString{},
}
as I understand the transformation only work if both values on each side are of same type.
Is there any way I can implement that with this library?
Related issues
Well actually thanks to example https://play.golang.org/p/iRvh9tTJk_q shared by @dsnet here #261 (comment) I was able to do what I wanted.
type AnyString struct {
value string
isInput bool
}
var anyString = AnyString{}
func TestAnyString(t *testing.T) {
// Example usage
x := map[string]any{
"foo": "12",
}
y := map[string]any{
"foo": anyString,
}
tr := cmp.FilterValues(func(x, y interface{}) bool {
_, okX1 := x.(string)
_, okX2 := x.(AnyString)
_, okY1 := y.(string)
_, okY2 := y.(AnyString)
return (okX1 || okX2) && (okY1 || okY2)
}, cmp.Transformer("AnyStringTransformer", func(x interface{}) AnyString {
if is, ok := x.(string); ok {
return AnyString{value: is, isInput: true}
}
return x.(AnyString)
}))
optComp := cmp.Comparer(func(x AnyString, y AnyString) bool {
// if one is input string and one is anyString we match
if x.isInput == !y.isInput {
return true
}
return x == y
})
if diff := cmp.Diff(x, y, tr, optComp); diff != "" {
fmt.Printf("Mismatch (-x +y):\n%s", diff)
t.Fail()
} else {
fmt.Println("Match")
}
}