226 lines
4.7 KiB
Go
226 lines
4.7 KiB
Go
package errors
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
func TestNew(t *testing.T) {
|
|
tests := []struct {
|
|
err string
|
|
want error
|
|
}{
|
|
{"", fmt.Errorf("")},
|
|
{"foo", fmt.Errorf("foo")},
|
|
{"foo", New("foo")},
|
|
{"string with format specifiers: %v", errors.New("string with format specifiers: %v")},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
got := New(tt.err)
|
|
if got.Error() != tt.want.Error() {
|
|
t.Errorf("New.Error(): got: %q, want %q", got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestWrapNil(t *testing.T) {
|
|
got := Wrap(nil, "no error")
|
|
if got != nil {
|
|
t.Errorf("Wrap(nil, \"no error\"): got %#v, expected nil", got)
|
|
}
|
|
}
|
|
|
|
func TestWrap(t *testing.T) {
|
|
tests := []struct {
|
|
err error
|
|
message string
|
|
want string
|
|
}{
|
|
{io.EOF, "read error", "read error: EOF"},
|
|
{Wrap(io.EOF, "read error"), "client error", "client error: read error: EOF"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
got := Wrap(tt.err, tt.message).Error()
|
|
if got != tt.want {
|
|
t.Errorf("Wrap(%v, %q): got: %v, want %v", tt.err, tt.message, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
type nilError struct{}
|
|
|
|
func (nilError) Error() string { return "nil error" }
|
|
|
|
func TestCause(t *testing.T) {
|
|
x := New("error")
|
|
tests := []struct {
|
|
err error
|
|
want error
|
|
}{{
|
|
// nil error is nil
|
|
err: nil,
|
|
want: nil,
|
|
}, {
|
|
// explicit nil error is nil
|
|
err: (error)(nil),
|
|
want: nil,
|
|
}, {
|
|
// typed nil is nil
|
|
err: (*nilError)(nil),
|
|
want: (*nilError)(nil),
|
|
}, {
|
|
// uncaused error is unaffected
|
|
err: io.EOF,
|
|
want: io.EOF,
|
|
}, {
|
|
// caused error returns cause
|
|
err: Wrap(io.EOF, "ignored"),
|
|
want: io.EOF,
|
|
}, {
|
|
err: x, // return from errors.New
|
|
want: x,
|
|
}, {
|
|
WithMessage(nil, "whoops"),
|
|
nil,
|
|
}, {
|
|
WithMessage(io.EOF, "whoops"),
|
|
io.EOF,
|
|
}, {
|
|
WithStack(nil),
|
|
nil,
|
|
}, {
|
|
WithStack(io.EOF),
|
|
io.EOF,
|
|
}}
|
|
|
|
for i, tt := range tests {
|
|
got := Cause(tt.err)
|
|
if !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("test %d: got %#v, want %#v", i+1, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestWrapfNil(t *testing.T) {
|
|
got := Wrapf(nil, "no error")
|
|
if got != nil {
|
|
t.Errorf("Wrapf(nil, \"no error\"): got %#v, expected nil", got)
|
|
}
|
|
}
|
|
|
|
func TestWrapf(t *testing.T) {
|
|
tests := []struct {
|
|
err error
|
|
message string
|
|
want string
|
|
}{
|
|
{io.EOF, "read error", "read error: EOF"},
|
|
{Wrapf(io.EOF, "read error without format specifiers"), "client error", "client error: read error without format specifiers: EOF"},
|
|
{Wrapf(io.EOF, "read error with %d format specifier", 1), "client error", "client error: read error with 1 format specifier: EOF"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
got := Wrapf(tt.err, tt.message).Error()
|
|
if got != tt.want {
|
|
t.Errorf("Wrapf(%v, %q): got: %v, want %v", tt.err, tt.message, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestErrorf(t *testing.T) {
|
|
tests := []struct {
|
|
err error
|
|
want string
|
|
}{
|
|
{Errorf("read error without format specifiers"), "read error without format specifiers"},
|
|
{Errorf("read error with %d format specifier", 1), "read error with 1 format specifier"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
got := tt.err.Error()
|
|
if got != tt.want {
|
|
t.Errorf("Errorf(%v): got: %q, want %q", tt.err, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestWithStackNil(t *testing.T) {
|
|
got := WithStack(nil)
|
|
if got != nil {
|
|
t.Errorf("WithStack(nil): got %#v, expected nil", got)
|
|
}
|
|
}
|
|
|
|
func TestWithStack(t *testing.T) {
|
|
tests := []struct {
|
|
err error
|
|
want string
|
|
}{
|
|
{io.EOF, "EOF"},
|
|
{WithStack(io.EOF), "EOF"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
got := WithStack(tt.err).Error()
|
|
if got != tt.want {
|
|
t.Errorf("WithStack(%v): got: %v, want %v", tt.err, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestWithMessageNil(t *testing.T) {
|
|
got := WithMessage(nil, "no error")
|
|
if got != nil {
|
|
t.Errorf("WithMessage(nil, \"no error\"): got %#v, expected nil", got)
|
|
}
|
|
}
|
|
|
|
func TestWithMessage(t *testing.T) {
|
|
tests := []struct {
|
|
err error
|
|
message string
|
|
want string
|
|
}{
|
|
{io.EOF, "read error", "read error: EOF"},
|
|
{WithMessage(io.EOF, "read error"), "client error", "client error: read error: EOF"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
got := WithMessage(tt.err, tt.message).Error()
|
|
if got != tt.want {
|
|
t.Errorf("WithMessage(%v, %q): got: %q, want %q", tt.err, tt.message, got, tt.want)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// errors.New, etc values are not expected to be compared by value
|
|
// but the change in errors#27 made them incomparable. Assert that
|
|
// various kinds of errors have a functional equality operator, even
|
|
// if the result of that equality is always false.
|
|
func TestErrorEquality(t *testing.T) {
|
|
vals := []error{
|
|
nil,
|
|
io.EOF,
|
|
errors.New("EOF"),
|
|
New("EOF"),
|
|
Errorf("EOF"),
|
|
Wrap(io.EOF, "EOF"),
|
|
Wrapf(io.EOF, "EOF%d", 2),
|
|
WithMessage(nil, "whoops"),
|
|
WithMessage(io.EOF, "whoops"),
|
|
WithStack(io.EOF),
|
|
WithStack(nil),
|
|
}
|
|
|
|
for i := range vals {
|
|
for j := range vals {
|
|
_ = vals[i] == vals[j] // mustn't panic
|
|
}
|
|
}
|
|
}
|