From fcaca4af4e64b707bdb0773ec92441c524bce3d0 Mon Sep 17 00:00:00 2001 From: favonia Date: Mon, 18 Sep 2023 21:42:58 -0500 Subject: [PATCH] feat: add AnyOf that matches values that satisfy at least one matcher (#63) Closes #58. --- gomock/matchers.go | 43 +++++++++++++++++++++++++++++++++++++++++ gomock/matchers_test.go | 3 +++ 2 files changed, 46 insertions(+) diff --git a/gomock/matchers.go b/gomock/matchers.go index bac4623..079eae9 100644 --- a/gomock/matchers.go +++ b/gomock/matchers.go @@ -180,6 +180,27 @@ func (m assignableToTypeOfMatcher) String() string { return "is assignable to " + m.targetType.Name() } +type anyOfMatcher struct { + matchers []Matcher +} + +func (am anyOfMatcher) Matches(x any) bool { + for _, m := range am.matchers { + if m.Matches(x) { + return true + } + } + return false +} + +func (am anyOfMatcher) String() string { + ss := make([]string, 0, len(am.matchers)) + for _, matcher := range am.matchers { + ss = append(ss, matcher.String()) + } + return strings.Join(ss, " | ") +} + type allMatcher struct { matchers []Matcher } @@ -302,6 +323,28 @@ func Any() Matcher { return anyMatcher{} } // Cond(func(x any){return x.(int) == 2}).Matches(1) // returns false func Cond(fn func(x any) bool) Matcher { return condMatcher{fn} } +// AnyOf returns a composite Matcher that returns true if at least one of the +// matchers returns true. +// +// Example usage: +// +// AnyOf(1, 2, 3).Matches(2) // returns true +// AnyOf(1, 2, 3).Matches(10) // returns false +// AnyOf(Nil(), Len(2)).Matches(nil) // returns true +// AnyOf(Nil(), Len(2)).Matches("hi") // returns true +// AnyOf(Nil(), Len(2)).Matches("hello") // returns false +func AnyOf(xs ...any) Matcher { + ms := make([]Matcher, 0, len(xs)) + for _, x := range xs { + if m, ok := x.(Matcher); ok { + ms = append(ms, m) + } else { + ms = append(ms, Eq(x)) + } + } + return anyOfMatcher{ms} +} + // Eq returns a matcher that matches on equality. // // Example usage: diff --git a/gomock/matchers_test.go b/gomock/matchers_test.go index 0a85906..0380aa8 100644 --- a/gomock/matchers_test.go +++ b/gomock/matchers_test.go @@ -39,6 +39,9 @@ func TestMatchers(t *testing.T) { yes, no []e }{ {"test Any", gomock.Any(), []e{3, nil, "foo"}, nil}, + {"test AnyOf", gomock.AnyOf(gomock.Nil(), gomock.Len(2), 1, 2, 3), + []e{nil, "hi", "to", 1, 2, 3}, + []e{"s", "", 0, 4, 10}}, {"test All", gomock.Eq(4), []e{4}, []e{3, "blah", nil, int64(4)}}, {"test Nil", gomock.Nil(), []e{nil, (error)(nil), (chan bool)(nil), (*int)(nil)},