Skip to content

Commit 437071b

Browse files
authored
assert: fix error message formatting for NotContains (#1362)
* assert: rename and refactor TestContainsFailMessage I've renamed it to TestContainsNotContains and added a test case structure so that I can use this test to validate the failure messages from both Contains and NotContains, There are no functional changes here, strictly refactoring. A new test case will be added in a subsequent change. * assert: fix error message formatting for NotContains It was using "%s" to format the s and contains arguments, but these could be any type that supports iteration such as a map. In this case of NotContains failing against a map, it would print something like: "map[one:%!s(int=1)]" should not contain "one" Fix this using "%#v" as was already done for Contains and added test cases covering both the "len()" / iterable failure messages as well as the Contains/NotContains failure case. The new message for this example map would be something like: map[string]int{"one":1} should not contain "one"
1 parent c5fc9d6 commit 437071b

File tree

2 files changed

+54
-9
lines changed

2 files changed

+54
-9
lines changed

assert/assertions.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -877,10 +877,10 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{})
877877

878878
ok, found := containsElement(s, contains)
879879
if !ok {
880-
return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...)
880+
return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...)
881881
}
882882
if found {
883-
return Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...)
883+
return Fail(t, fmt.Sprintf("%#v should not contain %#v", s, contains), msgAndArgs...)
884884
}
885885

886886
return true

assert/assertions_test.go

+52-7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"io"
1010
"math"
1111
"os"
12+
"path/filepath"
1213
"reflect"
1314
"regexp"
1415
"runtime"
@@ -688,15 +689,59 @@ func TestContainsNotContains(t *testing.T) {
688689
}
689690
}
690691

691-
func TestContainsFailMessage(t *testing.T) {
692-
692+
func TestContainsNotContainsFailMessage(t *testing.T) {
693693
mockT := new(mockTestingT)
694694

695-
Contains(mockT, "Hello World", errors.New("Hello"))
696-
expectedFail := "\"Hello World\" does not contain &errors.errorString{s:\"Hello\"}"
697-
actualFail := mockT.errorString()
698-
if !strings.Contains(actualFail, expectedFail) {
699-
t.Errorf("Contains failure should include %q but was %q", expectedFail, actualFail)
695+
type nonContainer struct {
696+
Value string
697+
}
698+
699+
cases := []struct {
700+
assertion func(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool
701+
container interface{}
702+
instance interface{}
703+
expected string
704+
}{
705+
{
706+
assertion: Contains,
707+
container: "Hello World",
708+
instance: errors.New("Hello"),
709+
expected: "\"Hello World\" does not contain &errors.errorString{s:\"Hello\"}",
710+
},
711+
{
712+
assertion: Contains,
713+
container: map[string]int{"one": 1},
714+
instance: "two",
715+
expected: "map[string]int{\"one\":1} does not contain \"two\"\n",
716+
},
717+
{
718+
assertion: NotContains,
719+
container: map[string]int{"one": 1},
720+
instance: "one",
721+
expected: "map[string]int{\"one\":1} should not contain \"one\"",
722+
},
723+
{
724+
assertion: Contains,
725+
container: nonContainer{Value: "Hello"},
726+
instance: "Hello",
727+
expected: "assert.nonContainer{Value:\"Hello\"} could not be applied builtin len()\n",
728+
},
729+
{
730+
assertion: NotContains,
731+
container: nonContainer{Value: "Hello"},
732+
instance: "Hello",
733+
expected: "assert.nonContainer{Value:\"Hello\"} could not be applied builtin len()\n",
734+
},
735+
}
736+
for _, c := range cases {
737+
name := filepath.Base(runtime.FuncForPC(reflect.ValueOf(c.assertion).Pointer()).Name())
738+
t.Run(fmt.Sprintf("%v(%T, %T)", name, c.container, c.instance), func(t *testing.T) {
739+
c.assertion(mockT, c.container, c.instance)
740+
actualFail := mockT.errorString()
741+
if !strings.Contains(actualFail, c.expected) {
742+
t.Errorf("Contains failure should include %q but was %q", c.expected, actualFail)
743+
}
744+
})
700745
}
701746
}
702747

0 commit comments

Comments
 (0)