doc.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Package assertions contains the implementations for all assertions which
  2. // are referenced in goconvey's `convey` package
  3. // (github.com/smartystreets/goconvey/convey) and gunit (github.com/smartystreets/gunit)
  4. // for use with the So(...) method.
  5. // They can also be used in traditional Go test functions and even in
  6. // applications.
  7. //
  8. // https://smartystreets.com
  9. //
  10. // Many of the assertions lean heavily on work done by Aaron Jacobs in his excellent oglematchers library.
  11. // (https://github.com/jacobsa/oglematchers)
  12. // The ShouldResemble assertion leans heavily on work done by Daniel Jacques in his very helpful go-render library.
  13. // (https://github.com/luci/go-render)
  14. package assertions
  15. import (
  16. "fmt"
  17. "runtime"
  18. )
  19. // By default we use a no-op serializer. The actual Serializer provides a JSON
  20. // representation of failure results on selected assertions so the goconvey
  21. // web UI can display a convenient diff.
  22. var serializer Serializer = new(noopSerializer)
  23. // GoConveyMode provides control over JSON serialization of failures. When
  24. // using the assertions in this package from the convey package JSON results
  25. // are very helpful and can be rendered in a DIFF view. In that case, this function
  26. // will be called with a true value to enable the JSON serialization. By default,
  27. // the assertions in this package will not serializer a JSON result, making
  28. // standalone usage more convenient.
  29. func GoConveyMode(yes bool) {
  30. if yes {
  31. serializer = newSerializer()
  32. } else {
  33. serializer = new(noopSerializer)
  34. }
  35. }
  36. type testingT interface {
  37. Error(args ...interface{})
  38. }
  39. type Assertion struct {
  40. t testingT
  41. failed bool
  42. }
  43. // New swallows the *testing.T struct and prints failed assertions using t.Error.
  44. // Example: assertions.New(t).So(1, should.Equal, 1)
  45. func New(t testingT) *Assertion {
  46. return &Assertion{t: t}
  47. }
  48. // Failed reports whether any calls to So (on this Assertion instance) have failed.
  49. func (this *Assertion) Failed() bool {
  50. return this.failed
  51. }
  52. // So calls the standalone So function and additionally, calls t.Error in failure scenarios.
  53. func (this *Assertion) So(actual interface{}, assert assertion, expected ...interface{}) bool {
  54. ok, result := So(actual, assert, expected...)
  55. if !ok {
  56. this.failed = true
  57. _, file, line, _ := runtime.Caller(1)
  58. this.t.Error(fmt.Sprintf("\n%s:%d\n%s", file, line, result))
  59. }
  60. return ok
  61. }
  62. // So is a convenience function (as opposed to an inconvenience function?)
  63. // for running assertions on arbitrary arguments in any context, be it for testing or even
  64. // application logging. It allows you to perform assertion-like behavior (and get nicely
  65. // formatted messages detailing discrepancies) but without the program blowing up or panicking.
  66. // All that is required is to import this package and call `So` with one of the assertions
  67. // exported by this package as the second parameter.
  68. // The first return parameter is a boolean indicating if the assertion was true. The second
  69. // return parameter is the well-formatted message showing why an assertion was incorrect, or
  70. // blank if the assertion was correct.
  71. //
  72. // Example:
  73. //
  74. // if ok, message := So(x, ShouldBeGreaterThan, y); !ok {
  75. // log.Println(message)
  76. // }
  77. //
  78. // For an alternative implementation of So (that provides more flexible return options)
  79. // see the `So` function in the package at github.com/smartystreets/assertions/assert.
  80. func So(actual interface{}, assert assertion, expected ...interface{}) (bool, string) {
  81. if result := so(actual, assert, expected...); len(result) == 0 {
  82. return true, result
  83. } else {
  84. return false, result
  85. }
  86. }
  87. // so is like So, except that it only returns the string message, which is blank if the
  88. // assertion passed. Used to facilitate testing.
  89. func so(actual interface{}, assert func(interface{}, ...interface{}) string, expected ...interface{}) string {
  90. return assert(actual, expected...)
  91. }
  92. // assertion is an alias for a function with a signature that the So()
  93. // function can handle. Any future or custom assertions should conform to this
  94. // method signature. The return value should be an empty string if the assertion
  95. // passes and a well-formed failure message if not.
  96. type assertion func(actual interface{}, expected ...interface{}) string
  97. ////////////////////////////////////////////////////////////////////////////