| // This file contains just a few generic helpers which are used by the | |
| // other test files. | |
| package check_test | |
| import ( | |
| "flag" | |
| "fmt" | |
| "os" | |
| "regexp" | |
| "runtime" | |
| "testing" | |
| "time" | |
| "gopkg.in/check.v1" | |
| ) | |
| // We count the number of suites run at least to get a vague hint that the | |
| // test suite is behaving as it should. Otherwise a bug introduced at the | |
| // very core of the system could go unperceived. | |
| const suitesRunExpected = 8 | |
| var suitesRun int = 0 | |
| func Test(t *testing.T) { | |
| check.TestingT(t) | |
| if suitesRun != suitesRunExpected && flag.Lookup("check.f").Value.String() == "" { | |
| critical(fmt.Sprintf("Expected %d suites to run rather than %d", | |
| suitesRunExpected, suitesRun)) | |
| } | |
| } | |
| // ----------------------------------------------------------------------- | |
| // Helper functions. | |
| // Break down badly. This is used in test cases which can't yet assume | |
| // that the fundamental bits are working. | |
| func critical(error string) { | |
| fmt.Fprintln(os.Stderr, "CRITICAL: "+error) | |
| os.Exit(1) | |
| } | |
| // Return the file line where it's called. | |
| func getMyLine() int { | |
| if _, _, line, ok := runtime.Caller(1); ok { | |
| return line | |
| } | |
| return -1 | |
| } | |
| // ----------------------------------------------------------------------- | |
| // Helper type implementing a basic io.Writer for testing output. | |
| // Type implementing the io.Writer interface for analyzing output. | |
| type String struct { | |
| value string | |
| } | |
| // The only function required by the io.Writer interface. Will append | |
| // written data to the String.value string. | |
| func (s *String) Write(p []byte) (n int, err error) { | |
| s.value += string(p) | |
| return len(p), nil | |
| } | |
| // Trivial wrapper to test errors happening on a different file | |
| // than the test itself. | |
| func checkEqualWrapper(c *check.C, obtained, expected interface{}) (result bool, line int) { | |
| return c.Check(obtained, check.Equals, expected), getMyLine() | |
| } | |
| // ----------------------------------------------------------------------- | |
| // Helper suite for testing basic fail behavior. | |
| type FailHelper struct { | |
| testLine int | |
| } | |
| func (s *FailHelper) TestLogAndFail(c *check.C) { | |
| s.testLine = getMyLine() - 1 | |
| c.Log("Expected failure!") | |
| c.Fail() | |
| } | |
| // ----------------------------------------------------------------------- | |
| // Helper suite for testing basic success behavior. | |
| type SuccessHelper struct{} | |
| func (s *SuccessHelper) TestLogAndSucceed(c *check.C) { | |
| c.Log("Expected success!") | |
| } | |
| // ----------------------------------------------------------------------- | |
| // Helper suite for testing ordering and behavior of fixture. | |
| type FixtureHelper struct { | |
| calls []string | |
| panicOn string | |
| skip bool | |
| skipOnN int | |
| sleepOn string | |
| sleep time.Duration | |
| bytes int64 | |
| } | |
| func (s *FixtureHelper) trace(name string, c *check.C) { | |
| s.calls = append(s.calls, name) | |
| if name == s.panicOn { | |
| panic(name) | |
| } | |
| if s.sleep > 0 && s.sleepOn == name { | |
| time.Sleep(s.sleep) | |
| } | |
| if s.skip && s.skipOnN == len(s.calls)-1 { | |
| c.Skip("skipOnN == n") | |
| } | |
| } | |
| func (s *FixtureHelper) SetUpSuite(c *check.C) { | |
| s.trace("SetUpSuite", c) | |
| } | |
| func (s *FixtureHelper) TearDownSuite(c *check.C) { | |
| s.trace("TearDownSuite", c) | |
| } | |
| func (s *FixtureHelper) SetUpTest(c *check.C) { | |
| s.trace("SetUpTest", c) | |
| } | |
| func (s *FixtureHelper) TearDownTest(c *check.C) { | |
| s.trace("TearDownTest", c) | |
| } | |
| func (s *FixtureHelper) Test1(c *check.C) { | |
| s.trace("Test1", c) | |
| } | |
| func (s *FixtureHelper) Test2(c *check.C) { | |
| s.trace("Test2", c) | |
| } | |
| func (s *FixtureHelper) Benchmark1(c *check.C) { | |
| s.trace("Benchmark1", c) | |
| for i := 0; i < c.N; i++ { | |
| time.Sleep(s.sleep) | |
| } | |
| } | |
| func (s *FixtureHelper) Benchmark2(c *check.C) { | |
| s.trace("Benchmark2", c) | |
| c.SetBytes(1024) | |
| for i := 0; i < c.N; i++ { | |
| time.Sleep(s.sleep) | |
| } | |
| } | |
| func (s *FixtureHelper) Benchmark3(c *check.C) { | |
| var x []int64 | |
| s.trace("Benchmark3", c) | |
| for i := 0; i < c.N; i++ { | |
| time.Sleep(s.sleep) | |
| x = make([]int64, 5) | |
| _ = x | |
| } | |
| } | |
| // ----------------------------------------------------------------------- | |
| // Helper which checks the state of the test and ensures that it matches | |
| // the given expectations. Depends on c.Errorf() working, so shouldn't | |
| // be used to test this one function. | |
| type expectedState struct { | |
| name string | |
| result interface{} | |
| failed bool | |
| log string | |
| } | |
| // Verify the state of the test. Note that since this also verifies if | |
| // the test is supposed to be in a failed state, no other checks should | |
| // be done in addition to what is being tested. | |
| func checkState(c *check.C, result interface{}, expected *expectedState) { | |
| failed := c.Failed() | |
| c.Succeed() | |
| log := c.GetTestLog() | |
| matched, matchError := regexp.MatchString("^"+expected.log+"$", log) | |
| if matchError != nil { | |
| c.Errorf("Error in matching expression used in testing %s: %v", | |
| expected.name, matchError) | |
| } else if !matched { | |
| c.Errorf("%s logged:\n----------\n%s----------\n\nExpected:\n----------\n%s\n----------", | |
| expected.name, log, expected.log) | |
| } | |
| if result != expected.result { | |
| c.Errorf("%s returned %#v rather than %#v", | |
| expected.name, result, expected.result) | |
| } | |
| if failed != expected.failed { | |
| if failed { | |
| c.Errorf("%s has failed when it shouldn't", expected.name) | |
| } else { | |
| c.Errorf("%s has not failed when it should", expected.name) | |
| } | |
| } | |
| } |