errors_test.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. package errors
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "reflect"
  8. "testing"
  9. )
  10. func TestNew(t *testing.T) {
  11. tests := []struct {
  12. err string
  13. want error
  14. }{
  15. {"", fmt.Errorf("")},
  16. {"foo", fmt.Errorf("foo")},
  17. {"foo", New("foo")},
  18. {"string with format specifiers: %v", errors.New("string with format specifiers: %v")},
  19. }
  20. for _, tt := range tests {
  21. got := New(tt.err)
  22. if got.Error() != tt.want.Error() {
  23. t.Errorf("New.Error(): got: %q, want %q", got, tt.want)
  24. }
  25. }
  26. }
  27. func TestWrapNil(t *testing.T) {
  28. got := Wrap(nil, "no error")
  29. if got != nil {
  30. t.Errorf("Wrap(nil, \"no error\"): got %#v, expected nil", got)
  31. }
  32. }
  33. func TestWrap(t *testing.T) {
  34. tests := []struct {
  35. err error
  36. message string
  37. want string
  38. }{
  39. {io.EOF, "read error", "read error: EOF"},
  40. {Wrap(io.EOF, "read error"), "client error", "client error: read error: EOF"},
  41. }
  42. for _, tt := range tests {
  43. got := Wrap(tt.err, tt.message).Error()
  44. if got != tt.want {
  45. t.Errorf("Wrap(%v, %q): got: %v, want %v", tt.err, tt.message, got, tt.want)
  46. }
  47. }
  48. }
  49. type nilError struct{}
  50. func (nilError) Error() string { return "nil error" }
  51. func TestCause(t *testing.T) {
  52. x := New("error")
  53. tests := []struct {
  54. err error
  55. want error
  56. }{{
  57. // nil error is nil
  58. err: nil,
  59. want: nil,
  60. }, {
  61. // explicit nil error is nil
  62. err: (error)(nil),
  63. want: nil,
  64. }, {
  65. // typed nil is nil
  66. err: (*nilError)(nil),
  67. want: (*nilError)(nil),
  68. }, {
  69. // uncaused error is unaffected
  70. err: io.EOF,
  71. want: io.EOF,
  72. }, {
  73. // caused error returns cause
  74. err: Wrap(io.EOF, "ignored"),
  75. want: io.EOF,
  76. }, {
  77. err: x, // return from errors.New
  78. want: x,
  79. }}
  80. for i, tt := range tests {
  81. got := Cause(tt.err)
  82. if !reflect.DeepEqual(got, tt.want) {
  83. t.Errorf("test %d: got %#v, want %#v", i+1, got, tt.want)
  84. }
  85. }
  86. }
  87. func TestFprintError(t *testing.T) {
  88. x := New("error")
  89. tests := []struct {
  90. err error
  91. want string
  92. }{{
  93. // nil error is nil
  94. err: nil,
  95. }, {
  96. // explicit nil error is nil
  97. err: (error)(nil),
  98. }, {
  99. // uncaused error is unaffected
  100. err: io.EOF,
  101. want: "EOF\n",
  102. }, {
  103. err: Wrap(io.EOF, "cause error"),
  104. want: "EOF\n" +
  105. "github.com/pkg/errors/errors_test.go:114: cause error\n",
  106. }, {
  107. err: x, // return from errors.New
  108. want: "github.com/pkg/errors/errors_test.go:99: error\n",
  109. }, {
  110. err: Wrap(x, "message"),
  111. want: "github.com/pkg/errors/errors_test.go:99: error\n" +
  112. "github.com/pkg/errors/errors_test.go:121: message\n",
  113. }, {
  114. err: Wrap(io.EOF, "message"),
  115. want: "EOF\n" +
  116. "github.com/pkg/errors/errors_test.go:125: message\n",
  117. }, {
  118. err: Wrap(Wrap(x, "message"), "another message"),
  119. want: "github.com/pkg/errors/errors_test.go:99: error\n" +
  120. "github.com/pkg/errors/errors_test.go:129: message\n" +
  121. "github.com/pkg/errors/errors_test.go:129: another message\n",
  122. }, {
  123. err: Wrapf(x, "message"),
  124. want: "github.com/pkg/errors/errors_test.go:99: error\n" +
  125. "github.com/pkg/errors/errors_test.go:134: message\n",
  126. }}
  127. for i, tt := range tests {
  128. var w bytes.Buffer
  129. Fprint(&w, tt.err)
  130. got := w.String()
  131. if got != tt.want {
  132. t.Errorf("test %d: Fprint(w, %q): got %q, want %q", i+1, tt.err, got, tt.want)
  133. }
  134. }
  135. }
  136. func TestWrapfNil(t *testing.T) {
  137. got := Wrapf(nil, "no error")
  138. if got != nil {
  139. t.Errorf("Wrapf(nil, \"no error\"): got %#v, expected nil", got)
  140. }
  141. }
  142. func TestWrapf(t *testing.T) {
  143. tests := []struct {
  144. err error
  145. message string
  146. want string
  147. }{
  148. {io.EOF, "read error", "read error: EOF"},
  149. {Wrapf(io.EOF, "read error without format specifiers"), "client error", "client error: read error without format specifiers: EOF"},
  150. {Wrapf(io.EOF, "read error with %d format specifier", 1), "client error", "client error: read error with 1 format specifier: EOF"},
  151. }
  152. for _, tt := range tests {
  153. got := Wrapf(tt.err, tt.message).Error()
  154. if got != tt.want {
  155. t.Errorf("Wrapf(%v, %q): got: %v, want %v", tt.err, tt.message, got, tt.want)
  156. }
  157. }
  158. }
  159. func TestErrorf(t *testing.T) {
  160. tests := []struct {
  161. err error
  162. want string
  163. }{
  164. {Errorf("read error without format specifiers"), "read error without format specifiers"},
  165. {Errorf("read error with %d format specifier", 1), "read error with 1 format specifier"},
  166. }
  167. for _, tt := range tests {
  168. got := tt.err.Error()
  169. if got != tt.want {
  170. t.Errorf("Errorf(%v): got: %q, want %q", tt.err, got, tt.want)
  171. }
  172. }
  173. }
  174. // errors.New, etc values are not expected to be compared by value
  175. // but the change in errors#27 made them incomparable. Assert that
  176. // various kinds of errors have a functional equality operator, even
  177. // if the result of that equality is always false.
  178. func TestErrorEquality(t *testing.T) {
  179. tests := []struct {
  180. err1, err2 error
  181. }{
  182. {io.EOF, io.EOF},
  183. {io.EOF, nil},
  184. {io.EOF, errors.New("EOF")},
  185. {io.EOF, New("EOF")},
  186. {New("EOF"), New("EOF")},
  187. {New("EOF"), Errorf("EOF")},
  188. {New("EOF"), Wrap(io.EOF, "EOF")},
  189. }
  190. for _, tt := range tests {
  191. _ = tt.err1 == tt.err2 // mustn't panic
  192. }
  193. }