blob: 2a5187f7fdbd6bb09d6cb7ff3774f309678d4296 [file] [log] [blame]
// This file contains just a few generic helpers which are used by the
// other test files.
package gocheck_test
import (
"gocheck"
gocheck_local "gocheck/local"
"testing"
"runtime"
"regexp"
"flag"
"fmt"
"os"
)
// 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 = 6
var suitesRun int = 0
func Test(t *testing.T) {
gocheck.TestingT(t)
if suitesRun != suitesRunExpected &&
flag.Lookup("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 os.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 *gocheck.C,
expected interface{},
obtained interface{}) (result bool, line int) {
return c.Check(expected, gocheck_local.Equals, obtained), getMyLine()
}
// -----------------------------------------------------------------------
// Helper suite for testing basic fail behavior.
type FailHelper struct {
testLine int
}
func (s *FailHelper) TestLogAndFail(c *gocheck.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 *gocheck.C) {
c.Log("Expected success!")
}
// -----------------------------------------------------------------------
// Helper suite for testing ordering and behavior of fixture.
type FixtureHelper struct {
calls [64]string
n int
panicOn string
}
func (s *FixtureHelper) trace(name string) {
s.calls[s.n] = name
s.n += 1
if name == s.panicOn {
panic(name)
}
}
func (s *FixtureHelper) SetUpSuite(c *gocheck.C) {
s.trace("SetUpSuite")
}
func (s *FixtureHelper) TearDownSuite(c *gocheck.C) {
s.trace("TearDownSuite")
}
func (s *FixtureHelper) SetUpTest(c *gocheck.C) {
s.trace("SetUpTest")
}
func (s *FixtureHelper) TearDownTest(c *gocheck.C) {
s.trace("TearDownTest")
}
func (s *FixtureHelper) Test1(c *gocheck.C) {
s.trace("Test1")
}
func (s *FixtureHelper) Test2(c *gocheck.C) {
s.trace("Test2")
}
// -----------------------------------------------------------------------
// 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 *gocheck.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 %#v which doesn't match %#v",
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)
}
}
}