doc.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. // Package convey contains all of the public-facing entry points to this project.
  2. // This means that it should never be required of the user to import any other
  3. // packages from this project as they serve internal purposes.
  4. package convey
  5. import "github.com/smartystreets/goconvey/convey/reporting"
  6. ////////////////////////////////// suite //////////////////////////////////
  7. // C is the Convey context which you can optionally obtain in your action
  8. // by calling Convey like:
  9. //
  10. // Convey(..., func(c C) {
  11. // ...
  12. // })
  13. //
  14. // See the documentation on Convey for more details.
  15. //
  16. // All methods in this context behave identically to the global functions of the
  17. // same name in this package.
  18. type C interface {
  19. Convey(items ...interface{})
  20. SkipConvey(items ...interface{})
  21. FocusConvey(items ...interface{})
  22. So(actual interface{}, assert Assertion, expected ...interface{})
  23. SoMsg(msg string, actual interface{}, assert Assertion, expected ...interface{})
  24. SkipSo(stuff ...interface{})
  25. Reset(action func())
  26. Println(items ...interface{}) (int, error)
  27. Print(items ...interface{}) (int, error)
  28. Printf(format string, items ...interface{}) (int, error)
  29. }
  30. // Convey is the method intended for use when declaring the scopes of
  31. // a specification. Each scope has a description and a func() which may contain
  32. // other calls to Convey(), Reset() or Should-style assertions. Convey calls can
  33. // be nested as far as you see fit.
  34. //
  35. // IMPORTANT NOTE: The top-level Convey() within a Test method
  36. // must conform to the following signature:
  37. //
  38. // Convey(description string, t *testing.T, action func())
  39. //
  40. // All other calls should look like this (no need to pass in *testing.T):
  41. //
  42. // Convey(description string, action func())
  43. //
  44. // Don't worry, goconvey will panic if you get it wrong so you can fix it.
  45. //
  46. // Additionally, you may explicitly obtain access to the Convey context by doing:
  47. //
  48. // Convey(description string, action func(c C))
  49. //
  50. // You may need to do this if you want to pass the context through to a
  51. // goroutine, or to close over the context in a handler to a library which
  52. // calls your handler in a goroutine (httptest comes to mind).
  53. //
  54. // All Convey()-blocks also accept an optional parameter of FailureMode which sets
  55. // how goconvey should treat failures for So()-assertions in the block and
  56. // nested blocks. See the constants in this file for the available options.
  57. //
  58. // By default it will inherit from its parent block and the top-level blocks
  59. // default to the FailureHalts setting.
  60. //
  61. // This parameter is inserted before the block itself:
  62. //
  63. // Convey(description string, t *testing.T, mode FailureMode, action func())
  64. // Convey(description string, mode FailureMode, action func())
  65. //
  66. // See the examples package for, well, examples.
  67. func Convey(items ...interface{}) {
  68. if ctx := getCurrentContext(); ctx == nil {
  69. rootConvey(items...)
  70. } else {
  71. ctx.Convey(items...)
  72. }
  73. }
  74. // SkipConvey is analogous to Convey except that the scope is not executed
  75. // (which means that child scopes defined within this scope are not run either).
  76. // The reporter will be notified that this step was skipped.
  77. func SkipConvey(items ...interface{}) {
  78. Convey(append(items, skipConvey)...)
  79. }
  80. // FocusConvey is has the inverse effect of SkipConvey. If the top-level
  81. // Convey is changed to `FocusConvey`, only nested scopes that are defined
  82. // with FocusConvey will be run. The rest will be ignored completely. This
  83. // is handy when debugging a large suite that runs a misbehaving function
  84. // repeatedly as you can disable all but one of that function
  85. // without swaths of `SkipConvey` calls, just a targeted chain of calls
  86. // to FocusConvey.
  87. func FocusConvey(items ...interface{}) {
  88. Convey(append(items, focusConvey)...)
  89. }
  90. // Reset registers a cleanup function to be run after each Convey()
  91. // in the same scope. See the examples package for a simple use case.
  92. func Reset(action func()) {
  93. mustGetCurrentContext().Reset(action)
  94. }
  95. /////////////////////////////////// Assertions ///////////////////////////////////
  96. // Assertion is an alias for a function with a signature that the convey.So()
  97. // method can handle. Any future or custom assertions should conform to this
  98. // method signature. The return value should be an empty string if the assertion
  99. // passes and a well-formed failure message if not.
  100. type Assertion func(actual interface{}, expected ...interface{}) string
  101. const assertionSuccess = ""
  102. // So is the means by which assertions are made against the system under test.
  103. // The majority of exported names in the assertions package begin with the word
  104. // 'Should' and describe how the first argument (actual) should compare with any
  105. // of the final (expected) arguments. How many final arguments are accepted
  106. // depends on the particular assertion that is passed in as the assert argument.
  107. // See the examples package for use cases and the assertions package for
  108. // documentation on specific assertion methods. A failing assertion will
  109. // cause t.Fail() to be invoked--you should never call this method (or other
  110. // failure-inducing methods) in your test code. Leave that to GoConvey.
  111. func So(actual interface{}, assert Assertion, expected ...interface{}) {
  112. mustGetCurrentContext().So(actual, assert, expected...)
  113. }
  114. // SoMsg is an extension of So that allows you to specify a message to report on error.
  115. func SoMsg(msg string, actual interface{}, assert Assertion, expected ...interface{}) {
  116. mustGetCurrentContext().SoMsg(msg, actual, assert, expected...)
  117. }
  118. // SkipSo is analogous to So except that the assertion that would have been passed
  119. // to So is not executed and the reporter is notified that the assertion was skipped.
  120. func SkipSo(stuff ...interface{}) {
  121. mustGetCurrentContext().SkipSo()
  122. }
  123. // FailureMode is a type which determines how the So() blocks should fail
  124. // if their assertion fails. See constants further down for acceptable values
  125. type FailureMode string
  126. // StackMode is a type which determines whether the So() blocks should report
  127. // stack traces their assertion fails. See constants further down for acceptable values
  128. type StackMode string
  129. const (
  130. // FailureContinues is a failure mode which prevents failing
  131. // So()-assertions from halting Convey-block execution, instead
  132. // allowing the test to continue past failing So()-assertions.
  133. FailureContinues FailureMode = "continue"
  134. // FailureHalts is the default setting for a top-level Convey()-block
  135. // and will cause all failing So()-assertions to halt further execution
  136. // in that test-arm and continue on to the next arm.
  137. FailureHalts FailureMode = "halt"
  138. // FailureInherits is the default setting for failure-mode, it will
  139. // default to the failure-mode of the parent block. You should never
  140. // need to specify this mode in your tests..
  141. FailureInherits FailureMode = "inherits"
  142. // StackError is a stack mode which tells Convey to print stack traces
  143. // only for errors and not for test failures
  144. StackError StackMode = "error"
  145. // StackFail is a stack mode which tells Convey to print stack traces
  146. // for both errors and test failures
  147. StackFail StackMode = "fail"
  148. // StackInherits is the default setting for stack-mode, it will
  149. // default to the stack-mode of the parent block. You should never
  150. // need to specify this mode in your tests..
  151. StackInherits StackMode = "inherits"
  152. )
  153. func (f FailureMode) combine(other FailureMode) FailureMode {
  154. if other == FailureInherits {
  155. return f
  156. }
  157. return other
  158. }
  159. var defaultFailureMode FailureMode = FailureHalts
  160. // SetDefaultFailureMode allows you to specify the default failure mode
  161. // for all Convey blocks. It is meant to be used in an init function to
  162. // allow the default mode to be changed across all tests for an entire packgae
  163. // but it can be used anywhere.
  164. func SetDefaultFailureMode(mode FailureMode) {
  165. if mode == FailureContinues || mode == FailureHalts {
  166. defaultFailureMode = mode
  167. } else {
  168. panic("You may only use the constants named 'FailureContinues' and 'FailureHalts' as default failure modes.")
  169. }
  170. }
  171. func (s StackMode) combine(other StackMode) StackMode {
  172. if other == StackInherits {
  173. return s
  174. }
  175. return other
  176. }
  177. var defaultStackMode StackMode = StackError
  178. // SetDefaultStackMode allows you to specify the default stack mode
  179. // for all Convey blocks. It is meant to be used in an init function to
  180. // allow the default mode to be changed across all tests for an entire packgae
  181. // but it can be used anywhere.
  182. func SetDefaultStackMode(mode StackMode) {
  183. if mode == StackError || mode == StackFail {
  184. defaultStackMode = mode
  185. } else {
  186. panic("You may only use the constants named 'StackError' and 'StackFail' as default stack modes.")
  187. }
  188. }
  189. //////////////////////////////////// Print functions ////////////////////////////////////
  190. // Print is analogous to fmt.Print (and it even calls fmt.Print). It ensures that
  191. // output is aligned with the corresponding scopes in the web UI.
  192. func Print(items ...interface{}) (written int, err error) {
  193. return mustGetCurrentContext().Print(items...)
  194. }
  195. // Print is analogous to fmt.Println (and it even calls fmt.Println). It ensures that
  196. // output is aligned with the corresponding scopes in the web UI.
  197. func Println(items ...interface{}) (written int, err error) {
  198. return mustGetCurrentContext().Println(items...)
  199. }
  200. // Print is analogous to fmt.Printf (and it even calls fmt.Printf). It ensures that
  201. // output is aligned with the corresponding scopes in the web UI.
  202. func Printf(format string, items ...interface{}) (written int, err error) {
  203. return mustGetCurrentContext().Printf(format, items...)
  204. }
  205. ///////////////////////////////////////////////////////////////////////////////
  206. // SuppressConsoleStatistics prevents automatic printing of console statistics.
  207. // Calling PrintConsoleStatistics explicitly will force printing of statistics.
  208. func SuppressConsoleStatistics() {
  209. reporting.SuppressConsoleStatistics()
  210. }
  211. // PrintConsoleStatistics may be called at any time to print assertion statistics.
  212. // Generally, the best place to do this would be in a TestMain function,
  213. // after all tests have been run. Something like this:
  214. //
  215. // func TestMain(m *testing.M) {
  216. // convey.SuppressConsoleStatistics()
  217. // result := m.Run()
  218. // convey.PrintConsoleStatistics()
  219. // os.Exit(result)
  220. // }
  221. //
  222. func PrintConsoleStatistics() {
  223. reporting.PrintConsoleStatistics()
  224. }