diff --git a/gomock/matchers.go b/gomock/matchers.go index 378c4046..bb627221 100644 --- a/gomock/matchers.go +++ b/gomock/matchers.go @@ -17,6 +17,7 @@ package gomock import ( "fmt" "reflect" + "strings" ) // A Matcher is a representation of a class of values. @@ -154,8 +155,33 @@ func (m assignableToTypeOfMatcher) String() string { return "is assignable to " + m.targetType.Name() } +type allMatcher struct { + matchers []Matcher +} + +func (am allMatcher) Matches(x interface{}) bool { + for _, m := range am.matchers { + if !m.Matches(x) { + return false + } + } + return true +} + +func (am allMatcher) String() string { + ss := make([]string, 0, len(am.matchers)) + for _, matcher := range am.matchers { + ss = append(ss, matcher.String()) + } + return strings.Join(ss, "; ") +} + // Constructors +// All returns a composite Matcher that returns true if and only all of the +// matchers return true. +func All(ms ...Matcher) Matcher { return allMatcher{ms} } + // Any returns a matcher that always matches. func Any() Matcher { return anyMatcher{} } diff --git a/gomock/matchers_test.go b/gomock/matchers_test.go index 8bb87f75..85d4275e 100644 --- a/gomock/matchers_test.go +++ b/gomock/matchers_test.go @@ -26,29 +26,32 @@ import ( func TestMatchers(t *testing.T) { type e interface{} - type testCase struct { + tests := []struct { + name string matcher gomock.Matcher yes, no []e - } - tests := []testCase{ - {gomock.Any(), []e{3, nil, "foo"}, nil}, - {gomock.Eq(4), []e{4}, []e{3, "blah", nil, int64(4)}}, - {gomock.Nil(), + }{ + {"test Any", gomock.Any(), []e{3, nil, "foo"}, nil}, + {"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)}, []e{"", 0, make(chan bool), errors.New("err"), new(int)}}, - {gomock.Not(gomock.Eq(4)), []e{3, "blah", nil, int64(4)}, []e{4}}, - } - for i, test := range tests { - for _, x := range test.yes { - if !test.matcher.Matches(x) { - t.Errorf(`test %d: "%v %s" should be true.`, i, x, test.matcher) + {"test Not", gomock.Not(gomock.Eq(4)), []e{3, "blah", nil, int64(4)}, []e{4}}, + {"test All", gomock.All(gomock.Any(), gomock.Eq(4)), []e{4}, []e{3, "blah", nil, int64(4)}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + for _, x := range tt.yes { + if !tt.matcher.Matches(x) { + t.Errorf(`"%v %s": got false, want true.`, x, tt.matcher) + } } - } - for _, x := range test.no { - if test.matcher.Matches(x) { - t.Errorf(`test %d: "%v %s" should be false.`, i, x, test.matcher) + for _, x := range tt.no { + if tt.matcher.Matches(x) { + t.Errorf(`"%v %s": got true, want false.`, x, tt.matcher) + } } - } + }) } }