check_test.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // This file contains just a few generic helpers which are used by the
  2. // other test files.
  3. package check_test
  4. import (
  5. "flag"
  6. "fmt"
  7. "os"
  8. "regexp"
  9. "runtime"
  10. "testing"
  11. "time"
  12. "gopkg.in/check.v1"
  13. )
  14. // We count the number of suites run at least to get a vague hint that the
  15. // test suite is behaving as it should. Otherwise a bug introduced at the
  16. // very core of the system could go unperceived.
  17. const suitesRunExpected = 8
  18. var suitesRun int = 0
  19. func Test(t *testing.T) {
  20. check.TestingT(t)
  21. if suitesRun != suitesRunExpected && flag.Lookup("check.f").Value.String() == "" {
  22. critical(fmt.Sprintf("Expected %d suites to run rather than %d",
  23. suitesRunExpected, suitesRun))
  24. }
  25. }
  26. // -----------------------------------------------------------------------
  27. // Helper functions.
  28. // Break down badly. This is used in test cases which can't yet assume
  29. // that the fundamental bits are working.
  30. func critical(error string) {
  31. fmt.Fprintln(os.Stderr, "CRITICAL: "+error)
  32. os.Exit(1)
  33. }
  34. // Return the file line where it's called.
  35. func getMyLine() int {
  36. if _, _, line, ok := runtime.Caller(1); ok {
  37. return line
  38. }
  39. return -1
  40. }
  41. // -----------------------------------------------------------------------
  42. // Helper type implementing a basic io.Writer for testing output.
  43. // Type implementing the io.Writer interface for analyzing output.
  44. type String struct {
  45. value string
  46. }
  47. // The only function required by the io.Writer interface. Will append
  48. // written data to the String.value string.
  49. func (s *String) Write(p []byte) (n int, err error) {
  50. s.value += string(p)
  51. return len(p), nil
  52. }
  53. // Trivial wrapper to test errors happening on a different file
  54. // than the test itself.
  55. func checkEqualWrapper(c *check.C, obtained, expected interface{}) (result bool, line int) {
  56. return c.Check(obtained, check.Equals, expected), getMyLine()
  57. }
  58. // -----------------------------------------------------------------------
  59. // Helper suite for testing basic fail behavior.
  60. type FailHelper struct {
  61. testLine int
  62. }
  63. func (s *FailHelper) TestLogAndFail(c *check.C) {
  64. s.testLine = getMyLine() - 1
  65. c.Log("Expected failure!")
  66. c.Fail()
  67. }
  68. // -----------------------------------------------------------------------
  69. // Helper suite for testing basic success behavior.
  70. type SuccessHelper struct{}
  71. func (s *SuccessHelper) TestLogAndSucceed(c *check.C) {
  72. c.Log("Expected success!")
  73. }
  74. // -----------------------------------------------------------------------
  75. // Helper suite for testing ordering and behavior of fixture.
  76. type FixtureHelper struct {
  77. calls []string
  78. panicOn string
  79. skip bool
  80. skipOnN int
  81. sleepOn string
  82. sleep time.Duration
  83. bytes int64
  84. }
  85. func (s *FixtureHelper) trace(name string, c *check.C) {
  86. s.calls = append(s.calls, name)
  87. if name == s.panicOn {
  88. panic(name)
  89. }
  90. if s.sleep > 0 && s.sleepOn == name {
  91. time.Sleep(s.sleep)
  92. }
  93. if s.skip && s.skipOnN == len(s.calls)-1 {
  94. c.Skip("skipOnN == n")
  95. }
  96. }
  97. func (s *FixtureHelper) SetUpSuite(c *check.C) {
  98. s.trace("SetUpSuite", c)
  99. }
  100. func (s *FixtureHelper) TearDownSuite(c *check.C) {
  101. s.trace("TearDownSuite", c)
  102. }
  103. func (s *FixtureHelper) SetUpTest(c *check.C) {
  104. s.trace("SetUpTest", c)
  105. }
  106. func (s *FixtureHelper) TearDownTest(c *check.C) {
  107. s.trace("TearDownTest", c)
  108. }
  109. func (s *FixtureHelper) Test1(c *check.C) {
  110. s.trace("Test1", c)
  111. }
  112. func (s *FixtureHelper) Test2(c *check.C) {
  113. s.trace("Test2", c)
  114. }
  115. func (s *FixtureHelper) Benchmark1(c *check.C) {
  116. s.trace("Benchmark1", c)
  117. for i := 0; i < c.N; i++ {
  118. time.Sleep(s.sleep)
  119. }
  120. }
  121. func (s *FixtureHelper) Benchmark2(c *check.C) {
  122. s.trace("Benchmark2", c)
  123. c.SetBytes(1024)
  124. for i := 0; i < c.N; i++ {
  125. time.Sleep(s.sleep)
  126. }
  127. }
  128. func (s *FixtureHelper) Benchmark3(c *check.C) {
  129. var x []int64
  130. s.trace("Benchmark3", c)
  131. for i := 0; i < c.N; i++ {
  132. time.Sleep(s.sleep)
  133. x = make([]int64, 5)
  134. _ = x
  135. }
  136. }
  137. // -----------------------------------------------------------------------
  138. // Helper which checks the state of the test and ensures that it matches
  139. // the given expectations. Depends on c.Errorf() working, so shouldn't
  140. // be used to test this one function.
  141. type expectedState struct {
  142. name string
  143. result interface{}
  144. failed bool
  145. log string
  146. }
  147. // Verify the state of the test. Note that since this also verifies if
  148. // the test is supposed to be in a failed state, no other checks should
  149. // be done in addition to what is being tested.
  150. func checkState(c *check.C, result interface{}, expected *expectedState) {
  151. failed := c.Failed()
  152. c.Succeed()
  153. log := c.GetTestLog()
  154. matched, matchError := regexp.MatchString("^"+expected.log+"$", log)
  155. if matchError != nil {
  156. c.Errorf("Error in matching expression used in testing %s: %v",
  157. expected.name, matchError)
  158. } else if !matched {
  159. c.Errorf("%s logged:\n----------\n%s----------\n\nExpected:\n----------\n%s\n----------",
  160. expected.name, log, expected.log)
  161. }
  162. if result != expected.result {
  163. c.Errorf("%s returned %#v rather than %#v",
  164. expected.name, result, expected.result)
  165. }
  166. if failed != expected.failed {
  167. if failed {
  168. c.Errorf("%s has failed when it shouldn't", expected.name)
  169. } else {
  170. c.Errorf("%s has not failed when it should", expected.name)
  171. }
  172. }
  173. }