checkers_test.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. package check_test
  2. import (
  3. "errors"
  4. "reflect"
  5. "runtime"
  6. "gopkg.in/check.v1"
  7. )
  8. type CheckersS struct{}
  9. var _ = check.Suite(&CheckersS{})
  10. func testInfo(c *check.C, checker check.Checker, name string, paramNames []string) {
  11. info := checker.Info()
  12. if info.Name != name {
  13. c.Fatalf("Got name %s, expected %s", info.Name, name)
  14. }
  15. if !reflect.DeepEqual(info.Params, paramNames) {
  16. c.Fatalf("Got param names %#v, expected %#v", info.Params, paramNames)
  17. }
  18. }
  19. func testCheck(c *check.C, checker check.Checker, result bool, error string, params ...interface{}) ([]interface{}, []string) {
  20. info := checker.Info()
  21. if len(params) != len(info.Params) {
  22. c.Fatalf("unexpected param count in test; expected %d got %d", len(info.Params), len(params))
  23. }
  24. names := append([]string{}, info.Params...)
  25. result_, error_ := checker.Check(params, names)
  26. if result_ != result || error_ != error {
  27. c.Fatalf("%s.Check(%#v) returned (%#v, %#v) rather than (%#v, %#v)",
  28. info.Name, params, result_, error_, result, error)
  29. }
  30. return params, names
  31. }
  32. func (s *CheckersS) TestComment(c *check.C) {
  33. bug := check.Commentf("a %d bc", 42)
  34. comment := bug.CheckCommentString()
  35. if comment != "a 42 bc" {
  36. c.Fatalf("Commentf returned %#v", comment)
  37. }
  38. }
  39. func (s *CheckersS) TestIsNil(c *check.C) {
  40. testInfo(c, check.IsNil, "IsNil", []string{"value"})
  41. testCheck(c, check.IsNil, true, "", nil)
  42. testCheck(c, check.IsNil, false, "", "a")
  43. testCheck(c, check.IsNil, true, "", (chan int)(nil))
  44. testCheck(c, check.IsNil, false, "", make(chan int))
  45. testCheck(c, check.IsNil, true, "", (error)(nil))
  46. testCheck(c, check.IsNil, false, "", errors.New(""))
  47. testCheck(c, check.IsNil, true, "", ([]int)(nil))
  48. testCheck(c, check.IsNil, false, "", make([]int, 1))
  49. testCheck(c, check.IsNil, false, "", int(0))
  50. }
  51. func (s *CheckersS) TestNotNil(c *check.C) {
  52. testInfo(c, check.NotNil, "NotNil", []string{"value"})
  53. testCheck(c, check.NotNil, false, "", nil)
  54. testCheck(c, check.NotNil, true, "", "a")
  55. testCheck(c, check.NotNil, false, "", (chan int)(nil))
  56. testCheck(c, check.NotNil, true, "", make(chan int))
  57. testCheck(c, check.NotNil, false, "", (error)(nil))
  58. testCheck(c, check.NotNil, true, "", errors.New(""))
  59. testCheck(c, check.NotNil, false, "", ([]int)(nil))
  60. testCheck(c, check.NotNil, true, "", make([]int, 1))
  61. }
  62. func (s *CheckersS) TestNot(c *check.C) {
  63. testInfo(c, check.Not(check.IsNil), "Not(IsNil)", []string{"value"})
  64. testCheck(c, check.Not(check.IsNil), false, "", nil)
  65. testCheck(c, check.Not(check.IsNil), true, "", "a")
  66. testCheck(c, check.Not(check.Equals), true, "", 42, 43)
  67. }
  68. type simpleStruct struct {
  69. i int
  70. }
  71. func (s *CheckersS) TestEquals(c *check.C) {
  72. testInfo(c, check.Equals, "Equals", []string{"obtained", "expected"})
  73. // The simplest.
  74. testCheck(c, check.Equals, true, "", 42, 42)
  75. testCheck(c, check.Equals, false, "", 42, 43)
  76. // Different native types.
  77. testCheck(c, check.Equals, false, "", int32(42), int64(42))
  78. // With nil.
  79. testCheck(c, check.Equals, false, "", 42, nil)
  80. // Slices
  81. testCheck(c, check.Equals, false, "runtime error: comparing uncomparable type []uint8", []byte{1, 2}, []byte{1, 2})
  82. // Struct values
  83. testCheck(c, check.Equals, true, "", simpleStruct{1}, simpleStruct{1})
  84. testCheck(c, check.Equals, false, `Difference:
  85. ... i: 1 != 2
  86. `, simpleStruct{1}, simpleStruct{2})
  87. // Struct pointers, no difference in values, just pointer
  88. testCheck(c, check.Equals, false, "", &simpleStruct{1}, &simpleStruct{1})
  89. // Struct pointers, different pointers and different values
  90. testCheck(c, check.Equals, false, `Difference:
  91. ... i: 1 != 2
  92. `, &simpleStruct{1}, &simpleStruct{2})
  93. }
  94. func (s *CheckersS) TestDeepEquals(c *check.C) {
  95. testInfo(c, check.DeepEquals, "DeepEquals", []string{"obtained", "expected"})
  96. // The simplest.
  97. testCheck(c, check.DeepEquals, true, "", 42, 42)
  98. testCheck(c, check.DeepEquals, false, "", 42, 43)
  99. // Different native types.
  100. testCheck(c, check.DeepEquals, false, "", int32(42), int64(42))
  101. // With nil.
  102. testCheck(c, check.DeepEquals, false, "", 42, nil)
  103. // Slices
  104. testCheck(c, check.DeepEquals, true, "", []byte{1, 2}, []byte{1, 2})
  105. testCheck(c, check.DeepEquals, false, `Difference:
  106. ... [1]: 2 != 3
  107. `, []byte{1, 2}, []byte{1, 3})
  108. // Struct values
  109. testCheck(c, check.DeepEquals, true, "", simpleStruct{1}, simpleStruct{1})
  110. testCheck(c, check.DeepEquals, false, `Difference:
  111. ... i: 1 != 2
  112. `, simpleStruct{1}, simpleStruct{2})
  113. // Struct pointers
  114. testCheck(c, check.DeepEquals, true, "", &simpleStruct{1}, &simpleStruct{1})
  115. s1 := &simpleStruct{1}
  116. s2 := &simpleStruct{2}
  117. testCheck(c, check.DeepEquals, false, `Difference:
  118. ... i: 1 != 2
  119. `, s1, s2)
  120. }
  121. func (s *CheckersS) TestHasLen(c *check.C) {
  122. testInfo(c, check.HasLen, "HasLen", []string{"obtained", "n"})
  123. testCheck(c, check.HasLen, true, "", "abcd", 4)
  124. testCheck(c, check.HasLen, true, "", []int{1, 2}, 2)
  125. testCheck(c, check.HasLen, false, "", []int{1, 2}, 3)
  126. testCheck(c, check.HasLen, false, "n must be an int", []int{1, 2}, "2")
  127. testCheck(c, check.HasLen, false, "obtained value type has no length", nil, 2)
  128. }
  129. func (s *CheckersS) TestErrorMatches(c *check.C) {
  130. testInfo(c, check.ErrorMatches, "ErrorMatches", []string{"value", "regex"})
  131. testCheck(c, check.ErrorMatches, false, "Error value is nil", nil, "some error")
  132. testCheck(c, check.ErrorMatches, false, "Value is not an error", 1, "some error")
  133. testCheck(c, check.ErrorMatches, true, "", errors.New("some error"), "some error")
  134. testCheck(c, check.ErrorMatches, true, "", errors.New("some error"), "so.*or")
  135. // Verify params mutation
  136. params, names := testCheck(c, check.ErrorMatches, false, "", errors.New("some error"), "other error")
  137. c.Assert(params[0], check.Equals, "some error")
  138. c.Assert(names[0], check.Equals, "error")
  139. }
  140. func (s *CheckersS) TestMatches(c *check.C) {
  141. testInfo(c, check.Matches, "Matches", []string{"value", "regex"})
  142. // Simple matching
  143. testCheck(c, check.Matches, true, "", "abc", "abc")
  144. testCheck(c, check.Matches, true, "", "abc", "a.c")
  145. // Must match fully
  146. testCheck(c, check.Matches, false, "", "abc", "ab")
  147. testCheck(c, check.Matches, false, "", "abc", "bc")
  148. // String()-enabled values accepted
  149. testCheck(c, check.Matches, true, "", reflect.ValueOf("abc"), "a.c")
  150. testCheck(c, check.Matches, false, "", reflect.ValueOf("abc"), "a.d")
  151. // Some error conditions.
  152. testCheck(c, check.Matches, false, "Obtained value is not a string and has no .String()", 1, "a.c")
  153. testCheck(c, check.Matches, false, "Can't compile regex: error parsing regexp: missing closing ]: `[c$`", "abc", "a[c")
  154. }
  155. func (s *CheckersS) TestPanics(c *check.C) {
  156. testInfo(c, check.Panics, "Panics", []string{"function", "expected"})
  157. // Some errors.
  158. testCheck(c, check.Panics, false, "Function has not panicked", func() bool { return false }, "BOOM")
  159. testCheck(c, check.Panics, false, "Function must take zero arguments", 1, "BOOM")
  160. // Plain strings.
  161. testCheck(c, check.Panics, true, "", func() { panic("BOOM") }, "BOOM")
  162. testCheck(c, check.Panics, false, "", func() { panic("KABOOM") }, "BOOM")
  163. testCheck(c, check.Panics, true, "", func() bool { panic("BOOM") }, "BOOM")
  164. // Error values.
  165. testCheck(c, check.Panics, true, "", func() { panic(errors.New("BOOM")) }, errors.New("BOOM"))
  166. testCheck(c, check.Panics, false, "", func() { panic(errors.New("KABOOM")) }, errors.New("BOOM"))
  167. type deep struct{ i int }
  168. // Deep value
  169. testCheck(c, check.Panics, true, "", func() { panic(&deep{99}) }, &deep{99})
  170. // Verify params/names mutation
  171. params, names := testCheck(c, check.Panics, false, "", func() { panic(errors.New("KABOOM")) }, errors.New("BOOM"))
  172. c.Assert(params[0], check.ErrorMatches, "KABOOM")
  173. c.Assert(names[0], check.Equals, "panic")
  174. // Verify a nil panic
  175. testCheck(c, check.Panics, true, "", func() { panic(nil) }, nil)
  176. testCheck(c, check.Panics, false, "", func() { panic(nil) }, "NOPE")
  177. }
  178. func (s *CheckersS) TestPanicMatches(c *check.C) {
  179. testInfo(c, check.PanicMatches, "PanicMatches", []string{"function", "expected"})
  180. // Error matching.
  181. testCheck(c, check.PanicMatches, true, "", func() { panic(errors.New("BOOM")) }, "BO.M")
  182. testCheck(c, check.PanicMatches, false, "", func() { panic(errors.New("KABOOM")) }, "BO.M")
  183. // Some errors.
  184. testCheck(c, check.PanicMatches, false, "Function has not panicked", func() bool { return false }, "BOOM")
  185. testCheck(c, check.PanicMatches, false, "Function must take zero arguments", 1, "BOOM")
  186. // Plain strings.
  187. testCheck(c, check.PanicMatches, true, "", func() { panic("BOOM") }, "BO.M")
  188. testCheck(c, check.PanicMatches, false, "", func() { panic("KABOOM") }, "BOOM")
  189. testCheck(c, check.PanicMatches, true, "", func() bool { panic("BOOM") }, "BO.M")
  190. // Verify params/names mutation
  191. params, names := testCheck(c, check.PanicMatches, false, "", func() { panic(errors.New("KABOOM")) }, "BOOM")
  192. c.Assert(params[0], check.Equals, "KABOOM")
  193. c.Assert(names[0], check.Equals, "panic")
  194. // Verify a nil panic
  195. testCheck(c, check.PanicMatches, false, "Panic value is not a string or an error", func() { panic(nil) }, "")
  196. }
  197. func (s *CheckersS) TestFitsTypeOf(c *check.C) {
  198. testInfo(c, check.FitsTypeOf, "FitsTypeOf", []string{"obtained", "sample"})
  199. // Basic types
  200. testCheck(c, check.FitsTypeOf, true, "", 1, 0)
  201. testCheck(c, check.FitsTypeOf, false, "", 1, int64(0))
  202. // Aliases
  203. testCheck(c, check.FitsTypeOf, false, "", 1, errors.New(""))
  204. testCheck(c, check.FitsTypeOf, false, "", "error", errors.New(""))
  205. testCheck(c, check.FitsTypeOf, true, "", errors.New("error"), errors.New(""))
  206. // Structures
  207. testCheck(c, check.FitsTypeOf, false, "", 1, simpleStruct{})
  208. testCheck(c, check.FitsTypeOf, false, "", simpleStruct{42}, &simpleStruct{})
  209. testCheck(c, check.FitsTypeOf, true, "", simpleStruct{42}, simpleStruct{})
  210. testCheck(c, check.FitsTypeOf, true, "", &simpleStruct{42}, &simpleStruct{})
  211. // Some bad values
  212. testCheck(c, check.FitsTypeOf, false, "Invalid sample value", 1, interface{}(nil))
  213. testCheck(c, check.FitsTypeOf, false, "", interface{}(nil), 0)
  214. }
  215. func (s *CheckersS) TestImplements(c *check.C) {
  216. testInfo(c, check.Implements, "Implements", []string{"obtained", "ifaceptr"})
  217. var e error
  218. var re runtime.Error
  219. testCheck(c, check.Implements, true, "", errors.New(""), &e)
  220. testCheck(c, check.Implements, false, "", errors.New(""), &re)
  221. // Some bad values
  222. testCheck(c, check.Implements, false, "ifaceptr should be a pointer to an interface variable", 0, errors.New(""))
  223. testCheck(c, check.Implements, false, "ifaceptr should be a pointer to an interface variable", 0, interface{}(nil))
  224. testCheck(c, check.Implements, false, "", interface{}(nil), &e)
  225. }