1package errors 2 3import ( 4 "errors" 5 "fmt" 6 "io" 7 "reflect" 8 "testing" 9) 10 11func TestNew(t *testing.T) { 12 tests := []struct { 13 err string 14 want error 15 }{ 16 {"", fmt.Errorf("")}, 17 {"foo", fmt.Errorf("foo")}, 18 {"foo", New("foo")}, 19 {"string with format specifiers: %v", errors.New("string with format specifiers: %v")}, 20 } 21 22 for _, tt := range tests { 23 got := New(tt.err) 24 if got.Error() != tt.want.Error() { 25 t.Errorf("New.Error(): got: %q, want %q", got, tt.want) 26 } 27 } 28} 29 30func TestWrapNil(t *testing.T) { 31 got := Wrap(nil, "no error") 32 if got != nil { 33 t.Errorf("Wrap(nil, \"no error\"): got %#v, expected nil", got) 34 } 35} 36 37func TestWrap(t *testing.T) { 38 tests := []struct { 39 err error 40 message string 41 want string 42 }{ 43 {io.EOF, "read error", "read error: EOF"}, 44 {Wrap(io.EOF, "read error"), "client error", "client error: read error: EOF"}, 45 } 46 47 for _, tt := range tests { 48 got := Wrap(tt.err, tt.message).Error() 49 if got != tt.want { 50 t.Errorf("Wrap(%v, %q): got: %v, want %v", tt.err, tt.message, got, tt.want) 51 } 52 } 53} 54 55type nilError struct{} 56 57func (nilError) Error() string { return "nil error" } 58 59func TestCause(t *testing.T) { 60 x := New("error") 61 tests := []struct { 62 err error 63 want error 64 }{{ 65 // nil error is nil 66 err: nil, 67 want: nil, 68 }, { 69 // explicit nil error is nil 70 err: (error)(nil), 71 want: nil, 72 }, { 73 // typed nil is nil 74 err: (*nilError)(nil), 75 want: (*nilError)(nil), 76 }, { 77 // uncaused error is unaffected 78 err: io.EOF, 79 want: io.EOF, 80 }, { 81 // caused error returns cause 82 err: Wrap(io.EOF, "ignored"), 83 want: io.EOF, 84 }, { 85 err: x, // return from errors.New 86 want: x, 87 }, { 88 WithMessage(nil, "whoops"), 89 nil, 90 }, { 91 WithMessage(io.EOF, "whoops"), 92 io.EOF, 93 }, { 94 WithStack(nil), 95 nil, 96 }, { 97 WithStack(io.EOF), 98 io.EOF, 99 }} 100 101 for i, tt := range tests { 102 got := Cause(tt.err) 103 if !reflect.DeepEqual(got, tt.want) { 104 t.Errorf("test %d: got %#v, want %#v", i+1, got, tt.want) 105 } 106 } 107} 108 109func TestWrapfNil(t *testing.T) { 110 got := Wrapf(nil, "no error") 111 if got != nil { 112 t.Errorf("Wrapf(nil, \"no error\"): got %#v, expected nil", got) 113 } 114} 115 116func TestWrapf(t *testing.T) { 117 tests := []struct { 118 err error 119 message string 120 want string 121 }{ 122 {io.EOF, "read error", "read error: EOF"}, 123 {Wrapf(io.EOF, "read error without format specifiers"), "client error", "client error: read error without format specifiers: EOF"}, 124 {Wrapf(io.EOF, "read error with %d format specifier", 1), "client error", "client error: read error with 1 format specifier: EOF"}, 125 } 126 127 for _, tt := range tests { 128 got := Wrapf(tt.err, tt.message).Error() 129 if got != tt.want { 130 t.Errorf("Wrapf(%v, %q): got: %v, want %v", tt.err, tt.message, got, tt.want) 131 } 132 } 133} 134 135func TestErrorf(t *testing.T) { 136 tests := []struct { 137 err error 138 want string 139 }{ 140 {Errorf("read error without format specifiers"), "read error without format specifiers"}, 141 {Errorf("read error with %d format specifier", 1), "read error with 1 format specifier"}, 142 } 143 144 for _, tt := range tests { 145 got := tt.err.Error() 146 if got != tt.want { 147 t.Errorf("Errorf(%v): got: %q, want %q", tt.err, got, tt.want) 148 } 149 } 150} 151 152func TestWithStackNil(t *testing.T) { 153 got := WithStack(nil) 154 if got != nil { 155 t.Errorf("WithStack(nil): got %#v, expected nil", got) 156 } 157} 158 159func TestWithStack(t *testing.T) { 160 tests := []struct { 161 err error 162 want string 163 }{ 164 {io.EOF, "EOF"}, 165 {WithStack(io.EOF), "EOF"}, 166 } 167 168 for _, tt := range tests { 169 got := WithStack(tt.err).Error() 170 if got != tt.want { 171 t.Errorf("WithStack(%v): got: %v, want %v", tt.err, got, tt.want) 172 } 173 } 174} 175 176func TestWithMessageNil(t *testing.T) { 177 got := WithMessage(nil, "no error") 178 if got != nil { 179 t.Errorf("WithMessage(nil, \"no error\"): got %#v, expected nil", got) 180 } 181} 182 183func TestWithMessage(t *testing.T) { 184 tests := []struct { 185 err error 186 message string 187 want string 188 }{ 189 {io.EOF, "read error", "read error: EOF"}, 190 {WithMessage(io.EOF, "read error"), "client error", "client error: read error: EOF"}, 191 } 192 193 for _, tt := range tests { 194 got := WithMessage(tt.err, tt.message).Error() 195 if got != tt.want { 196 t.Errorf("WithMessage(%v, %q): got: %q, want %q", tt.err, tt.message, got, tt.want) 197 } 198 } 199} 200 201func TestWithMessagefNil(t *testing.T) { 202 got := WithMessagef(nil, "no error") 203 if got != nil { 204 t.Errorf("WithMessage(nil, \"no error\"): got %#v, expected nil", got) 205 } 206} 207 208func TestWithMessagef(t *testing.T) { 209 tests := []struct { 210 err error 211 message string 212 want string 213 }{ 214 {io.EOF, "read error", "read error: EOF"}, 215 {WithMessagef(io.EOF, "read error without format specifier"), "client error", "client error: read error without format specifier: EOF"}, 216 {WithMessagef(io.EOF, "read error with %d format specifier", 1), "client error", "client error: read error with 1 format specifier: EOF"}, 217 } 218 219 for _, tt := range tests { 220 got := WithMessagef(tt.err, tt.message).Error() 221 if got != tt.want { 222 t.Errorf("WithMessage(%v, %q): got: %q, want %q", tt.err, tt.message, got, tt.want) 223 } 224 } 225} 226 227// errors.New, etc values are not expected to be compared by value 228// but the change in errors#27 made them incomparable. Assert that 229// various kinds of errors have a functional equality operator, even 230// if the result of that equality is always false. 231func TestErrorEquality(t *testing.T) { 232 vals := []error{ 233 nil, 234 io.EOF, 235 errors.New("EOF"), 236 New("EOF"), 237 Errorf("EOF"), 238 Wrap(io.EOF, "EOF"), 239 Wrapf(io.EOF, "EOF%d", 2), 240 WithMessage(nil, "whoops"), 241 WithMessage(io.EOF, "whoops"), 242 WithStack(io.EOF), 243 WithStack(nil), 244 } 245 246 for i := range vals { 247 for j := range vals { 248 _ = vals[i] == vals[j] // mustn't panic 249 } 250 } 251} 252