-
Notifications
You must be signed in to change notification settings - Fork 0
/
kerrors_test.go
131 lines (110 loc) · 3.44 KB
/
kerrors_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package kerrors
import (
"errors"
"regexp"
"strings"
"testing"
"github.com/stretchr/testify/require"
)
type (
testErr struct{}
)
func (e testErr) Error() string {
return "test struct err"
}
func TestError(t *testing.T) {
t.Parallel()
stackRegex := regexp.MustCompile(`Stack trace\n\[\[\n\S+ \S+:\d+\n\]\]`)
errorsErr := errors.New("test errors err")
nestedErr := WithKind(WithMsg(errorsErr, "another message"), testErr{}, "test error message")
for _, tc := range []struct {
Test string
Opts []ErrorOpt
Msg string
Kind error
ErrMsg string
}{
{
Test: "produces an error with an errors kind and message",
Opts: []ErrorOpt{OptMsg("test message 123"), OptKind(errorsErr)},
Msg: "test message 123",
Kind: errorsErr,
ErrMsg: "test message 123\n[[\ntest errors err\n]]\n--\n%!(STACKTRACE)",
},
{
Test: "produces an error with an error struct kind and message",
Opts: []ErrorOpt{OptMsg("test message 321"), OptKind(testErr{})},
Msg: "test message 321",
Kind: testErr{},
ErrMsg: "test message 321\n[[\ntest struct err\n]]\n--\n%!(STACKTRACE)",
},
{
Test: "produces an error with a deeply nested error",
Opts: []ErrorOpt{OptMsg("test message 654"), OptKind(errors.New("other error")), OptInner(nestedErr)},
Msg: "test message 654",
Kind: testErr{},
ErrMsg: "test message 654\n[[\nother error\n]]\n--\ntest error message\n[[\ntest struct err\n]]\n--\nanother message\n--\n%!(STACKTRACE)\n--\ntest errors err",
},
{
Test: "ignores kind if not provided",
Opts: []ErrorOpt{OptMsg("test message 654"), OptInner(nestedErr)},
Msg: "test message 654",
Kind: testErr{},
ErrMsg: "test message 654\n--\ntest error message\n[[\ntest struct err\n]]\n--\nanother message\n--\n%!(STACKTRACE)\n--\ntest errors err",
},
} {
t.Run(tc.Test, func(t *testing.T) {
t.Parallel()
assert := require.New(t)
err := New(tc.Opts...)
assert.Error(err)
var msger ErrorMsger
assert.ErrorAs(err, &msger)
assert.Equal(tc.Msg, msger.ErrorMsg())
var stackstringer StackStringer
assert.ErrorAs(err, &stackstringer)
var k *Error
assert.ErrorAs(err, &k)
assert.Equal(tc.Msg, k.Message)
errMsg := err.Error()
assert.Regexp(stackRegex, errMsg)
stackstr := stackRegex.FindString(errMsg)
assert.Contains(stackstr, "xorkevin.dev/kerrors/kerrors_test.go")
assert.Contains(stackstr, "xorkevin.dev/kerrors.TestError")
assert.Equal(tc.ErrMsg, stackRegex.ReplaceAllString(errMsg, "%!(STACKTRACE)"))
if tc.Kind != nil {
assert.ErrorIs(err, tc.Kind)
}
var s *StackTrace
assert.ErrorAs(err, &s)
})
}
}
func TestStackTrace(t *testing.T) {
t.Parallel()
stackRegex := regexp.MustCompile(`^(?:\S+\n\t\S+:\d+\n)+$`)
t.Run("StackString", func(t *testing.T) {
t.Parallel()
assert := require.New(t)
st := NewStackTrace(0)
stackstr := st.StackString()
assert.Regexp(stackRegex, stackstr)
assert.Contains(stackstr, "xorkevin.dev/kerrors/kerrors_test.go")
assert.True(strings.HasPrefix(stackstr, "xorkevin.dev/kerrors.TestStackTrace"))
})
t.Run("empty stack", func(t *testing.T) {
t.Parallel()
assert := require.New(t)
st := NewStackTrace(8)
assert.Equal("", st.Error())
assert.Equal("", st.StackString())
})
t.Run("As", func(t *testing.T) {
t.Parallel()
assert := require.New(t)
st := NewStackTrace(0)
var stackstringer StackStringer
assert.ErrorAs(st, &stackstringer)
assert.True(stackstringer == st)
})
}