From 9a7e703a6c0f5a8579156fc25f9a2c8e68a165f7 Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Wed, 11 Oct 2023 11:50:43 -0700 Subject: [PATCH] assert: better formatting for Len() error Previously, the use of %s with array objects meant you would get an error like this: "[%!s(int=1) %!s(int=2) %!s(int=3)]\" should have 4 item(s), but has 3 Use %v instead, which provides a much nicer error. "[1 2 3]" should have 4 item(s), but has 3 Fixes #1482. --- assert/assertions.go | 4 ++-- assert/assertions_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 719164e7e..52905a5c3 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -751,11 +751,11 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) } l, ok := getLen(object) if !ok { - return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...) + return Fail(t, fmt.Sprintf("\"%v\" could not be applied builtin len()", object), msgAndArgs...) } if l != length { - return Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...) + return Fail(t, fmt.Sprintf("\"%v\" should have %d item(s), but has %d", object, length, l), msgAndArgs...) } return true } diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 40e372015..ab309de09 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -1677,6 +1677,33 @@ func TestLen(t *testing.T) { for _, c := range cases { False(t, Len(mockT, c.v, c.l), "%#v have %d items", c.v, c.l) } + + formatCases := []struct { + in interface{} + wantLen int + want string + }{ + {[]int{1, 2, 3}, 3, "[1 2 3]"}, + {[...]int{1, 2, 3}, 3, "[1 2 3]"}, + {"ABC", 3, "ABC"}, + {map[int]int{1: 2, 2: 4, 3: 6}, 3, "map[1:2 2:4 3:6]"}, + + {[]int{}, 0, "[]"}, + {map[int]int{}, 0, "map[]"}, + + {[]int(nil), 0, "[]"}, + {map[int]int(nil), 0, "map[]"}, + {(chan int)(nil), 0, ""}, + } + + t.Run("Len() error message formatting", func(t *testing.T) { + for _, tt := range formatCases { + msgMock := new(mockTestingT) + Len(msgMock, tt.in, 1234567) + want := fmt.Sprintf(`"%s" should have 1234567 item(s), but has %d`, tt.want, tt.wantLen) + Contains(t, msgMock.errorString(), want) + } + }) } func TestWithinDuration(t *testing.T) {