@@ -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.
955957func (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