代码拉取完成,页面将自动刷新
// Copyright 2014 Roger Peppe.
// See LICENCE file for details.
package errgo_test
import (
"fmt"
"io/ioutil"
"runtime"
"strings"
"testing"
qt "github.com/frankban/quicktest"
"gopkg.in/errgo.v1"
)
var (
_ errgo.Wrapper = (*errgo.Err)(nil)
_ errgo.Locationer = (*errgo.Err)(nil)
_ errgo.Causer = (*errgo.Err)(nil)
)
func TestNew(t *testing.T) {
c := qt.New(t)
err := errgo.New("foo") //err TestNew
checkErr(c, err, nil, "foo", "[{$TestNew$: foo}]", err)
}
func TestNewf(t *testing.T) {
c := qt.New(t)
err := errgo.Newf("foo %d", 5) //err TestNewf
checkErr(c, err, nil, "foo 5", "[{$TestNewf$: foo 5}]", err)
}
var someErr = errgo.New("some error") //err varSomeErr
func annotate1() error {
err := errgo.Notef(someErr, "annotate1") //err annotate1
return err
}
func annotate2() error {
err := annotate1()
err = errgo.Notef(err, "annotate2") //err annotate2
return err
}
func TestNoteUsage(t *testing.T) {
c := qt.New(t)
err0 := annotate2()
err, ok := err0.(errgo.Wrapper)
c.Assert(ok, qt.Equals, true)
underlying := err.Underlying()
checkErr(
c, err0, underlying,
"annotate2: annotate1: some error",
"[{$annotate2$: annotate2} {$annotate1$: annotate1} {$varSomeErr$: some error}]",
err0)
}
func TestMask(t *testing.T) {
c := qt.New(t)
err0 := errgo.WithCausef(nil, someErr, "foo") //err TestMask#0
err := errgo.Mask(err0) //err TestMask#1
checkErr(c, err, err0, "foo", "[{$TestMask#1$: } {$TestMask#0$: foo}]", err)
err = errgo.Mask(nil)
c.Assert(err, qt.IsNil)
}
func TestNotef(t *testing.T) {
c := qt.New(t)
err0 := errgo.WithCausef(nil, someErr, "foo") //err TestNotef#0
err := errgo.Notef(err0, "bar") //err TestNotef#1
checkErr(c, err, err0, "bar: foo", "[{$TestNotef#1$: bar} {$TestNotef#0$: foo}]", err)
err = errgo.Notef(nil, "bar") //err TestNotef#2
checkErr(c, err, nil, "bar", "[{$TestNotef#2$: bar}]", err)
}
func TestNoteMask(t *testing.T) {
c := qt.New(t)
err0 := errgo.WithCausef(nil, someErr, "foo") //err TestNoteMask#0
err := errgo.NoteMask(err0, "bar") //err TestNoteMask#1
checkErr(c, err, err0, "bar: foo", "[{$TestNoteMask#1$: bar} {$TestNoteMask#0$: foo}]", err)
err = errgo.NoteMask(err0, "bar", errgo.Is(someErr)) //err TestNoteMask#2
checkErr(c, err, err0, "bar: foo", "[{$TestNoteMask#2$: bar} {$TestNoteMask#0$: foo}]", someErr)
err = errgo.NoteMask(err0, "") //err TestNoteMask#3
checkErr(c, err, err0, "foo", "[{$TestNoteMask#3$: } {$TestNoteMask#0$: foo}]", err)
}
func TestMaskFunc(t *testing.T) {
c := qt.New(t)
err0 := errgo.New("zero")
err1 := errgo.New("one")
allowVals := func(vals ...error) (r []func(error) bool) {
for _, val := range vals {
r = append(r, errgo.Is(val))
}
return
}
tests := []struct {
err error
allow0 []func(error) bool
allow1 []func(error) bool
cause error
}{{
err: err0,
allow0: allowVals(err0),
cause: err0,
}, {
err: err1,
allow0: allowVals(err0),
cause: nil,
}, {
err: err0,
allow1: allowVals(err0),
cause: err0,
}, {
err: err0,
allow0: allowVals(err1),
allow1: allowVals(err0),
cause: err0,
}, {
err: err0,
allow0: allowVals(err0, err1),
cause: err0,
}, {
err: err1,
allow0: allowVals(err0, err1),
cause: err1,
}, {
err: err0,
allow1: allowVals(err0, err1),
cause: err0,
}, {
err: err1,
allow1: allowVals(err0, err1),
cause: err1,
}}
for i, test := range tests {
c.Logf("test %d", i)
wrap := errgo.MaskFunc(test.allow0...)
err := wrap(test.err, test.allow1...)
cause := errgo.Cause(err)
wantCause := test.cause
if wantCause == nil {
wantCause = err
}
c.Check(cause, qt.Equals, wantCause)
}
}
type embed struct {
*errgo.Err
}
func TestCause(t *testing.T) {
c := qt.New(t)
c.Assert(errgo.Cause(someErr), qt.Equals, someErr)
causeErr := errgo.New("cause error")
underlyingErr := errgo.New("underlying error") //err TestCause#1
err := errgo.WithCausef(underlyingErr, causeErr, "foo %d", 99) //err TestCause#2
c.Assert(errgo.Cause(err), qt.Equals, causeErr)
checkErr(c, err, underlyingErr, "foo 99: underlying error", "[{$TestCause#2$: foo 99} {$TestCause#1$: underlying error}]", causeErr)
err = &embed{err.(*errgo.Err)}
c.Assert(errgo.Cause(err), qt.Equals, causeErr)
}
func TestWithCausefNoMessage(t *testing.T) {
c := qt.New(t)
cause := errgo.New("cause")
err := errgo.WithCausef(nil, cause, "")
c.Assert(err, qt.ErrorMatches, "cause")
c.Assert(errgo.Cause(err), qt.Equals, cause)
}
func TestWithCausefWithUnderlyingButNoMessage(t *testing.T) {
c := qt.New(t)
err := errgo.New("something")
cause := errgo.New("cause")
err = errgo.WithCausef(err, cause, "")
c.Assert(err, qt.ErrorMatches, "something")
c.Assert(errgo.Cause(err), qt.Equals, cause)
}
func TestDetails(t *testing.T) {
c := qt.New(t)
c.Assert(errgo.Details(nil), qt.Equals, "[]")
otherErr := fmt.Errorf("other")
checkErr(c, otherErr, nil, "other", "[{other}]", otherErr)
err0 := &embed{errgo.New("foo").(*errgo.Err)} //err TestStack#0
checkErr(c, err0, nil, "foo", "[{$TestStack#0$: foo}]", err0)
err1 := &embed{errgo.Notef(err0, "bar").(*errgo.Err)} //err TestStack#1
checkErr(c, err1, err0, "bar: foo", "[{$TestStack#1$: bar} {$TestStack#0$: foo}]", err1)
err2 := errgo.Mask(err1) //err TestStack#2
checkErr(c, err2, err1, "bar: foo", "[{$TestStack#2$: } {$TestStack#1$: bar} {$TestStack#0$: foo}]", err2)
}
func TestMatch(t *testing.T) {
c := qt.New(t)
type errTest func(error) bool
allow := func(ss ...string) []func(error) bool {
fns := make([]func(error) bool, len(ss))
for i, s := range ss {
s := s
fns[i] = func(err error) bool {
return err != nil && err.Error() == s
}
}
return fns
}
tests := []struct {
err error
fns []func(error) bool
ok bool
}{{
err: errgo.New("foo"),
fns: allow("foo"),
ok: true,
}, {
err: errgo.New("foo"),
fns: allow("bar"),
ok: false,
}, {
err: errgo.New("foo"),
fns: allow("bar", "foo"),
ok: true,
}, {
err: errgo.New("foo"),
fns: nil,
ok: false,
}, {
err: nil,
fns: nil,
ok: false,
}}
for i, test := range tests {
c.Logf("test %d", i)
c.Assert(errgo.Match(test.err, test.fns...), qt.Equals, test.ok)
}
}
func checkErr(c *qt.C, err, underlying error, msg string, details string, cause error) {
c.Assert(err, qt.Not(qt.IsNil))
c.Assert(err.Error(), qt.Equals, msg)
if err, ok := err.(errgo.Wrapper); ok {
c.Assert(err.Underlying(), qt.Equals, underlying)
} else {
c.Assert(underlying, qt.IsNil)
}
c.Assert(errgo.Cause(err), qt.Equals, cause)
wantDetails := replaceLocations(details)
c.Assert(errgo.Details(err), qt.Equals, wantDetails)
}
func replaceLocations(s string) string {
t := ""
for {
i := strings.Index(s, "$")
if i == -1 {
break
}
t += s[0:i]
s = s[i+1:]
i = strings.Index(s, "$")
if i == -1 {
panic("no second $")
}
file, line := location(s[0:i])
t += fmt.Sprintf("%s:%d", file, line)
s = s[i+1:]
}
t += s
return t
}
func location(tag string) (string, int) {
line, ok := tagToLine[tag]
if !ok {
panic(fmt.Errorf("tag %q not found", tag))
}
return filename, line
}
var tagToLine = make(map[string]int)
var filename string
func init() {
data, err := ioutil.ReadFile("errors_test.go")
if err != nil {
panic(err)
}
lines := strings.Split(string(data), "\n")
for i, line := range lines {
if j := strings.Index(line, "//err "); j >= 0 {
tagToLine[line[j+len("//err "):]] = i + 1
}
}
_, filename, _, _ = runtime.Caller(0)
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。