launchpad.net/gocheck@v0.0.0-20140225173054-000000000087/gocheck_test.go (about)

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