232 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			232 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Go
		
	
	
package check
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"strings"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
// TestName returns the current test name in the form "SuiteName.TestName"
 | 
						|
func (c *C) TestName() string {
 | 
						|
	return c.testName
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------
 | 
						|
// Basic succeeding/failing logic.
 | 
						|
 | 
						|
// Failed returns whether the currently running test has already failed.
 | 
						|
func (c *C) Failed() bool {
 | 
						|
	return c.status == failedSt
 | 
						|
}
 | 
						|
 | 
						|
// Fail marks the currently running test as failed.
 | 
						|
//
 | 
						|
// Something ought to have been previously logged so the developer can tell
 | 
						|
// what went wrong. The higher level helper functions will fail the test
 | 
						|
// and do the logging properly.
 | 
						|
func (c *C) Fail() {
 | 
						|
	c.status = failedSt
 | 
						|
}
 | 
						|
 | 
						|
// FailNow marks the currently running test as failed and stops running it.
 | 
						|
// Something ought to have been previously logged so the developer can tell
 | 
						|
// what went wrong. The higher level helper functions will fail the test
 | 
						|
// and do the logging properly.
 | 
						|
func (c *C) FailNow() {
 | 
						|
	c.Fail()
 | 
						|
	c.stopNow()
 | 
						|
}
 | 
						|
 | 
						|
// Succeed marks the currently running test as succeeded, undoing any
 | 
						|
// previous failures.
 | 
						|
func (c *C) Succeed() {
 | 
						|
	c.status = succeededSt
 | 
						|
}
 | 
						|
 | 
						|
// SucceedNow marks the currently running test as succeeded, undoing any
 | 
						|
// previous failures, and stops running the test.
 | 
						|
func (c *C) SucceedNow() {
 | 
						|
	c.Succeed()
 | 
						|
	c.stopNow()
 | 
						|
}
 | 
						|
 | 
						|
// ExpectFailure informs that the running test is knowingly broken for
 | 
						|
// the provided reason. If the test does not fail, an error will be reported
 | 
						|
// to raise attention to this fact. This method is useful to temporarily
 | 
						|
// disable tests which cover well known problems until a better time to
 | 
						|
// fix the problem is found, without forgetting about the fact that a
 | 
						|
// failure still exists.
 | 
						|
func (c *C) ExpectFailure(reason string) {
 | 
						|
	if reason == "" {
 | 
						|
		panic("Missing reason why the test is expected to fail")
 | 
						|
	}
 | 
						|
	c.mustFail = true
 | 
						|
	c.reason = reason
 | 
						|
}
 | 
						|
 | 
						|
// Skip skips the running test for the provided reason. If run from within
 | 
						|
// SetUpTest, the individual test being set up will be skipped, and if run
 | 
						|
// from within SetUpSuite, the whole suite is skipped.
 | 
						|
func (c *C) Skip(reason string) {
 | 
						|
	if reason == "" {
 | 
						|
		panic("Missing reason why the test is being skipped")
 | 
						|
	}
 | 
						|
	c.reason = reason
 | 
						|
	c.status = skippedSt
 | 
						|
	c.stopNow()
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------
 | 
						|
// Basic logging.
 | 
						|
 | 
						|
// GetTestLog returns the current test error output.
 | 
						|
func (c *C) GetTestLog() string {
 | 
						|
	return c.logb.String()
 | 
						|
}
 | 
						|
 | 
						|
// Log logs some information into the test error output.
 | 
						|
// The provided arguments are assembled together into a string with fmt.Sprint.
 | 
						|
func (c *C) Log(args ...interface{}) {
 | 
						|
	c.log(args...)
 | 
						|
}
 | 
						|
 | 
						|
// Log logs some information into the test error output.
 | 
						|
// The provided arguments are assembled together into a string with fmt.Sprintf.
 | 
						|
func (c *C) Logf(format string, args ...interface{}) {
 | 
						|
	c.logf(format, args...)
 | 
						|
}
 | 
						|
 | 
						|
// Output enables *C to be used as a logger in functions that require only
 | 
						|
// the minimum interface of *log.Logger.
 | 
						|
func (c *C) Output(calldepth int, s string) error {
 | 
						|
	d := time.Now().Sub(c.startTime)
 | 
						|
	msec := d / time.Millisecond
 | 
						|
	sec := d / time.Second
 | 
						|
	min := d / time.Minute
 | 
						|
 | 
						|
	c.Logf("[LOG] %d:%02d.%03d %s", min, sec%60, msec%1000, s)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Error logs an error into the test error output and marks the test as failed.
 | 
						|
// The provided arguments are assembled together into a string with fmt.Sprint.
 | 
						|
func (c *C) Error(args ...interface{}) {
 | 
						|
	c.logCaller(1)
 | 
						|
	c.logString(fmt.Sprint("Error: ", fmt.Sprint(args...)))
 | 
						|
	c.logNewLine()
 | 
						|
	c.Fail()
 | 
						|
}
 | 
						|
 | 
						|
// Errorf logs an error into the test error output and marks the test as failed.
 | 
						|
// The provided arguments are assembled together into a string with fmt.Sprintf.
 | 
						|
func (c *C) Errorf(format string, args ...interface{}) {
 | 
						|
	c.logCaller(1)
 | 
						|
	c.logString(fmt.Sprintf("Error: "+format, args...))
 | 
						|
	c.logNewLine()
 | 
						|
	c.Fail()
 | 
						|
}
 | 
						|
 | 
						|
// Fatal logs an error into the test error output, marks the test as failed, and
 | 
						|
// stops the test execution. The provided arguments are assembled together into
 | 
						|
// a string with fmt.Sprint.
 | 
						|
func (c *C) Fatal(args ...interface{}) {
 | 
						|
	c.logCaller(1)
 | 
						|
	c.logString(fmt.Sprint("Error: ", fmt.Sprint(args...)))
 | 
						|
	c.logNewLine()
 | 
						|
	c.FailNow()
 | 
						|
}
 | 
						|
 | 
						|
// Fatlaf logs an error into the test error output, marks the test as failed, and
 | 
						|
// stops the test execution. The provided arguments are assembled together into
 | 
						|
// a string with fmt.Sprintf.
 | 
						|
func (c *C) Fatalf(format string, args ...interface{}) {
 | 
						|
	c.logCaller(1)
 | 
						|
	c.logString(fmt.Sprint("Error: ", fmt.Sprintf(format, args...)))
 | 
						|
	c.logNewLine()
 | 
						|
	c.FailNow()
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------
 | 
						|
// Generic checks and assertions based on checkers.
 | 
						|
 | 
						|
// Check verifies if the first value matches the expected value according
 | 
						|
// to the provided checker. If they do not match, an error is logged, the
 | 
						|
// test is marked as failed, and the test execution continues.
 | 
						|
//
 | 
						|
// Some checkers may not need the expected argument (e.g. IsNil).
 | 
						|
//
 | 
						|
// Extra arguments provided to the function are logged next to the reported
 | 
						|
// problem when the matching fails.
 | 
						|
func (c *C) Check(obtained interface{}, checker Checker, args ...interface{}) bool {
 | 
						|
	return c.internalCheck("Check", obtained, checker, args...)
 | 
						|
}
 | 
						|
 | 
						|
// Assert ensures that the first value matches the expected value according
 | 
						|
// to the provided checker. If they do not match, an error is logged, the
 | 
						|
// test is marked as failed, and the test execution stops.
 | 
						|
//
 | 
						|
// Some checkers may not need the expected argument (e.g. IsNil).
 | 
						|
//
 | 
						|
// Extra arguments provided to the function are logged next to the reported
 | 
						|
// problem when the matching fails.
 | 
						|
func (c *C) Assert(obtained interface{}, checker Checker, args ...interface{}) {
 | 
						|
	if !c.internalCheck("Assert", obtained, checker, args...) {
 | 
						|
		c.stopNow()
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (c *C) internalCheck(funcName string, obtained interface{}, checker Checker, args ...interface{}) bool {
 | 
						|
	if checker == nil {
 | 
						|
		c.logCaller(2)
 | 
						|
		c.logString(fmt.Sprintf("%s(obtained, nil!?, ...):", funcName))
 | 
						|
		c.logString("Oops.. you've provided a nil checker!")
 | 
						|
		c.logNewLine()
 | 
						|
		c.Fail()
 | 
						|
		return false
 | 
						|
	}
 | 
						|
 | 
						|
	// If the last argument is a bug info, extract it out.
 | 
						|
	var comment CommentInterface
 | 
						|
	if len(args) > 0 {
 | 
						|
		if c, ok := args[len(args)-1].(CommentInterface); ok {
 | 
						|
			comment = c
 | 
						|
			args = args[:len(args)-1]
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	params := append([]interface{}{obtained}, args...)
 | 
						|
	info := checker.Info()
 | 
						|
 | 
						|
	if len(params) != len(info.Params) {
 | 
						|
		names := append([]string{info.Params[0], info.Name}, info.Params[1:]...)
 | 
						|
		c.logCaller(2)
 | 
						|
		c.logString(fmt.Sprintf("%s(%s):", funcName, strings.Join(names, ", ")))
 | 
						|
		c.logString(fmt.Sprintf("Wrong number of parameters for %s: want %d, got %d", info.Name, len(names), len(params)+1))
 | 
						|
		c.logNewLine()
 | 
						|
		c.Fail()
 | 
						|
		return false
 | 
						|
	}
 | 
						|
 | 
						|
	// Copy since it may be mutated by Check.
 | 
						|
	names := append([]string{}, info.Params...)
 | 
						|
 | 
						|
	// Do the actual check.
 | 
						|
	result, error := checker.Check(params, names)
 | 
						|
	if !result || error != "" {
 | 
						|
		c.logCaller(2)
 | 
						|
		for i := 0; i != len(params); i++ {
 | 
						|
			c.logValue(names[i], params[i])
 | 
						|
		}
 | 
						|
		if comment != nil {
 | 
						|
			c.logString(comment.CheckCommentString())
 | 
						|
		}
 | 
						|
		if error != "" {
 | 
						|
			c.logString(error)
 | 
						|
		}
 | 
						|
		c.logNewLine()
 | 
						|
		c.Fail()
 | 
						|
		return false
 | 
						|
	}
 | 
						|
	return true
 | 
						|
}
 |