errors: improve As tests
Check the value of target after As returns true.
Change-Id: I76a2b25fe825ee1dbb5f39f8f0b211c55bd25a4f
Reviewed-on: https://go-review.googlesource.com/c/go/+/181299
Reviewed-by: Bryan C. Mills <bcmills@google.com>
diff --git a/src/errors/wrap_test.go b/src/errors/wrap_test.go
index d349414..590c185 100644
--- a/src/errors/wrap_test.go
+++ b/src/errors/wrap_test.go
@@ -8,6 +8,7 @@
"errors"
"fmt"
"os"
+ "reflect"
"testing"
)
@@ -60,6 +61,8 @@
f func(error) bool
}
+var poserPathErr = &os.PathError{Op: "poser"}
+
func (p *poser) Error() string { return p.msg }
func (p *poser) Is(err error) bool { return p.f(err) }
func (p *poser) As(err interface{}) bool {
@@ -67,9 +70,9 @@
case **poser:
*x = p
case *errorT:
- *x = errorT{}
+ *x = errorT{"poser"}
case **os.PathError:
- *x = &os.PathError{}
+ *x = poserPathErr
default:
return false
}
@@ -82,58 +85,74 @@
var timeout interface{ Timeout() bool }
var p *poser
_, errF := os.Open("non-existing")
+ poserErr := &poser{"oh no", nil}
testCases := []struct {
err error
target interface{}
match bool
+ want interface{} // value of target on match
}{{
nil,
&errP,
false,
+ nil,
}, {
- wrapped{"pittied the fool", errorT{}},
+ wrapped{"pitied the fool", errorT{"T"}},
&errT,
true,
+ errorT{"T"},
}, {
errF,
&errP,
true,
+ errF,
}, {
errorT{},
&errP,
false,
+ nil,
}, {
wrapped{"wrapped", nil},
&errT,
false,
+ nil,
}, {
&poser{"error", nil},
&errT,
true,
+ errorT{"poser"},
}, {
&poser{"path", nil},
&errP,
true,
+ poserPathErr,
}, {
- &poser{"oh no", nil},
+ poserErr,
&p,
true,
+ poserErr,
}, {
errors.New("err"),
&timeout,
false,
+ nil,
}, {
errF,
&timeout,
true,
+ errF,
}, {
wrapped{"path error", errF},
&timeout,
true,
+ errF,
}}
for i, tc := range testCases {
name := fmt.Sprintf("%d:As(Errorf(..., %v), %v)", i, tc.err, tc.target)
+ // Clear the target pointer, in case it was set in a previous test.
+ rtarget := reflect.ValueOf(tc.target)
+ rtarget.Elem().Set(reflect.Zero(reflect.TypeOf(tc.target).Elem()))
t.Run(name, func(t *testing.T) {
match := errors.As(tc.err, tc.target)
if match != tc.match {
@@ -142,8 +161,8 @@
if !match {
return
}
- if tc.target == nil {
- t.Fatalf("non-nil result after match")
+ if got := rtarget.Elem().Interface(); got != tc.want {
+ t.Fatalf("got %#v, want %#v", got, tc.want)
}
})
}
@@ -193,9 +212,9 @@
}
}
-type errorT struct{}
+type errorT struct{ s string }
-func (errorT) Error() string { return "errorT" }
+func (e errorT) Error() string { return fmt.Sprintf("errorT(%s)", e.s) }
type wrapped struct {
msg string