diff --git a/gomock/matchers.go b/gomock/matchers.go index bb627221..7aa43a6d 100644 --- a/gomock/matchers.go +++ b/gomock/matchers.go @@ -176,6 +176,24 @@ func (am allMatcher) String() string { return strings.Join(ss, "; ") } +type lenMatcher struct { + i int +} + +func (m lenMatcher) Matches(x interface{}) bool { + v := reflect.ValueOf(x) + switch v.Kind() { + case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == m.i + default: + return false + } +} + +func (m lenMatcher) String() string { + return fmt.Sprintf("has length %d", m.i) +} + // Constructors // All returns a composite Matcher that returns true if and only all of the @@ -192,6 +210,12 @@ func Any() Matcher { return anyMatcher{} } // Eq(5).Matches(4) // returns false func Eq(x interface{}) Matcher { return eqMatcher{x} } +// Len returns a matcher that matches on length. This matcher returns false if +// is compared to a type that is not an array, chan, map, slice, or string. +func Len(i int) Matcher { + return lenMatcher{i} +} + // Nil returns a matcher that matches if the received value is nil. // // Example usage: diff --git a/gomock/matchers_test.go b/gomock/matchers_test.go index 85d4275e..eebb7331 100644 --- a/gomock/matchers_test.go +++ b/gomock/matchers_test.go @@ -38,6 +38,10 @@ func TestMatchers(t *testing.T) { []e{"", 0, make(chan bool), errors.New("err"), new(int)}}, {"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)}}, + {"test Len", gomock.Len(2), + []e{[]int{1, 2}, "ab", map[string]int{"a": 0, "b": 1}, [2]string{"a", "b"}}, + []e{[]int{1}, "a", 42, 42.0, false, [1]string{"a"}}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {