Blame vendor/github.com/stretchr/testify/suite/suite.go

Packit 63bb0d
package suite
Packit 63bb0d
Packit 63bb0d
import (
Packit 63bb0d
	"flag"
Packit 63bb0d
	"fmt"
Packit 63bb0d
	"os"
Packit 63bb0d
	"reflect"
Packit 63bb0d
	"regexp"
Packit 63bb0d
	"runtime/debug"
Packit Service 509fd4
	"sync"
Packit 63bb0d
	"testing"
Packit 63bb0d
Packit 63bb0d
	"github.com/stretchr/testify/assert"
Packit 63bb0d
	"github.com/stretchr/testify/require"
Packit 63bb0d
)
Packit 63bb0d
Packit 63bb0d
var allTestsFilter = func(_, _ string) (bool, error) { return true, nil }
Packit 63bb0d
var matchMethod = flag.String("testify.m", "", "regular expression to select tests of the testify suite to run")
Packit 63bb0d
Packit 63bb0d
// Suite is a basic testing suite with methods for storing and
Packit 63bb0d
// retrieving the current *testing.T context.
Packit 63bb0d
type Suite struct {
Packit 63bb0d
	*assert.Assertions
Packit 63bb0d
	require *require.Assertions
Packit 63bb0d
	t       *testing.T
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// T retrieves the current *testing.T context.
Packit 63bb0d
func (suite *Suite) T() *testing.T {
Packit 63bb0d
	return suite.t
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// SetT sets the current *testing.T context.
Packit 63bb0d
func (suite *Suite) SetT(t *testing.T) {
Packit 63bb0d
	suite.t = t
Packit 63bb0d
	suite.Assertions = assert.New(t)
Packit 63bb0d
	suite.require = require.New(t)
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Require returns a require context for suite.
Packit 63bb0d
func (suite *Suite) Require() *require.Assertions {
Packit 63bb0d
	if suite.require == nil {
Packit 63bb0d
		suite.require = require.New(suite.T())
Packit 63bb0d
	}
Packit 63bb0d
	return suite.require
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Assert returns an assert context for suite.  Normally, you can call
Packit 63bb0d
// `suite.NoError(expected, actual)`, but for situations where the embedded
Packit 63bb0d
// methods are overridden (for example, you might want to override
Packit 63bb0d
// assert.Assertions with require.Assertions), this method is provided so you
Packit 63bb0d
// can call `suite.Assert().NoError()`.
Packit 63bb0d
func (suite *Suite) Assert() *assert.Assertions {
Packit 63bb0d
	if suite.Assertions == nil {
Packit 63bb0d
		suite.Assertions = assert.New(suite.T())
Packit 63bb0d
	}
Packit 63bb0d
	return suite.Assertions
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func failOnPanic(t *testing.T) {
Packit 63bb0d
	r := recover()
Packit 63bb0d
	if r != nil {
Packit 63bb0d
		t.Errorf("test panicked: %v\n%s", r, debug.Stack())
Packit 63bb0d
		t.FailNow()
Packit 63bb0d
	}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Run provides suite functionality around golang subtests.  It should be
Packit 63bb0d
// called in place of t.Run(name, func(t *testing.T)) in test suite code.
Packit 63bb0d
// The passed-in func will be executed as a subtest with a fresh instance of t.
Packit 63bb0d
// Provides compatibility with go test pkg -run TestSuite/TestName/SubTestName.
Packit 63bb0d
func (suite *Suite) Run(name string, subtest func()) bool {
Packit 63bb0d
	oldT := suite.T()
Packit 63bb0d
	defer suite.SetT(oldT)
Packit 63bb0d
	return oldT.Run(name, func(t *testing.T) {
Packit 63bb0d
		suite.SetT(t)
Packit 63bb0d
		subtest()
Packit 63bb0d
	})
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Run takes a testing suite and runs all of the tests attached
Packit 63bb0d
// to it.
Packit 63bb0d
func Run(t *testing.T, suite TestingSuite) {
Packit Service 509fd4
	testsSync := &sync.WaitGroup{}
Packit 63bb0d
	suite.SetT(t)
Packit 63bb0d
	defer failOnPanic(t)
Packit 63bb0d
Packit 63bb0d
	suiteSetupDone := false
Packit Service 509fd4
Packit 63bb0d
	methodFinder := reflect.TypeOf(suite)
Packit 63bb0d
	tests := []testing.InternalTest{}
Packit 63bb0d
	for index := 0; index < methodFinder.NumMethod(); index++ {
Packit 63bb0d
		method := methodFinder.Method(index)
Packit 63bb0d
		ok, err := methodFilter(method.Name)
Packit 63bb0d
		if err != nil {
Packit 63bb0d
			fmt.Fprintf(os.Stderr, "testify: invalid regexp for -m: %s\n", err)
Packit 63bb0d
			os.Exit(1)
Packit 63bb0d
		}
Packit 63bb0d
		if !ok {
Packit 63bb0d
			continue
Packit 63bb0d
		}
Packit 63bb0d
		if !suiteSetupDone {
Packit 63bb0d
			if setupAllSuite, ok := suite.(SetupAllSuite); ok {
Packit 63bb0d
				setupAllSuite.SetupSuite()
Packit 63bb0d
			}
Packit 63bb0d
			defer func() {
Packit 63bb0d
				if tearDownAllSuite, ok := suite.(TearDownAllSuite); ok {
Packit Service 509fd4
					testsSync.Wait()
Packit 63bb0d
					tearDownAllSuite.TearDownSuite()
Packit 63bb0d
				}
Packit 63bb0d
			}()
Packit 63bb0d
			suiteSetupDone = true
Packit 63bb0d
		}
Packit 63bb0d
		test := testing.InternalTest{
Packit 63bb0d
			Name: method.Name,
Packit 63bb0d
			F: func(t *testing.T) {
Packit Service 509fd4
				defer testsSync.Done()
Packit 63bb0d
				parentT := suite.T()
Packit 63bb0d
				suite.SetT(t)
Packit 63bb0d
				defer failOnPanic(t)
Packit 63bb0d
Packit 63bb0d
				if setupTestSuite, ok := suite.(SetupTestSuite); ok {
Packit 63bb0d
					setupTestSuite.SetupTest()
Packit 63bb0d
				}
Packit 63bb0d
				if beforeTestSuite, ok := suite.(BeforeTest); ok {
Packit 63bb0d
					beforeTestSuite.BeforeTest(methodFinder.Elem().Name(), method.Name)
Packit 63bb0d
				}
Packit 63bb0d
				defer func() {
Packit 63bb0d
					if afterTestSuite, ok := suite.(AfterTest); ok {
Packit 63bb0d
						afterTestSuite.AfterTest(methodFinder.Elem().Name(), method.Name)
Packit 63bb0d
					}
Packit 63bb0d
					if tearDownTestSuite, ok := suite.(TearDownTestSuite); ok {
Packit 63bb0d
						tearDownTestSuite.TearDownTest()
Packit 63bb0d
					}
Packit 63bb0d
					suite.SetT(parentT)
Packit 63bb0d
				}()
Packit 63bb0d
				method.Func.Call([]reflect.Value{reflect.ValueOf(suite)})
Packit 63bb0d
			},
Packit 63bb0d
		}
Packit 63bb0d
		tests = append(tests, test)
Packit Service 509fd4
		testsSync.Add(1)
Packit 63bb0d
	}
Packit 63bb0d
	runTests(t, tests)
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func runTests(t testing.TB, tests []testing.InternalTest) {
Packit 63bb0d
	r, ok := t.(runner)
Packit 63bb0d
	if !ok { // backwards compatibility with Go 1.6 and below
Packit 63bb0d
		if !testing.RunTests(allTestsFilter, tests) {
Packit 63bb0d
			t.Fail()
Packit 63bb0d
		}
Packit 63bb0d
		return
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	for _, test := range tests {
Packit 63bb0d
		r.Run(test.Name, test.F)
Packit 63bb0d
	}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Filtering method according to set regular expression
Packit 63bb0d
// specified command-line argument -m
Packit 63bb0d
func methodFilter(name string) (bool, error) {
Packit 63bb0d
	if ok, _ := regexp.MatchString("^Test", name); !ok {
Packit 63bb0d
		return false, nil
Packit 63bb0d
	}
Packit 63bb0d
	return regexp.MatchString(*matchMethod, name)
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
type runner interface {
Packit 63bb0d
	Run(name string, f func(t *testing.T)) bool
Packit 63bb0d
}