Skip to content

Commit a31a53e

Browse files
Merge pull request #1615 from DevotedHealth/mauclair-mock-match-sprintf
Lazily render mock diff output on successful match
2 parents 5ac6528 + e6575e0 commit a31a53e

File tree

1 file changed

+55
-17
lines changed

1 file changed

+55
-17
lines changed

mock/mock.go

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

951+
type outputRenderer func() string
952+
951953
// Diff gets a string describing the differences between the arguments
952954
// and the specified objects.
953955
//
954956
// Returns the diff string and number of differences found.
955957
func (args Arguments) Diff(objects []interface{}) (string, int) {
956958
// TODO: could return string as error and nil for No difference
957959

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

961963
maxArgCount := len(args)
962964
if len(objects) > maxArgCount {
963965
maxArgCount = len(objects)
964966
}
965967

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

970975
if len(objects) <= i {
971976
actual = "(Missing)"
972-
actualFmt = "(Missing)"
977+
actualFmt = func() string {
978+
return "(Missing)"
979+
}
973980
} else {
974981
actual = objects[i]
975-
actualFmt = fmt.Sprintf("(%[1]T=%[1]v)", actual)
982+
actualFmt = func() string {
983+
return fmt.Sprintf("(%[1]T=%[1]v)", actual)
984+
}
976985
}
977986

978987
if len(args) <= i {
979988
expected = "(Missing)"
980-
expectedFmt = "(Missing)"
989+
expectedFmt = func() string {
990+
return "(Missing)"
991+
}
981992
} else {
982993
expected = args[i]
983-
expectedFmt = fmt.Sprintf("(%[1]T=%[1]v)", expected)
994+
expectedFmt = func() string {
995+
return fmt.Sprintf("(%[1]T=%[1]v)", expected)
996+
}
984997
}
985998

986999
if matcher, ok := expected.(argumentMatcher); ok {
9871000
var matches bool
9881001
func() {
9891002
defer func() {
9901003
if r := recover(); r != nil {
991-
actualFmt = fmt.Sprintf("panic in argument matcher: %v", r)
1004+
actualFmt = func() string {
1005+
return fmt.Sprintf("panic in argument matcher: %v", r)
1006+
}
9921007
}
9931008
}()
9941009
matches = matcher.Matches(actual)
9951010
}()
9961011
if matches {
997-
output = fmt.Sprintf("%s\t%d: PASS: %s matched by %s\n", output, i, actualFmt, matcher)
1012+
outputRenderers = append(outputRenderers, func() string {
1013+
return fmt.Sprintf("\t%d: PASS: %s matched by %s\n", i, actualFmt(), matcher)
1014+
})
9981015
} else {
9991016
differences++
1000-
output = fmt.Sprintf("%s\t%d: FAIL: %s not matched by %s\n", output, i, actualFmt, matcher)
1017+
outputRenderers = append(outputRenderers, func() string {
1018+
return fmt.Sprintf("\t%d: FAIL: %s not matched by %s\n", i, actualFmt(), matcher)
1019+
})
10011020
}
10021021
} else {
10031022
switch expected := expected.(type) {
@@ -1006,13 +1025,17 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
10061025
if reflect.TypeOf(actual).Name() != string(expected) && reflect.TypeOf(actual).String() != string(expected) {
10071026
// not match
10081027
differences++
1009-
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actualFmt)
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+
})
10101031
}
10111032
case *IsTypeArgument:
10121033
actualT := reflect.TypeOf(actual)
10131034
if actualT != expected.t {
10141035
differences++
1015-
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected.t.Name(), actualT.Name(), actualFmt)
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+
})
10161039
}
10171040
case *FunctionalOptionsArgument:
10181041
var name string
@@ -1023,26 +1046,36 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
10231046
const tName = "[]interface{}"
10241047
if name != reflect.TypeOf(actual).String() && len(expected.values) != 0 {
10251048
differences++
1026-
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, tName, reflect.TypeOf(actual).Name(), actualFmt)
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+
})
10271052
} else {
10281053
if ef, af := assertOpts(expected.values, actual); ef == "" && af == "" {
10291054
// match
1030-
output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, tName, tName)
1055+
outputRenderers = append(outputRenderers, func() string {
1056+
return fmt.Sprintf("\t%d: PASS: %s == %s\n", i, tName, tName)
1057+
})
10311058
} else {
10321059
// not match
10331060
differences++
1034-
output = fmt.Sprintf("%s\t%d: FAIL: %s != %s\n", output, i, af, ef)
1061+
outputRenderers = append(outputRenderers, func() string {
1062+
return fmt.Sprintf("\t%d: FAIL: %s != %s\n", i, af, ef)
1063+
})
10351064
}
10361065
}
10371066

10381067
default:
10391068
if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) {
10401069
// match
1041-
output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, actualFmt, expectedFmt)
1070+
outputRenderers = append(outputRenderers, func() string {
1071+
return fmt.Sprintf("\t%d: PASS: %s == %s\n", i, actualFmt(), expectedFmt())
1072+
})
10421073
} else {
10431074
// not match
10441075
differences++
1045-
output = fmt.Sprintf("%s\t%d: FAIL: %s != %s\n", output, i, actualFmt, expectedFmt)
1076+
outputRenderers = append(outputRenderers, func() string {
1077+
return fmt.Sprintf("\t%d: FAIL: %s != %s\n", i, actualFmt(), expectedFmt())
1078+
})
10461079
}
10471080
}
10481081
}
@@ -1053,7 +1086,12 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
10531086
return "No differences.", differences
10541087
}
10551088

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

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

0 commit comments

Comments
 (0)