Add NotErrorAs assertion

The library already had assertions for `ErrorIs`, `NotErrorIs` and
`ErrorAs`. This commit adds the `NotErrorAs` assertion which is the
inverse of `ErrorAs`.
pull/1129/head
Pal Sivertsen 2021-11-30 14:26:04 +01:00 committed by Pål Sivertsen
parent 95d1f9c2ad
commit 3380867632
6 changed files with 113 additions and 1 deletions

View File

@ -621,6 +621,15 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s
return NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)
}
// NotErrorAsf asserts that at none of the errors in err's chain matches target.
// This is the inverse of the ErrorAs function.
func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}
return NotErrorAs(t, err, target, append([]interface{}{msg}, args...)...)
}
// NotErrorIsf asserts that none of the errors in err's chain matches target.
// This is a wrapper for errors.Is.
func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool {

View File

@ -1234,6 +1234,24 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str
return NotEqualf(a.t, expected, actual, msg, args...)
}
// NotErrorAs asserts that at none of the errors in err's chain matches target.
// This is the inverse of the ErrorAs function.
func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) bool {
if h, ok := a.t.(tHelper); ok {
h.Helper()
}
return NotErrorAs(a.t, err, target, msgAndArgs...)
}
// NotErrorAsf asserts that at none of the errors in err's chain matches target.
// This is the inverse of the ErrorAs function.
func (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) bool {
if h, ok := a.t.(tHelper); ok {
h.Helper()
}
return NotErrorAsf(a.t, err, target, msg, args...)
}
// NotErrorIs asserts that none of the errors in err's chain matches target.
// This is a wrapper for errors.Is.
func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) bool {

View File

@ -2149,6 +2149,24 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{
), msgAndArgs...)
}
// NotErrorAs asserts that at none of the errors in err's chain matches target.
// This is the inverse of the ErrorAs function.
func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}
if !errors.As(err, target) {
return true
}
chain := buildErrorChainString(err)
return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+
"found: %q\n"+
"in chain: %s", target, chain,
), msgAndArgs...)
}
func buildErrorChainString(err error) string {
if err == nil {
return ""

View File

@ -3284,7 +3284,32 @@ func TestErrorAs(t *testing.T) {
t.Run(fmt.Sprintf("ErrorAs(%#v,%#v)", tt.err, target), func(t *testing.T) {
res := ErrorAs(mockT, tt.err, &target)
if res != tt.result {
t.Errorf("ErrorAs(%#v,%#v) should return %t)", tt.err, target, tt.result)
t.Errorf("ErrorAs(%#v,%#v) should return %t", tt.err, target, tt.result)
}
})
}
}
func TestNotErrorAs(t *testing.T) {
tests := []struct {
err error
result bool
}{
{fmt.Errorf("wrap: %w", &customError{}), false},
{io.EOF, true},
{nil, true},
}
for _, tt := range tests {
tt := tt
var target *customError
t.Run(fmt.Sprintf("NotErrorAs(%#v,%#v)", tt.err, target), func(t *testing.T) {
mockT := new(testing.T)
res := NotErrorAs(mockT, tt.err, &target)
if res != tt.result {
t.Errorf("NotErrorAs(%#v,%#v) should not return %t", tt.err, target, tt.result)
}
if res == mockT.Failed() {
t.Errorf("The test result (%t) should be reflected in the testing.T type (%t)", res, !mockT.Failed())
}
})
}

View File

@ -1559,6 +1559,30 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string,
t.FailNow()
}
// NotErrorAs asserts that at none of the errors in err's chain matches target.
// This is the inverse of the ErrorAs function.
func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) {
if h, ok := t.(tHelper); ok {
h.Helper()
}
if assert.NotErrorAs(t, err, target, msgAndArgs...) {
return
}
t.FailNow()
}
// NotErrorAsf asserts that at none of the errors in err's chain matches target.
// This is the inverse of the ErrorAs function.
func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) {
if h, ok := t.(tHelper); ok {
h.Helper()
}
if assert.NotErrorAsf(t, err, target, msg, args...) {
return
}
t.FailNow()
}
// NotErrorIs asserts that none of the errors in err's chain matches target.
// This is a wrapper for errors.Is.
func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) {

View File

@ -1235,6 +1235,24 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str
NotEqualf(a.t, expected, actual, msg, args...)
}
// NotErrorAs asserts that at none of the errors in err's chain matches target.
// This is the inverse of the ErrorAs function.
func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) {
if h, ok := a.t.(tHelper); ok {
h.Helper()
}
NotErrorAs(a.t, err, target, msgAndArgs...)
}
// NotErrorAsf asserts that at none of the errors in err's chain matches target.
// This is the inverse of the ErrorAs function.
func (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) {
if h, ok := a.t.(tHelper); ok {
h.Helper()
}
NotErrorAsf(a.t, err, target, msg, args...)
}
// NotErrorIs asserts that none of the errors in err's chain matches target.
// This is a wrapper for errors.Is.
func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) {