Skip to content

Commit 49bcd2a

Browse files
Merge pull request #1646 from brackendawson/token-too-long
assert: truncate very long objects in test failure messages
2 parents 6c30310 + d5be414 commit 49bcd2a

File tree

2 files changed

+290
-47
lines changed

2 files changed

+290
-47
lines changed

assert/assertions.go

Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -325,13 +325,15 @@ func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
325325
func indentMessageLines(message string, longestLabelLen int) string {
326326
outBuf := new(bytes.Buffer)
327327

328-
for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ {
329-
// no need to align first line because it starts at the correct location (after the label)
330-
if i != 0 {
331-
// append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab
332-
outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t")
328+
scanner := bufio.NewScanner(strings.NewReader(message))
329+
for firstLine := true; scanner.Scan(); firstLine = false {
330+
if !firstLine {
331+
fmt.Fprint(outBuf, "\n\t"+strings.Repeat(" ", longestLabelLen+1)+"\t")
333332
}
334-
outBuf.WriteString(scanner.Text())
333+
fmt.Fprint(outBuf, scanner.Text())
334+
}
335+
if err := scanner.Err(); err != nil {
336+
return fmt.Sprintf("cannot display message: %s", err)
335337
}
336338

337339
return outBuf.String()
@@ -544,9 +546,8 @@ func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) b
544546
if !same {
545547
// both are pointers but not the same type & pointing to the same address
546548
return Fail(t, fmt.Sprintf("Not same: \n"+
547-
"expected: %#[1]v (%[1]T)(%[1]p)\n"+
548-
"actual : %#[2]v (%[2]T)(%[2]p)",
549-
expected, actual), msgAndArgs...)
549+
"expected: %[2]s (%[1]T)(%[1]p)\n"+
550+
"actual : %[4]s (%[3]T)(%[3]p)", expected, truncatingFormat("%#v", expected), actual, truncatingFormat("%#v", actual)), msgAndArgs...)
550551
}
551552

552553
return true
@@ -571,8 +572,8 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}
571572

572573
if same {
573574
return Fail(t, fmt.Sprintf(
574-
"Expected and actual point to the same object: %p %#[1]v",
575-
expected), msgAndArgs...)
575+
"Expected and actual point to the same object: %p %s",
576+
expected, truncatingFormat("%#v", expected)), msgAndArgs...)
576577
}
577578
return true
578579
}
@@ -604,25 +605,26 @@ func samePointers(first, second interface{}) (same bool, ok bool) {
604605
// to a type conversion in the Go grammar.
605606
func formatUnequalValues(expected, actual interface{}) (e string, a string) {
606607
if reflect.TypeOf(expected) != reflect.TypeOf(actual) {
607-
return fmt.Sprintf("%T(%s)", expected, truncatingFormat(expected)),
608-
fmt.Sprintf("%T(%s)", actual, truncatingFormat(actual))
608+
return fmt.Sprintf("%T(%s)", expected, truncatingFormat("%#v", expected)),
609+
fmt.Sprintf("%T(%s)", actual, truncatingFormat("%#v", actual))
609610
}
610611
switch expected.(type) {
611612
case time.Duration:
612613
return fmt.Sprintf("%v", expected), fmt.Sprintf("%v", actual)
613614
}
614-
return truncatingFormat(expected), truncatingFormat(actual)
615+
return truncatingFormat("%#v", expected), truncatingFormat("%#v", actual)
615616
}
616617

617618
// truncatingFormat formats the data and truncates it if it's too long.
618619
//
619620
// This helps keep formatted error messages lines from exceeding the
620621
// bufio.MaxScanTokenSize max line length that the go testing framework imposes.
621-
func truncatingFormat(data interface{}) string {
622-
value := fmt.Sprintf("%#v", data)
623-
max := bufio.MaxScanTokenSize - 100 // Give us some space the type info too if needed.
624-
if len(value) > max {
625-
value = value[0:max] + "<... truncated>"
622+
func truncatingFormat(format string, data interface{}) string {
623+
value := fmt.Sprintf(format, data)
624+
// Give us space for two truncated objects and the surrounding sentence.
625+
maxMessageSize := bufio.MaxScanTokenSize/2 - 100
626+
if len(value) > maxMessageSize {
627+
value = value[0:maxMessageSize] + "<... truncated>"
626628
}
627629
return value
628630
}
@@ -743,7 +745,7 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
743745
if h, ok := t.(tHelper); ok {
744746
h.Helper()
745747
}
746-
return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...)
748+
return Fail(t, fmt.Sprintf("Expected nil, but got: %s", truncatingFormat("%#v", object)), msgAndArgs...)
747749
}
748750

749751
// isEmpty gets whether the specified object is considered empty or not.
@@ -793,7 +795,7 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
793795
if h, ok := t.(tHelper); ok {
794796
h.Helper()
795797
}
796-
Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...)
798+
Fail(t, fmt.Sprintf("Should be empty, but was %s", truncatingFormat("%v", object)), msgAndArgs...)
797799
}
798800

799801
return pass
@@ -836,11 +838,11 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{})
836838
}
837839
l, ok := getLen(object)
838840
if !ok {
839-
return Fail(t, fmt.Sprintf("\"%v\" could not be applied builtin len()", object), msgAndArgs...)
841+
return Fail(t, fmt.Sprintf("%q could not be applied builtin len()", truncatingFormat("%v", object)), msgAndArgs...)
840842
}
841843

842844
if l != length {
843-
return Fail(t, fmt.Sprintf("\"%v\" should have %d item(s), but has %d", object, length, l), msgAndArgs...)
845+
return Fail(t, fmt.Sprintf("%q should have %d item(s), but has %d", truncatingFormat("%v", object), length, l), msgAndArgs...)
844846
}
845847
return true
846848
}
@@ -889,7 +891,7 @@ func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{
889891
}
890892

891893
if ObjectsAreEqual(expected, actual) {
892-
return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...)
894+
return Fail(t, fmt.Sprintf("Should not be: %s\n", truncatingFormat("%#v", actual)), msgAndArgs...)
893895
}
894896

895897
return true
@@ -904,7 +906,7 @@ func NotEqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...inte
904906
}
905907

906908
if ObjectsAreEqualValues(expected, actual) {
907-
return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...)
909+
return Fail(t, fmt.Sprintf("Should not be: %s\n", truncatingFormat("%#v", actual)), msgAndArgs...)
908910
}
909911

910912
return true
@@ -964,10 +966,10 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo
964966

965967
ok, found := containsElement(s, contains)
966968
if !ok {
967-
return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...)
969+
return Fail(t, fmt.Sprintf("%s could not be applied builtin len()", truncatingFormat("%#v", s)), msgAndArgs...)
968970
}
969971
if !found {
970-
return Fail(t, fmt.Sprintf("%#v does not contain %#v", s, contains), msgAndArgs...)
972+
return Fail(t, fmt.Sprintf("%s does not contain %#v", truncatingFormat("%#v", s), contains), msgAndArgs...)
971973
}
972974

973975
return true
@@ -986,10 +988,10 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{})
986988

987989
ok, found := containsElement(s, contains)
988990
if !ok {
989-
return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...)
991+
return Fail(t, fmt.Sprintf("%s could not be applied builtin len()", truncatingFormat("%#v", s)), msgAndArgs...)
990992
}
991993
if found {
992-
return Fail(t, fmt.Sprintf("%#v should not contain %#v", s, contains), msgAndArgs...)
994+
return Fail(t, fmt.Sprintf("%s should not contain %#v", truncatingFormat("%#v", s), contains), msgAndArgs...)
993995
}
994996

995997
return true
@@ -1031,10 +1033,10 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
10311033
av := actualMap.MapIndex(k)
10321034

10331035
if !av.IsValid() {
1034-
return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...)
1036+
return Fail(t, fmt.Sprintf("%s does not contain %s", truncatingFormat("%#v", list), truncatingFormat("%#v", subset)), msgAndArgs...)
10351037
}
10361038
if !ObjectsAreEqual(ev.Interface(), av.Interface()) {
1037-
return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...)
1039+
return Fail(t, fmt.Sprintf("%s does not contain %s", truncatingFormat("%#v", list), truncatingFormat("%#v", subset)), msgAndArgs...)
10381040
}
10391041
}
10401042

@@ -1056,7 +1058,7 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
10561058
return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", list), msgAndArgs...)
10571059
}
10581060
if !found {
1059-
return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, element), msgAndArgs...)
1061+
return Fail(t, fmt.Sprintf("%s does not contain %#v", truncatingFormat("%#v", list), element), msgAndArgs...)
10601062
}
10611063
}
10621064

@@ -1106,7 +1108,7 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{})
11061108
}
11071109
}
11081110

1109-
return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...)
1111+
return Fail(t, fmt.Sprintf("%s is a subset of %s", truncatingFormat("%q", subset), truncatingFormat("%q", list)), msgAndArgs...)
11101112
}
11111113

11121114
subsetList := reflect.ValueOf(subset)
@@ -1128,7 +1130,7 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{})
11281130
}
11291131
}
11301132

1131-
return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...)
1133+
return Fail(t, fmt.Sprintf("%s is a subset of %s", truncatingFormat("%q", subset), truncatingFormat("%q", list)), msgAndArgs...)
11321134
}
11331135

11341136
// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified
@@ -1641,7 +1643,7 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
16411643
if h, ok := t.(tHelper); ok {
16421644
h.Helper()
16431645
}
1644-
return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...)
1646+
return Fail(t, fmt.Sprintf("Received unexpected error:\n%s", truncatingFormat("%+v", err)), msgAndArgs...)
16451647
}
16461648

16471649
return true
@@ -1680,7 +1682,7 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte
16801682
if expected != actual {
16811683
return Fail(t, fmt.Sprintf("Error message not equal:\n"+
16821684
"expected: %q\n"+
1683-
"actual : %q", expected, actual), msgAndArgs...)
1685+
"actual : %s", expected, truncatingFormat("%q", actual)), msgAndArgs...)
16841686
}
16851687
return true
16861688
}
@@ -1700,7 +1702,7 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in
17001702

17011703
actual := theError.Error()
17021704
if !strings.Contains(actual, contains) {
1703-
return Fail(t, fmt.Sprintf("Error %#v does not contain %#v", actual, contains), msgAndArgs...)
1705+
return Fail(t, fmt.Sprintf("Error %s does not contain %#v", truncatingFormat("%#v", actual), contains), msgAndArgs...)
17041706
}
17051707

17061708
return true
@@ -1766,7 +1768,7 @@ func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
17661768
h.Helper()
17671769
}
17681770
if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
1769-
return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...)
1771+
return Fail(t, fmt.Sprintf("Should be zero, but was %s", truncatingFormat("%v", i)), msgAndArgs...)
17701772
}
17711773
return true
17721774
}
@@ -2206,8 +2208,8 @@ func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {
22062208
chain := buildErrorChainString(err, false)
22072209

22082210
return Fail(t, fmt.Sprintf("Target error should be in err chain:\n"+
2209-
"expected: %q\n"+
2210-
"in chain: %s", expectedText, chain,
2211+
"expected: %s\n"+
2212+
"in chain: %s", truncatingFormat("%q", expectedText), truncatingFormat("%s", chain),
22112213
), msgAndArgs...)
22122214
}
22132215

@@ -2229,8 +2231,8 @@ func NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {
22292231
chain := buildErrorChainString(err, false)
22302232

22312233
return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+
2232-
"found: %q\n"+
2233-
"in chain: %s", expectedText, chain,
2234+
"found: %s\n"+
2235+
"in chain: %s", truncatingFormat("%q", expectedText), truncatingFormat("%s", chain),
22342236
), msgAndArgs...)
22352237
}
22362238

@@ -2254,7 +2256,7 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{
22542256

22552257
return Fail(t, fmt.Sprintf("Should be in error chain:\n"+
22562258
"expected: %s\n"+
2257-
"in chain: %s", expectedType, chain,
2259+
"in chain: %s", expectedType, truncatingFormat("%s", chain),
22582260
), msgAndArgs...)
22592261
}
22602262

@@ -2272,7 +2274,7 @@ func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interfa
22722274

22732275
return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+
22742276
"found: %s\n"+
2275-
"in chain: %s", reflect.TypeOf(target).Elem().String(), chain,
2277+
"in chain: %s", reflect.TypeOf(target).Elem().String(), truncatingFormat("%s", chain),
22762278
), msgAndArgs...)
22772279
}
22782280

0 commit comments

Comments
 (0)