From f159d62078cd1ee294e58036af3e8809ec88de8b Mon Sep 17 00:00:00 2001 From: hori-ryota Date: Fri, 18 Aug 2017 16:51:06 +0900 Subject: [PATCH 1/4] Fix variadic mock for gomock.Any() . fix #68 --- gomock/call.go | 32 +++++++++++++++++++++++++++++--- sample/user_test.go | 43 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 70 insertions(+), 5 deletions(-) diff --git a/gomock/call.go b/gomock/call.go index dc2a479d..79ae78d3 100644 --- a/gomock/call.go +++ b/gomock/call.go @@ -198,11 +198,37 @@ func (c *Call) String() string { // Tests if the given call matches the expected call. // If yes, returns nil. If no, returns error with message explaining why it does not match. func (c *Call) matches(args []interface{}) error { - if len(args) != len(c.args) { - return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %s, want: %s", - c.origin, strconv.Itoa(len(args)), strconv.Itoa(len(c.args))) + if c.methodType.IsVariadic() { + if len(c.args) < c.methodType.NumIn()-1 { + return fmt.Errorf("matcher count is not enough at %s. Got: %d, want: greater than or equal to %d", + c.origin, len(c.args), c.methodType.NumIn()-1) + } + if len(c.args) != c.methodType.NumIn() && len(args) != len(c.args) { + return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want: %d", + c.origin, len(args), len(c.args)) + } + if len(args) < len(c.args)-1 { + return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want: greater than or equal to %d", + c.origin, len(args), len(c.args)-1) + } + } else { + if len(args) != len(c.args) { + return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want %d", + c.origin, len(args), len(c.args)) + } + } + + if len(args) < len(c.args) { + args = append(args, nil) } for i, m := range c.args { + if i == len(c.args) && c.methodType.IsVariadic() { + if !c.args[i].Matches(args[i:]) && !(len(c.args) == len(args) && c.args[i].Matches(args[i])) { + return fmt.Errorf("Expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v\n", + c.origin, strconv.Itoa(i), args[i:], c.args[i]) + } + break + } if !m.Matches(args[i]) { return fmt.Errorf("Expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v\n", c.origin, strconv.Itoa(i), args[i], m) diff --git a/sample/user_test.go b/sample/user_test.go index c8c3864a..875e81f5 100644 --- a/sample/user_test.go +++ b/sample/user_test.go @@ -68,8 +68,7 @@ func TestVariadicFunction(t *testing.T) { defer ctrl.Finish() mockIndex := mock_user.NewMockIndex(ctrl) - m := mockIndex.EXPECT().Ellip("%d", 0, 1, 1, 2, 3) - m.Do(func(format string, nums ...int) { + mockIndex.EXPECT().Ellip("%d", 0, 1, 1, 2, 3).Do(func(format string, nums ...int) { sum := 0 for _, value := range nums { sum += value @@ -78,8 +77,48 @@ func TestVariadicFunction(t *testing.T) { t.Errorf("Expected 7, got %d", sum) } }) + mockIndex.EXPECT().Ellip("%d", gomock.Any()).Do(func(format string, nums ...int) { + sum := 0 + for _, value := range nums { + sum += value + } + if sum != 7 { + t.Errorf("Expected 7, got %d", sum) + } + }) + mockIndex.EXPECT().Ellip("%d", gomock.Any()).Do(func(format string, nums ...int) { + sum := 0 + for _, value := range nums { + sum += value + } + if sum != 0 { + t.Errorf("Expected 0, got %d", sum) + } + }) + mockIndex.EXPECT().Ellip("%d", gomock.Any()).Do(func(format string, nums ...int) { + sum := 0 + for _, value := range nums { + sum += value + } + if sum != 0 { + t.Errorf("Expected 0, got %d", sum) + } + }) + mockIndex.EXPECT().Ellip("%d").Do(func(format string, nums ...int) { + sum := 0 + for _, value := range nums { + sum += value + } + if sum != 0 { + t.Errorf("Expected 0, got %d", sum) + } + }) mockIndex.Ellip("%d", 0, 1, 1, 2, 3) + mockIndex.Ellip("%d", 0, 1, 1, 2, 3) + mockIndex.Ellip("%d", 0) + mockIndex.Ellip("%d") + mockIndex.Ellip("%d") } func TestGrabPointer(t *testing.T) { From e5aec3d1615ae568772c81de772ba31e2bbba696 Mon Sep 17 00:00:00 2001 From: hori-ryota Date: Fri, 18 Aug 2017 17:14:44 +0900 Subject: [PATCH 2/4] fix bug --- gomock/call.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/gomock/call.go b/gomock/call.go index 79ae78d3..1d6646ad 100644 --- a/gomock/call.go +++ b/gomock/call.go @@ -218,11 +218,8 @@ func (c *Call) matches(args []interface{}) error { } } - if len(args) < len(c.args) { - args = append(args, nil) - } for i, m := range c.args { - if i == len(c.args) && c.methodType.IsVariadic() { + if i == len(c.args)-1 && c.methodType.IsVariadic() { if !c.args[i].Matches(args[i:]) && !(len(c.args) == len(args) && c.args[i].Matches(args[i])) { return fmt.Errorf("Expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v\n", c.origin, strconv.Itoa(i), args[i:], c.args[i]) From ab9c68c8727ea1b50e417b188a414b8edef92627 Mon Sep 17 00:00:00 2001 From: hori-ryota Date: Fri, 18 Aug 2017 17:17:44 +0900 Subject: [PATCH 3/4] fix typo --- gomock/call.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gomock/call.go b/gomock/call.go index 1d6646ad..a954ec39 100644 --- a/gomock/call.go +++ b/gomock/call.go @@ -213,7 +213,7 @@ func (c *Call) matches(args []interface{}) error { } } else { if len(args) != len(c.args) { - return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want %d", + return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want: %d", c.origin, len(args), len(c.args)) } } From 7dc66f5f789eca1f66e82966331cde181184e62e Mon Sep 17 00:00:00 2001 From: hori-ryota Date: Fri, 29 Sep 2017 12:47:24 +0900 Subject: [PATCH 4/4] refactor messages --- gomock/call.go | 63 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/gomock/call.go b/gomock/call.go index a954ec39..2c52e127 100644 --- a/gomock/call.go +++ b/gomock/call.go @@ -198,9 +198,21 @@ func (c *Call) String() string { // Tests if the given call matches the expected call. // If yes, returns nil. If no, returns error with message explaining why it does not match. func (c *Call) matches(args []interface{}) error { - if c.methodType.IsVariadic() { + if !c.methodType.IsVariadic() { + if len(args) != len(c.args) { + return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want: %d", + c.origin, len(args), len(c.args)) + } + + for i, m := range c.args { + if !m.Matches(args[i]) { + return fmt.Errorf("Expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v\n", + c.origin, strconv.Itoa(i), args[i], m) + } + } + } else { if len(c.args) < c.methodType.NumIn()-1 { - return fmt.Errorf("matcher count is not enough at %s. Got: %d, want: greater than or equal to %d", + return fmt.Errorf("Expected call at %s has the wrong number of matchers. Got: %d, want: %d", c.origin, len(c.args), c.methodType.NumIn()-1) } if len(c.args) != c.methodType.NumIn() && len(args) != len(c.args) { @@ -211,24 +223,43 @@ func (c *Call) matches(args []interface{}) error { return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want: greater than or equal to %d", c.origin, len(args), len(c.args)-1) } - } else { - if len(args) != len(c.args) { - return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want: %d", - c.origin, len(args), len(c.args)) - } - } - for i, m := range c.args { - if i == len(c.args)-1 && c.methodType.IsVariadic() { - if !c.args[i].Matches(args[i:]) && !(len(c.args) == len(args) && c.args[i].Matches(args[i])) { + for i, m := range c.args { + if i == len(c.args)-1 { + // The last arg has a possibility of a variadic argument, so let it branch + + // sample: Foo(a int, b int, c ...int) + + if len(c.args) == len(args) { + if c.args[i].Matches(args[i]) { + // Got Foo(a, b, c) want Foo(matcherA, matcherB, gomock.Any()) + // Got Foo(a, b, c) want Foo(matcherA, matcherB, someSliceMatcher) + // Got Foo(a, b, c) want Foo(matcherA, matcherB, matcherC) + // Got Foo(a, b) want Foo(matcherA, matcherB) + // Got Foo(a, b, c, d) want Foo(matcherA, matcherB, matcherC, matcherD) + break + } + } else if c.args[i].Matches(args[i:]) { + // Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, gomock.Any()) + // Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, someSliceMatcher) + // Got Foo(a, b) want Foo(matcherA, matcherB, gomock.Any()) + // Got Foo(a, b) want Foo(matcherA, matcherB, someEmptySliceMatcher) + break + } + // Wrong number of matchers or not match. Fail. + // Got Foo(a, b) want Foo(matcherA, matcherB, matcherC, matcherD) + // Got Foo(a, b, c) want Foo(matcherA, matcherB, matcherC, matcherD) + // Got Foo(a, b, c, d) want Foo(matcherA, matcherB, matcherC, matcherD, matcherE) + // Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, matcherC, matcherD) + // Got Foo(a, b, c) want Foo(matcherA, matcherB) return fmt.Errorf("Expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v\n", c.origin, strconv.Itoa(i), args[i:], c.args[i]) } - break - } - if !m.Matches(args[i]) { - return fmt.Errorf("Expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v\n", - c.origin, strconv.Itoa(i), args[i], m) + + if !m.Matches(args[i]) { + return fmt.Errorf("Expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v\n", + c.origin, strconv.Itoa(i), args[i], m) + } } }