From 0f6dc2121372d4e01b91c09c922fdc5047283635 Mon Sep 17 00:00:00 2001 From: Guido Arnau Date: Fri, 10 Jul 2020 16:42:11 +0200 Subject: [PATCH] format variadic arguments with GotFormatter (#434) Matchers implementing the GotFormatter interface are no longer ignored. Match failures are formatted correctly. Fixes: #432 --- gomock/call.go | 21 ++++++++++------- gomock/controller_test.go | 49 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/gomock/call.go b/gomock/call.go index 49d35846..b18cc2d6 100644 --- a/gomock/call.go +++ b/gomock/call.go @@ -304,14 +304,9 @@ func (c *Call) matches(args []interface{}) error { for i, m := range c.args { if !m.Matches(args[i]) { - got := fmt.Sprintf("%v", args[i]) - if gs, ok := m.(GotFormatter); ok { - got = gs.Got(args[i]) - } - return fmt.Errorf( "expected call at %s doesn't match the argument at index %d.\nGot: %v\nWant: %v", - c.origin, i, got, m, + c.origin, i, formatGottenArg(m, args[i]), m, ) } } @@ -334,7 +329,7 @@ func (c *Call) matches(args []interface{}) error { // Non-variadic 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", - c.origin, strconv.Itoa(i), args[i], m) + c.origin, strconv.Itoa(i), formatGottenArg(m, args[i]), m) } continue } @@ -376,9 +371,9 @@ func (c *Call) matches(args []interface{}) error { // 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", - c.origin, strconv.Itoa(i), args[i:], c.args[i]) + return fmt.Errorf("expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v", + c.origin, strconv.Itoa(i), formatGottenArg(m, args[i:]), c.args[i]) } } @@ -428,3 +423,11 @@ func setSlice(arg interface{}, v reflect.Value) { func (c *Call) addAction(action func([]interface{}) []interface{}) { c.actions = append(c.actions, action) } + +func formatGottenArg(m Matcher, arg interface{}) string { + got := fmt.Sprintf("%v", arg) + if gs, ok := m.(GotFormatter); ok { + got = gs.Got(arg) + } + return got +} diff --git a/gomock/controller_test.go b/gomock/controller_test.go index 5f6e7427..d28fee11 100644 --- a/gomock/controller_test.go +++ b/gomock/controller_test.go @@ -749,6 +749,55 @@ func TestVariadicMatchingWithSlice(t *testing.T) { } } +func TestVariadicArgumentsGotFormatter(t *testing.T) { + rep, ctrl := createFixtures(t) + defer rep.recoverUnexpectedFatal() + + s := new(Subject) + ctrl.RecordCall( + s, + "VariadicMethod", + gomock.GotFormatterAdapter( + gomock.GotFormatterFunc(func(i interface{}) string { + return fmt.Sprintf("test{%v}", i) + }), + gomock.Eq(0), + ), + ) + + rep.assertFatal(func() { + ctrl.Call(s, "VariadicMethod", 1) + }, "expected call to", "doesn't match the argument at index 0", + "Got: test{1}\nWant: is equal to 0") + ctrl.Call(s, "VariadicMethod", 0) + ctrl.Finish() +} + +func TestVariadicArgumentsGotFormatterTooManyArgsFailure(t *testing.T) { + rep, ctrl := createFixtures(t) + defer rep.recoverUnexpectedFatal() + + s := new(Subject) + ctrl.RecordCall( + s, + "VariadicMethod", + 0, + gomock.GotFormatterAdapter( + gomock.GotFormatterFunc(func(i interface{}) string { + return fmt.Sprintf("test{%v}", i) + }), + gomock.Eq("1"), + ), + ) + + rep.assertFatal(func() { + ctrl.Call(s, "VariadicMethod", 0, "2", "3") + }, "expected call to", "doesn't match the argument at index 1", + "Got: test{[2 3]}\nWant: is equal to 1") + ctrl.Call(s, "VariadicMethod", 0, "1") + ctrl.Finish() +} + func TestNoHelper(t *testing.T) { ctrlNoHelper := gomock.NewController(NewErrorReporter(t))