Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make IsNil guard against nil underlying errors #64

Merged
merged 1 commit into from
Mar 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,12 @@ func (c *panicMatchesChecker) Check(got interface{}, args []interface{}, note fu
//
// c.Assert(got, qt.IsNil)
//
// As a special case, if the value is nil but implements the
// error interface, it is still considered to be non-nil.
// This means that IsNil will fail on an error value that happens
// to have an underlying nil value, because that's
// invariably a mistake.
// See https://golang.org/doc/faq#nil_error.
var IsNil Checker = &isNilChecker{
argNames: []string{"got"},
}
Expand All @@ -267,6 +273,10 @@ func (c *isNilChecker) Check(got interface{}, args []interface{}, note func(key
}
value := reflect.ValueOf(got)
if canBeNil(value.Kind()) && value.IsNil() {
if _, ok := got.(error); ok {
// It's an error with an underlying nil value.
return fmt.Errorf("error containing nil value of type %T. See https://golang.org/doc/faq#nil_error", got)
}
return nil
}
return fmt.Errorf("%#v is not nil", got)
Expand Down
6 changes: 3 additions & 3 deletions checker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1327,12 +1327,12 @@ got:
[]int(nil)
`,
}, {
about: "IsNil: error does not guard against nil",
about: "IsNil: nil error-implementing type",
checker: qt.IsNil,
got: (*errTest)(nil),
expectedNegateFailure: `
expectedCheckFailure: `
error:
unexpected success
error containing nil value of type *quicktest_test.errTest. See https://golang.org/doc/faq#nil_error
got:
e<nil>
`,
Expand Down
18 changes: 18 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,14 @@ For example:
c.Assert("hello world", qt.Contains, "world")
c.Assert([]int{3,5,7,99}, qt.Contains, 7)

ContentEquals

ContentEquals is is like DeepEquals but any slices in the compared values will be sorted before being compared.

For example:

c.Assert([]string{"c", "a", "b"}, qt.ContentEquals, []string{"a", "b", "c"})

DeepEquals

DeepEquals checks that two arbitrary values are deeply equal.
Expand Down Expand Up @@ -192,6 +200,16 @@ For instance:

c.Assert(got, qt.IsNil)

As a special case, if the value is nil but implements the
error interface, it is still considered to be non-nil.
This means that IsNil will fail on an error value that happens
to have an underlying nil value, because that's
invariably a mistake. See https://golang.org/doc/faq#nil_error.

So it's just fine to check an error like this:

c.Assert(err, qt.IsNil)

JSONEquals

JSONEquals checks whether a byte slice or string is JSON-equivalent to a Go
Expand Down