Skip to content

Commit af8c912

Browse files
committed
Backport #1786 to release/1.11
mock: revert to pre-v1.11.0 argument matching behavior for mutating stringers
1 parent b7801fb commit af8c912

File tree

2 files changed

+37
-55
lines changed

2 files changed

+37
-55
lines changed

mock/mock.go

Lines changed: 17 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -948,75 +948,56 @@ func (args Arguments) Is(objects ...interface{}) bool {
948948
return true
949949
}
950950

951-
type outputRenderer func() string
952-
953951
// Diff gets a string describing the differences between the arguments
954952
// and the specified objects.
955953
//
956954
// Returns the diff string and number of differences found.
957955
func (args Arguments) Diff(objects []interface{}) (string, int) {
958956
// TODO: could return string as error and nil for No difference
959957

960-
var outputBuilder strings.Builder
958+
output := "\n"
961959
var differences int
962960

963961
maxArgCount := len(args)
964962
if len(objects) > maxArgCount {
965963
maxArgCount = len(objects)
966964
}
967965

968-
outputRenderers := []outputRenderer{}
969-
970966
for i := 0; i < maxArgCount; i++ {
971-
i := i
972967
var actual, expected interface{}
973-
var actualFmt, expectedFmt func() string
968+
var actualFmt, expectedFmt string
974969

975970
if len(objects) <= i {
976971
actual = "(Missing)"
977-
actualFmt = func() string {
978-
return "(Missing)"
979-
}
972+
actualFmt = "(Missing)"
980973
} else {
981974
actual = objects[i]
982-
actualFmt = func() string {
983-
return fmt.Sprintf("(%[1]T=%[1]v)", actual)
984-
}
975+
actualFmt = fmt.Sprintf("(%[1]T=%[1]v)", actual)
985976
}
986977

987978
if len(args) <= i {
988979
expected = "(Missing)"
989-
expectedFmt = func() string {
990-
return "(Missing)"
991-
}
980+
expectedFmt = "(Missing)"
992981
} else {
993982
expected = args[i]
994-
expectedFmt = func() string {
995-
return fmt.Sprintf("(%[1]T=%[1]v)", expected)
996-
}
983+
expectedFmt = fmt.Sprintf("(%[1]T=%[1]v)", expected)
997984
}
998985

999986
if matcher, ok := expected.(argumentMatcher); ok {
1000987
var matches bool
1001988
func() {
1002989
defer func() {
1003990
if r := recover(); r != nil {
1004-
actualFmt = func() string {
1005-
return fmt.Sprintf("panic in argument matcher: %v", r)
1006-
}
991+
actualFmt = fmt.Sprintf("panic in argument matcher: %v", r)
1007992
}
1008993
}()
1009994
matches = matcher.Matches(actual)
1010995
}()
1011996
if matches {
1012-
outputRenderers = append(outputRenderers, func() string {
1013-
return fmt.Sprintf("\t%d: PASS: %s matched by %s\n", i, actualFmt(), matcher)
1014-
})
997+
output = fmt.Sprintf("%s\t%d: PASS: %s matched by %s\n", output, i, actualFmt, matcher)
1015998
} else {
1016999
differences++
1017-
outputRenderers = append(outputRenderers, func() string {
1018-
return fmt.Sprintf("\t%d: FAIL: %s not matched by %s\n", i, actualFmt(), matcher)
1019-
})
1000+
output = fmt.Sprintf("%s\t%d: FAIL: %s not matched by %s\n", output, i, actualFmt, matcher)
10201001
}
10211002
} else {
10221003
switch expected := expected.(type) {
@@ -1025,17 +1006,13 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
10251006
if reflect.TypeOf(actual).Name() != string(expected) && reflect.TypeOf(actual).String() != string(expected) {
10261007
// not match
10271008
differences++
1028-
outputRenderers = append(outputRenderers, func() string {
1029-
return fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, expected, reflect.TypeOf(actual).Name(), actualFmt())
1030-
})
1009+
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actualFmt)
10311010
}
10321011
case *IsTypeArgument:
10331012
actualT := reflect.TypeOf(actual)
10341013
if actualT != expected.t {
10351014
differences++
1036-
outputRenderers = append(outputRenderers, func() string {
1037-
return fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, expected.t.Name(), actualT.Name(), actualFmt())
1038-
})
1015+
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected.t.Name(), actualT.Name(), actualFmt)
10391016
}
10401017
case *FunctionalOptionsArgument:
10411018
var name string
@@ -1046,36 +1023,26 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
10461023
const tName = "[]interface{}"
10471024
if name != reflect.TypeOf(actual).String() && len(expected.values) != 0 {
10481025
differences++
1049-
outputRenderers = append(outputRenderers, func() string {
1050-
return fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, tName, reflect.TypeOf(actual).Name(), actualFmt())
1051-
})
1026+
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, tName, reflect.TypeOf(actual).Name(), actualFmt)
10521027
} else {
10531028
if ef, af := assertOpts(expected.values, actual); ef == "" && af == "" {
10541029
// match
1055-
outputRenderers = append(outputRenderers, func() string {
1056-
return fmt.Sprintf("\t%d: PASS: %s == %s\n", i, tName, tName)
1057-
})
1030+
output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, tName, tName)
10581031
} else {
10591032
// not match
10601033
differences++
1061-
outputRenderers = append(outputRenderers, func() string {
1062-
return fmt.Sprintf("\t%d: FAIL: %s != %s\n", i, af, ef)
1063-
})
1034+
output = fmt.Sprintf("%s\t%d: FAIL: %s != %s\n", output, i, af, ef)
10641035
}
10651036
}
10661037

10671038
default:
10681039
if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) {
10691040
// match
1070-
outputRenderers = append(outputRenderers, func() string {
1071-
return fmt.Sprintf("\t%d: PASS: %s == %s\n", i, actualFmt(), expectedFmt())
1072-
})
1041+
output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, actualFmt, expectedFmt)
10731042
} else {
10741043
// not match
10751044
differences++
1076-
outputRenderers = append(outputRenderers, func() string {
1077-
return fmt.Sprintf("\t%d: FAIL: %s != %s\n", i, actualFmt(), expectedFmt())
1078-
})
1045+
output = fmt.Sprintf("%s\t%d: FAIL: %s != %s\n", output, i, actualFmt, expectedFmt)
10791046
}
10801047
}
10811048
}
@@ -1086,12 +1053,7 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
10861053
return "No differences.", differences
10871054
}
10881055

1089-
outputBuilder.WriteString("\n")
1090-
for _, r := range outputRenderers {
1091-
outputBuilder.WriteString(r())
1092-
}
1093-
1094-
return outputBuilder.String(), differences
1056+
return output, differences
10951057
}
10961058

10971059
// Assert compares the arguments with the specified objects and fails if

mock/mock_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"regexp"
77
"runtime"
8+
"strconv"
89
"sync"
910
"testing"
1011
"time"
@@ -2421,3 +2422,22 @@ type user interface {
24212422
type mockUser struct{ Mock }
24222423

24232424
func (m *mockUser) Use(c caller) { m.Called(c) }
2425+
2426+
type mutatingStringer struct {
2427+
N int
2428+
s string
2429+
}
2430+
2431+
func (m *mutatingStringer) String() string {
2432+
m.s = strconv.Itoa(m.N)
2433+
return m.s
2434+
}
2435+
2436+
func TestIssue1785ArgumentWithMutatingStringer(t *testing.T) {
2437+
m := &Mock{}
2438+
m.On("Method", &mutatingStringer{N: 2})
2439+
m.On("Method", &mutatingStringer{N: 1})
2440+
m.MethodCalled("Method", &mutatingStringer{N: 1})
2441+
m.MethodCalled("Method", &mutatingStringer{N: 2})
2442+
m.AssertExpectations(t)
2443+
}

0 commit comments

Comments
 (0)