238 lines
6 KiB
Go
238 lines
6 KiB
Go
package errors
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
var err = fmt.Errorf("test error")
|
|
|
|
func TestFormat(t *testing.T) {
|
|
IncludeBacktrace = false
|
|
// %+s check for unwrapped error
|
|
e1 := Newf("test")
|
|
str := fmt.Sprintf("%+s", e1)
|
|
if str != e1.m {
|
|
t.Errorf("Error message invalid %s, expected %s", str, e1.m)
|
|
}
|
|
|
|
// %+s check for wrapped error
|
|
e2 := Annotatef(e1, "another")
|
|
str = fmt.Sprintf("%+s", e2)
|
|
val := e2.m + ": " + e2.c.Error()
|
|
if str != val {
|
|
t.Errorf("Error message invalid %s, expected %s", str, val)
|
|
}
|
|
|
|
// %v check for unwrapped error with trace
|
|
IncludeBacktrace = true
|
|
e3 := Newf("test1")
|
|
str = fmt.Sprintf("%+v", e3)
|
|
if !strings.Contains(str, e3.m) {
|
|
t.Errorf("Error message %s\n should contain %s", str, e3.m)
|
|
}
|
|
if !strings.Contains(str, fmt.Sprintf("%+v", e3.t.StackTrace())) {
|
|
t.Errorf("Error message %s\n should contain %+v", str, e3.t.StackTrace())
|
|
}
|
|
}
|
|
|
|
func TestMarshalJSON(t *testing.T) {
|
|
IncludeBacktrace = true
|
|
e := Newf("test")
|
|
|
|
b, err := e.t.StackTrace().MarshalJSON()
|
|
if err != nil {
|
|
t.Errorf("MarshalJSON failed with error: %+s", err)
|
|
}
|
|
stack := make([]json.RawMessage, 0)
|
|
err = json.Unmarshal(b, &stack)
|
|
if err != nil {
|
|
t.Errorf("JSON message could not be unmarshaled: %+s", err)
|
|
}
|
|
if len(stack) != len(e.t) {
|
|
t.Errorf("Count of stack frames different after marshaling, expected %d got %d", len(e.t), len(stack))
|
|
}
|
|
}
|
|
|
|
func TestAnnotatef(t *testing.T) {
|
|
testStr := "Annotatef string"
|
|
te := Annotatef(err, testStr)
|
|
if te.c != err {
|
|
t.Errorf("Invalid parent error %T:%s, expected %T:%s", te.c, te.c, err, err)
|
|
}
|
|
if te.m != testStr {
|
|
t.Errorf("Invalid error message %s, expected %s", te.m, testStr)
|
|
}
|
|
}
|
|
|
|
var homeVal = "$HOME"
|
|
|
|
func TestNewf(t *testing.T) {
|
|
testStr := "Newf string"
|
|
te := Newf(testStr)
|
|
if te.c != nil {
|
|
t.Errorf("Invalid parent error %T:%s, expected nil", te.c, te.c)
|
|
}
|
|
if te.m != testStr {
|
|
t.Errorf("Invalid error message %s, expected %s", te.m, testStr)
|
|
}
|
|
}
|
|
|
|
func TestErrorf(t *testing.T) {
|
|
testStr := "Errorf string"
|
|
err := Errorf(testStr)
|
|
if te, ok := err.(*Err); ok {
|
|
if te.c != nil {
|
|
t.Errorf("Invalid parent error %T:%s, expected nil", te.c, te.c)
|
|
}
|
|
if te.m != testStr {
|
|
t.Errorf("Invalid error message %s, expected %s", te.m, testStr)
|
|
}
|
|
} else {
|
|
t.Errorf("Invalid error type returned %T, expected type %T", err, &Err{})
|
|
}
|
|
}
|
|
|
|
/*
|
|
func TestErr_As(t *testing.T) {
|
|
e := Err{m: "test", l: 11, f: "random", t: []uintptr{0x6, 0x6, 0x6}, c: fmt.Errorf("ttt")}
|
|
if e.As(&err) {
|
|
t.Errorf("%T should not be assertable as %T", err, e)
|
|
}
|
|
type clone = Err
|
|
e1 := clone{}
|
|
if !e.As(&e1) {
|
|
t.Errorf("%T should be assertable as %T", e, e1)
|
|
}
|
|
if e1.m != e.m {
|
|
t.Errorf("%T message should equal %T's, received %s, expected %s", e1, e, e1.m, e.m)
|
|
}
|
|
if e1.l != e.l {
|
|
t.Errorf("%T line should equal %T's, received %d, expected %d", e1, e, e1.l, e.l)
|
|
}
|
|
if e1.f != e.f {
|
|
t.Errorf("%T file should equal %T's, received %s, expected %s", e1, e, e1.f, e.f)
|
|
}
|
|
if !bytes.Equal(e1.t, e.t) {
|
|
t.Errorf("%T trace should equal %T's, received %2x, expected %2x", e1, e, e1.t, e.t)
|
|
}
|
|
if e1.c != e.c {
|
|
t.Errorf("%T parent error should equal %T's, received %T[%s], expected %T[%s]", e1, e, e1.c, e1.c, e.c, e.c)
|
|
}
|
|
e2 := &e
|
|
if !e.As(&e2) {
|
|
t.Errorf("%T should be assertable as %T", e, e2)
|
|
}
|
|
if e2.m != e.m {
|
|
t.Errorf("%T message should equal %T's, received %s, expected %s", e2, e, e2.m, e.m)
|
|
}
|
|
if e2.l != e.l {
|
|
t.Errorf("%T line should equal %T's, received %d, expected %d", e2, e, e2.l, e.l)
|
|
}
|
|
if e2.f != e.f {
|
|
t.Errorf("%T file should equal %T's, received %s, expected %s", e2, e, e2.f, e.f)
|
|
}
|
|
if !bytes.Equal(e2.t, e.t) {
|
|
t.Errorf("%T trace should equal %T's, received %2x, expected %2x", e2, e, e2.t, e.t)
|
|
}
|
|
if e2.c != e.c {
|
|
t.Errorf("%T parent error should equal %T's, received %T[%s], expected %T[%s]", e2, e, e2.c, e2.c, e.c, e.c)
|
|
}
|
|
}
|
|
|
|
func TestErr_Error(t *testing.T) {
|
|
e := Err{m: "test"}
|
|
if e.Error() != e.m {
|
|
t.Errorf("Error() returned %s, expected %s", e.Error(), e.m)
|
|
}
|
|
}
|
|
|
|
func TestErr_Location(t *testing.T) {
|
|
e := Err{l: 11, f: "random"}
|
|
if f, l := e.Location(); l != e.l || f != e.f {
|
|
t.Errorf("Location() returned: %s:%d, expected: %s:%d", f, l, e.f, e.l)
|
|
}
|
|
}
|
|
|
|
func TestErr_StackTrace(t *testing.T) {
|
|
e := Err{t: []byte{0x6, 0x6, 0x6}}
|
|
if !bytes.Equal(e.StackTrace(), e.t) {
|
|
t.Errorf("StackTrace() returned: %2x, expected: %2x", e.StackTrace(), e.t)
|
|
}
|
|
}
|
|
|
|
func TestErr_Unwrap(t *testing.T) {
|
|
e := Err{c: fmt.Errorf("ttt")}
|
|
w := e.Unwrap()
|
|
if w != e.c {
|
|
t.Errorf("Unwrap() returned: %T[%s], expected: %T[%s]", w, w, e.c, e.c)
|
|
}
|
|
}
|
|
*/
|
|
|
|
func TestErr_Error(t *testing.T) {
|
|
type fields struct {
|
|
m string
|
|
c error
|
|
t stack
|
|
}
|
|
tests := []struct {
|
|
quiet bool
|
|
name string
|
|
fields fields
|
|
want string
|
|
}{
|
|
{
|
|
name: "empty",
|
|
fields: fields{},
|
|
want: "",
|
|
},
|
|
{
|
|
name: "just text",
|
|
fields: fields{m: "test"},
|
|
want: "test",
|
|
},
|
|
{
|
|
name: "text with single wrapped error",
|
|
fields: fields{m: "test", c: fmt.Errorf("error")},
|
|
want: "test: error",
|
|
},
|
|
{
|
|
name: "text with two wrapped errors",
|
|
fields: fields{m: "test", c: fmt.Errorf("error: %w", Newf("some error"))},
|
|
want: "test: error: some error",
|
|
},
|
|
{
|
|
name: "text with two wrapped errors, but no unwrapping",
|
|
quiet: true,
|
|
fields: fields{m: "test", c: fmt.Errorf("error: %w", Newf("some error"))},
|
|
want: "test",
|
|
},
|
|
{
|
|
name: "text with two wrapped Err errors",
|
|
fields: fields{m: "test", c: &Err{m: "error", c: &Err{m: "another error"}}},
|
|
want: "test: error: another error",
|
|
},
|
|
{
|
|
name: "text with two wrapped Err errors, without unwrapping",
|
|
quiet: true,
|
|
fields: fields{m: "test", c: &Err{m: "error", c: &Err{m: "another error"}}},
|
|
want: "test",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
IncludeBacktrace = tt.quiet
|
|
e := Err{
|
|
m: tt.fields.m,
|
|
c: tt.fields.c,
|
|
t: tt.fields.t,
|
|
}
|
|
if got := e.Error(); got != tt.want {
|
|
t.Errorf("Error() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|