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