Skip to content

Commit

Permalink
Make Cond Matcher generic (#183)
Browse files Browse the repository at this point in the history
`gomock.Cond` at the moment expects an matcher function with the
signature `func(x any) bool` requiring a manual cast to the expected
type. By making this matcher generic the callback function can be typed
removing the need for a manual cast to the expected type.

The change should be backwards compatible with existing tests using
`gomock.Cond`.
  • Loading branch information
fasmat committed Jul 1, 2024
1 parent b59039c commit 5021857
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 15 deletions.
20 changes: 12 additions & 8 deletions gomock/matchers.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,19 @@ func (anyMatcher) String() string {
return "is anything"
}

type condMatcher struct {
fn func(x any) bool
type condMatcher[T any] struct {
fn func(x T) bool
}

func (c condMatcher) Matches(x any) bool {
return c.fn(x)
func (c condMatcher[T]) Matches(x any) bool {
typed, ok := x.(T)
if !ok {
return false
}
return c.fn(typed)
}

func (condMatcher) String() string {
func (c condMatcher[T]) String() string {
return "adheres to a custom condition"
}

Expand Down Expand Up @@ -339,9 +343,9 @@ func Any() Matcher { return anyMatcher{} }
//
// Example usage:
//
// Cond(func(x any){return x.(int) == 1}).Matches(1) // returns true
// Cond(func(x any){return x.(int) == 2}).Matches(1) // returns false
func Cond(fn func(x any) bool) Matcher { return condMatcher{fn} }
// Cond(func(x int){return x == 1}).Matches(1) // returns true
// Cond(func(x int){return x == 2}).Matches(1) // returns false
func Cond[T any](fn func(x T) bool) Matcher { return condMatcher[T]{fn} }

// AnyOf returns a composite Matcher that returns true if at least one of the
// matchers returns true.
Expand Down
4 changes: 3 additions & 1 deletion gomock/matchers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ func TestMatchers(t *testing.T) {
[]e{[]string{"a", "b"}, A{"a", "b"}},
[]e{[]string{"a"}, A{"b"}},
},
{"test Cond", gomock.Cond(func(x any) bool { return x.(B).Name == "Dam" }), []e{B{Name: "Dam"}}, []e{B{Name: "Dave"}}},
{"test Cond", gomock.Cond(func(x B) bool { return x.Name == "Dam" }), []e{B{Name: "Dam"}}, []e{B{Name: "Dave"}}},
{"test Cond wrong type", gomock.Cond(func(x B) bool { return x.Name == "Dam" }), []e{B{Name: "Dam"}}, []e{"Dave"}},
{"test Cond any type", gomock.Cond(func(x any) bool { return x.(B).Name == "Dam" }), []e{B{Name: "Dam"}}, []e{B{Name: "Dave"}}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
8 changes: 2 additions & 6 deletions sample/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,8 @@ func TestExpectCondForeignFour(t *testing.T) {
defer ctrl.Finish()

mockIndex := NewMockIndex(ctrl)
mockIndex.EXPECT().ForeignFour(gomock.Cond(func(x any) bool {
four, ok := x.(imp_four.Imp4)
if !ok {
return false
}
return four.Field == "Cool"
mockIndex.EXPECT().ForeignFour(gomock.Cond(func(x imp_four.Imp4) bool {
return x.Field == "Cool"
}))

mockIndex.ForeignFour(imp_four.Imp4{Field: "Cool"})
Expand Down

0 comments on commit 5021857

Please sign in to comment.