-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #171 from SimonRichardson/errors-is-checker
error.Is testing checker
- Loading branch information
Showing
2 changed files
with
121 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// Copyright 2023 Canonical Ltd. | ||
// Licensed under the LGPLv3, see LICENCE file for details. | ||
|
||
package checkers | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"reflect" | ||
|
||
gc "gopkg.in/check.v1" | ||
) | ||
|
||
type errorIsChecker struct { | ||
*gc.CheckerInfo | ||
} | ||
|
||
// ErrorIs checks whether a value is an error that matches the other | ||
// argument. | ||
var ErrorIs gc.Checker = &errorIsChecker{ | ||
CheckerInfo: &gc.CheckerInfo{ | ||
Name: "ErrorIs", | ||
Params: []string{"obtained", "error"}, | ||
}, | ||
} | ||
|
||
var ( | ||
errType = reflect.TypeOf((*error)(nil)).Elem() | ||
) | ||
|
||
func (checker *errorIsChecker) Check(params []interface{}, names []string) (result bool, err string) { | ||
if params[1] == nil || params[0] == nil { | ||
return params[1] == params[0], "" | ||
} | ||
|
||
f := reflect.ValueOf(params[1]) | ||
ft := f.Type() | ||
if !ft.Implements(errType) { | ||
return false, fmt.Sprintf("wrong error target type, got: %s", ft) | ||
} | ||
|
||
v := reflect.ValueOf(params[0]) | ||
vt := v.Type() | ||
if !v.IsValid() { | ||
return false, fmt.Sprintf("wrong argument type %s for %s", vt, ft) | ||
} | ||
if !vt.Implements(errType) { | ||
return false, fmt.Sprintf("wrong argument type %s for %s", vt, ft) | ||
} | ||
|
||
return errors.Is(v.Interface().(error), f.Interface().(error)), "" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package checkers_test | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/juju/errors" | ||
jc "github.com/juju/testing/checkers" | ||
gc "gopkg.in/check.v1" | ||
) | ||
|
||
type ErrorSuite struct{} | ||
|
||
var _ = gc.Suite(&ErrorSuite{}) | ||
|
||
var errorIsTests = []struct { | ||
arg interface{} | ||
target interface{} | ||
result bool | ||
msg string | ||
}{{ | ||
arg: fmt.Errorf("bar"), | ||
target: nil, | ||
result: false, | ||
}, { | ||
arg: nil, | ||
target: fmt.Errorf("bar"), | ||
result: false, | ||
}, { | ||
arg: nil, | ||
target: nil, | ||
result: true, | ||
}, { | ||
arg: fmt.Errorf("bar"), | ||
target: fmt.Errorf("foo"), | ||
result: false, | ||
}, { | ||
arg: errors.ConstError("bar"), | ||
target: errors.ConstError("foo"), | ||
result: false, | ||
}, { | ||
arg: errors.ConstError("foo"), | ||
target: errors.ConstError("foo"), | ||
result: true, | ||
}, { | ||
arg: errors.Trace(errors.ConstError("foo")), | ||
target: errors.ConstError("foo"), | ||
result: true, | ||
}, { | ||
arg: errors.ConstError("foo"), | ||
target: "blah", | ||
msg: "wrong error target type, got: string", | ||
}, { | ||
arg: "blah", | ||
target: errors.ConstError("foo"), | ||
msg: "wrong argument type string for errors.ConstError", | ||
}, { | ||
arg: (*error)(nil), | ||
target: errors.ConstError("foo"), | ||
msg: "wrong argument type *error for errors.ConstError", | ||
}} | ||
|
||
func (s *ErrorSuite) TestErrorIs(c *gc.C) { | ||
for i, test := range errorIsTests { | ||
c.Logf("test %d. %T %T", i, test.arg, test.target) | ||
result, msg := jc.ErrorIs.Check([]interface{}{test.arg, test.target}, nil) | ||
c.Check(result, gc.Equals, test.result) | ||
c.Check(msg, gc.Equals, test.msg) | ||
} | ||
} |