208 lines
5 KiB
Go
208 lines
5 KiB
Go
|
// 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",
|
||
|
expected.name)
|
||
|
} 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)
|
||
|
}
|
||
|
}
|
||
|
}
|