assertions.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. package assert
  2. import (
  3. "fmt"
  4. "reflect"
  5. "runtime"
  6. "strings"
  7. "time"
  8. )
  9. // TestingT is an interface wrapper around *testing.T
  10. type TestingT interface {
  11. Errorf(format string, args ...interface{})
  12. }
  13. // Comparison a custom function that returns true on success and false on failure
  14. type Comparison func() (success bool)
  15. /*
  16. Helper functions
  17. */
  18. // ObjectsAreEqual determines if two objects are considered equal.
  19. //
  20. // This function does no assertion of any kind.
  21. func ObjectsAreEqual(expected, actual interface{}) bool {
  22. if reflect.DeepEqual(expected, actual) {
  23. return true
  24. }
  25. if reflect.ValueOf(expected) == reflect.ValueOf(actual) {
  26. return true
  27. }
  28. // Last ditch effort
  29. if fmt.Sprintf("%#v", expected) == fmt.Sprintf("%#v", actual) {
  30. return true
  31. }
  32. return false
  33. }
  34. /* CallerInfo is necessary because the assert functions use the testing object
  35. internally, causing it to print the file:line of the assert method, rather than where
  36. the problem actually occured in calling code.*/
  37. // CallerInfo returns a string containing the file and line number of the assert call
  38. // that failed.
  39. func CallerInfo() string {
  40. file := ""
  41. line := 0
  42. ok := false
  43. for i := 0; ; i++ {
  44. _, file, line, ok = runtime.Caller(i)
  45. if !ok {
  46. return ""
  47. }
  48. parts := strings.Split(file, "/")
  49. dir := parts[len(parts)-2]
  50. file = parts[len(parts)-1]
  51. if (dir != "assert" && dir != "mock") || file == "mock_test.go" {
  52. break
  53. }
  54. }
  55. return fmt.Sprintf("%s:%d", file, line)
  56. }
  57. // getWhitespaceString returns a string that is long enough to overwrite the default
  58. // output from the go testing framework.
  59. func getWhitespaceString() string {
  60. _, file, line, ok := runtime.Caller(1)
  61. if !ok {
  62. return ""
  63. }
  64. parts := strings.Split(file, "/")
  65. file = parts[len(parts)-1]
  66. return strings.Repeat(" ", len(fmt.Sprintf("%s:%d: ", file, line)))
  67. }
  68. func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
  69. if len(msgAndArgs) == 0 || msgAndArgs == nil {
  70. return ""
  71. }
  72. if len(msgAndArgs) == 1 {
  73. return msgAndArgs[0].(string)
  74. }
  75. if len(msgAndArgs) > 1 {
  76. return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)
  77. }
  78. return ""
  79. }
  80. // Fail reports a failure through
  81. func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
  82. message := messageFromMsgAndArgs(msgAndArgs...)
  83. if len(message) > 0 {
  84. t.Errorf("\r%s\r\tLocation:\t%s\n\r\tError:\t\t%s\n\r\tMessages:\t%s\n\r", getWhitespaceString(), CallerInfo(), failureMessage, message)
  85. } else {
  86. t.Errorf("\r%s\r\tLocation:\t%s\n\r\tError:\t\t%s\n\r", getWhitespaceString(), CallerInfo(), failureMessage)
  87. }
  88. return false
  89. }
  90. // Implements asserts that an object is implemented by the specified interface.
  91. //
  92. // assert.Implements(t, (*MyInterface)(nil), new(MyObject), "MyObject")
  93. func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
  94. interfaceType := reflect.TypeOf(interfaceObject).Elem()
  95. if !reflect.TypeOf(object).Implements(interfaceType) {
  96. return Fail(t, fmt.Sprintf("Object must implement %v", interfaceType), msgAndArgs...)
  97. }
  98. return true
  99. }
  100. // IsType asserts that the specified objects are of the same type.
  101. func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
  102. if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) {
  103. return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...)
  104. }
  105. return true
  106. }
  107. // Equal asserts that two objects are equal.
  108. //
  109. // assert.Equal(t, 123, 123, "123 and 123 should be equal")
  110. //
  111. // Returns whether the assertion was successful (true) or not (false).
  112. func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
  113. if !ObjectsAreEqual(expected, actual) {
  114. return Fail(t, fmt.Sprintf("Not equal: %#v != %#v", expected, actual), msgAndArgs...)
  115. }
  116. return true
  117. }
  118. // Exactly asserts that two objects are equal is value and type.
  119. //
  120. // assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal")
  121. //
  122. // Returns whether the assertion was successful (true) or not (false).
  123. func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
  124. aType := reflect.TypeOf(expected)
  125. bType := reflect.TypeOf(actual)
  126. if aType != bType {
  127. return Fail(t, "Types expected to match exactly", "%v != %v", aType, bType)
  128. }
  129. return Equal(t, expected, actual, msgAndArgs...)
  130. }
  131. // NotNil asserts that the specified object is not nil.
  132. //
  133. // assert.NotNil(t, err, "err should be something")
  134. //
  135. // Returns whether the assertion was successful (true) or not (false).
  136. func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
  137. var success bool = true
  138. if object == nil {
  139. success = false
  140. } else {
  141. value := reflect.ValueOf(object)
  142. kind := value.Kind()
  143. if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() {
  144. success = false
  145. }
  146. }
  147. if !success {
  148. Fail(t, "Expected not to be nil.", msgAndArgs...)
  149. }
  150. return success
  151. }
  152. // Nil asserts that the specified object is nil.
  153. //
  154. // assert.Nil(t, err, "err should be nothing")
  155. //
  156. // Returns whether the assertion was successful (true) or not (false).
  157. func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
  158. if object == nil {
  159. return true
  160. } else {
  161. value := reflect.ValueOf(object)
  162. kind := value.Kind()
  163. if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() {
  164. return true
  165. }
  166. }
  167. return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...)
  168. }
  169. // isEmpty gets whether the specified object is considered empty or not.
  170. func isEmpty(object interface{}) bool {
  171. if object == nil {
  172. return true
  173. } else if object == "" {
  174. return true
  175. } else if object == 0 {
  176. return true
  177. } else if object == false {
  178. return true
  179. }
  180. objValue := reflect.ValueOf(object)
  181. switch objValue.Kind() {
  182. case reflect.Map:
  183. fallthrough
  184. case reflect.Slice:
  185. {
  186. return (objValue.Len() == 0)
  187. }
  188. }
  189. return false
  190. }
  191. // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or a
  192. // slice with len == 0.
  193. //
  194. // assert.Empty(t, obj)
  195. //
  196. // Returns whether the assertion was successful (true) or not (false).
  197. func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
  198. pass := isEmpty(object)
  199. if !pass {
  200. Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...)
  201. }
  202. return pass
  203. }
  204. // Empty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or a
  205. // slice with len == 0.
  206. //
  207. // if assert.NotEmpty(t, obj) {
  208. // assert.Equal(t, "two", obj[1])
  209. // }
  210. //
  211. // Returns whether the assertion was successful (true) or not (false).
  212. func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
  213. pass := !isEmpty(object)
  214. if !pass {
  215. Fail(t, fmt.Sprintf("Should NOT be empty, but was %v", object), msgAndArgs...)
  216. }
  217. return pass
  218. }
  219. // True asserts that the specified value is true.
  220. //
  221. // assert.True(t, myBool, "myBool should be true")
  222. //
  223. // Returns whether the assertion was successful (true) or not (false).
  224. func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
  225. if value != true {
  226. return Fail(t, "Should be true", msgAndArgs...)
  227. }
  228. return true
  229. }
  230. // False asserts that the specified value is true.
  231. //
  232. // assert.False(t, myBool, "myBool should be false")
  233. //
  234. // Returns whether the assertion was successful (true) or not (false).
  235. func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
  236. if value != false {
  237. return Fail(t, "Should be false", msgAndArgs...)
  238. }
  239. return true
  240. }
  241. // NotEqual asserts that the specified values are NOT equal.
  242. //
  243. // assert.NotEqual(t, obj1, obj2, "two objects shouldn't be equal")
  244. //
  245. // Returns whether the assertion was successful (true) or not (false).
  246. func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
  247. if ObjectsAreEqual(expected, actual) {
  248. return Fail(t, "Should not be equal", msgAndArgs...)
  249. }
  250. return true
  251. }
  252. // Contains asserts that the specified string contains the specified substring.
  253. //
  254. // assert.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'")
  255. //
  256. // Returns whether the assertion was successful (true) or not (false).
  257. func Contains(t TestingT, s, contains string, msgAndArgs ...interface{}) bool {
  258. if !strings.Contains(s, contains) {
  259. return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", s, contains), msgAndArgs...)
  260. }
  261. return true
  262. }
  263. // NotContains asserts that the specified string does NOT contain the specified substring.
  264. //
  265. // assert.NotContains(t, "Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
  266. //
  267. // Returns whether the assertion was successful (true) or not (false).
  268. func NotContains(t TestingT, s, contains string, msgAndArgs ...interface{}) bool {
  269. if strings.Contains(s, contains) {
  270. return Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...)
  271. }
  272. return true
  273. }
  274. // Uses a Comparison to assert a complex condition.
  275. func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool {
  276. result := comp()
  277. if !result {
  278. Fail(t, "Condition failed!", msgAndArgs...)
  279. }
  280. return result
  281. }
  282. // PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics
  283. // methods, and represents a simple func that takes no arguments, and returns nothing.
  284. type PanicTestFunc func()
  285. // didPanic returns true if the function passed to it panics. Otherwise, it returns false.
  286. func didPanic(f PanicTestFunc) (bool, interface{}) {
  287. var didPanic bool = false
  288. var message interface{}
  289. func() {
  290. defer func() {
  291. if message = recover(); message != nil {
  292. didPanic = true
  293. }
  294. }()
  295. // call the target function
  296. f()
  297. }()
  298. return didPanic, message
  299. }
  300. // Panics asserts that the code inside the specified PanicTestFunc panics.
  301. //
  302. // assert.Panics(t, func(){
  303. // GoCrazy()
  304. // }, "Calling GoCrazy() should panic")
  305. //
  306. // Returns whether the assertion was successful (true) or not (false).
  307. func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
  308. if funcDidPanic, panicValue := didPanic(f); !funcDidPanic {
  309. return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
  310. }
  311. return true
  312. }
  313. // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
  314. //
  315. // assert.NotPanics(t, func(){
  316. // RemainCalm()
  317. // }, "Calling RemainCalm() should NOT panic")
  318. //
  319. // Returns whether the assertion was successful (true) or not (false).
  320. func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
  321. if funcDidPanic, panicValue := didPanic(f); funcDidPanic {
  322. return Fail(t, fmt.Sprintf("func %#v should not panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
  323. }
  324. return true
  325. }
  326. // WithinDuration asserts that the two times are within duration delta of each other.
  327. //
  328. // assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
  329. //
  330. // Returns whether the assertion was successful (true) or not (false).
  331. func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
  332. dt := expected.Sub(actual)
  333. if dt < -delta || dt > delta {
  334. return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, dt, delta), msgAndArgs...)
  335. }
  336. return true
  337. }
  338. /*
  339. Errors
  340. */
  341. // NoError asserts that a function returned no error (i.e. `nil`).
  342. //
  343. // actualObj, err := SomeFunction()
  344. // if assert.NoError(t, err) {
  345. // assert.Equal(t, actualObj, expectedObj)
  346. // }
  347. //
  348. // Returns whether the assertion was successful (true) or not (false).
  349. func NoError(t TestingT, theError error, msgAndArgs ...interface{}) bool {
  350. message := messageFromMsgAndArgs(msgAndArgs...)
  351. return Nil(t, theError, "No error is expected but got %v %s", theError, message)
  352. }
  353. // Error asserts that a function returned an error (i.e. not `nil`).
  354. //
  355. // actualObj, err := SomeFunction()
  356. // if assert.Error(t, err, "An error was expected") {
  357. // assert.Equal(t, err, expectedError)
  358. // }
  359. //
  360. // Returns whether the assertion was successful (true) or not (false).
  361. func Error(t TestingT, theError error, msgAndArgs ...interface{}) bool {
  362. message := messageFromMsgAndArgs(msgAndArgs...)
  363. return NotNil(t, theError, "An error is expected but got nil. %s", message)
  364. }