errors_test.go 4.7 KB

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