summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/stretchr/testify/suite
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/stretchr/testify/suite')
-rw-r--r--vendor/github.com/stretchr/testify/suite/interfaces.go7
-rw-r--r--vendor/github.com/stretchr/testify/suite/stats.go46
-rw-r--r--vendor/github.com/stretchr/testify/suite/suite.go102
3 files changed, 123 insertions, 32 deletions
diff --git a/vendor/github.com/stretchr/testify/suite/interfaces.go b/vendor/github.com/stretchr/testify/suite/interfaces.go
index b37cb040..8b98a8af 100644
--- a/vendor/github.com/stretchr/testify/suite/interfaces.go
+++ b/vendor/github.com/stretchr/testify/suite/interfaces.go
@@ -44,3 +44,10 @@ type BeforeTest interface {
type AfterTest interface {
AfterTest(suiteName, testName string)
}
+
+// WithStats implements HandleStats, a function that will be executed
+// when a test suite is finished. The stats contain information about
+// the execution of that suite and its tests.
+type WithStats interface {
+ HandleStats(suiteName string, stats *SuiteInformation)
+}
diff --git a/vendor/github.com/stretchr/testify/suite/stats.go b/vendor/github.com/stretchr/testify/suite/stats.go
new file mode 100644
index 00000000..261da37f
--- /dev/null
+++ b/vendor/github.com/stretchr/testify/suite/stats.go
@@ -0,0 +1,46 @@
+package suite
+
+import "time"
+
+// SuiteInformation stats stores stats for the whole suite execution.
+type SuiteInformation struct {
+ Start, End time.Time
+ TestStats map[string]*TestInformation
+}
+
+// TestInformation stores information about the execution of each test.
+type TestInformation struct {
+ TestName string
+ Start, End time.Time
+ Passed bool
+}
+
+func newSuiteInformation() *SuiteInformation {
+ testStats := make(map[string]*TestInformation)
+
+ return &SuiteInformation{
+ TestStats: testStats,
+ }
+}
+
+func (s SuiteInformation) start(testName string) {
+ s.TestStats[testName] = &TestInformation{
+ TestName: testName,
+ Start: time.Now(),
+ }
+}
+
+func (s SuiteInformation) end(testName string, passed bool) {
+ s.TestStats[testName].End = time.Now()
+ s.TestStats[testName].Passed = passed
+}
+
+func (s SuiteInformation) Passed() bool {
+ for _, stats := range s.TestStats {
+ if !stats.Passed {
+ return false
+ }
+ }
+
+ return true
+}
diff --git a/vendor/github.com/stretchr/testify/suite/suite.go b/vendor/github.com/stretchr/testify/suite/suite.go
index 61953018..b9b5d1c5 100644
--- a/vendor/github.com/stretchr/testify/suite/suite.go
+++ b/vendor/github.com/stretchr/testify/suite/suite.go
@@ -7,8 +7,8 @@ import (
"reflect"
"regexp"
"runtime/debug"
- "sync"
"testing"
+ "time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -81,69 +81,116 @@ func (suite *Suite) Run(name string, subtest func()) bool {
// Run takes a testing suite and runs all of the tests attached
// to it.
func Run(t *testing.T, suite TestingSuite) {
- testsSync := &sync.WaitGroup{}
- suite.SetT(t)
defer failOnPanic(t)
- suiteSetupDone := false
+ suite.SetT(t)
+
+ var suiteSetupDone bool
+
+ var stats *SuiteInformation
+ if _, ok := suite.(WithStats); ok {
+ stats = newSuiteInformation()
+ }
- methodFinder := reflect.TypeOf(suite)
tests := []testing.InternalTest{}
- for index := 0; index < methodFinder.NumMethod(); index++ {
- method := methodFinder.Method(index)
+ methodFinder := reflect.TypeOf(suite)
+ suiteName := methodFinder.Elem().Name()
+
+ for i := 0; i < methodFinder.NumMethod(); i++ {
+ method := methodFinder.Method(i)
+
ok, err := methodFilter(method.Name)
if err != nil {
fmt.Fprintf(os.Stderr, "testify: invalid regexp for -m: %s\n", err)
os.Exit(1)
}
+
if !ok {
continue
}
+
if !suiteSetupDone {
+ if stats != nil {
+ stats.Start = time.Now()
+ }
+
if setupAllSuite, ok := suite.(SetupAllSuite); ok {
setupAllSuite.SetupSuite()
}
- defer func() {
- if tearDownAllSuite, ok := suite.(TearDownAllSuite); ok {
- testsSync.Wait()
- tearDownAllSuite.TearDownSuite()
- }
- }()
+
suiteSetupDone = true
}
+
test := testing.InternalTest{
Name: method.Name,
F: func(t *testing.T) {
- defer testsSync.Done()
parentT := suite.T()
suite.SetT(t)
defer failOnPanic(t)
-
- if setupTestSuite, ok := suite.(SetupTestSuite); ok {
- setupTestSuite.SetupTest()
- }
- if beforeTestSuite, ok := suite.(BeforeTest); ok {
- beforeTestSuite.BeforeTest(methodFinder.Elem().Name(), method.Name)
- }
defer func() {
+ if stats != nil {
+ passed := !t.Failed()
+ stats.end(method.Name, passed)
+ }
+
if afterTestSuite, ok := suite.(AfterTest); ok {
- afterTestSuite.AfterTest(methodFinder.Elem().Name(), method.Name)
+ afterTestSuite.AfterTest(suiteName, method.Name)
}
+
if tearDownTestSuite, ok := suite.(TearDownTestSuite); ok {
tearDownTestSuite.TearDownTest()
}
+
suite.SetT(parentT)
}()
+
+ if setupTestSuite, ok := suite.(SetupTestSuite); ok {
+ setupTestSuite.SetupTest()
+ }
+ if beforeTestSuite, ok := suite.(BeforeTest); ok {
+ beforeTestSuite.BeforeTest(methodFinder.Elem().Name(), method.Name)
+ }
+
+ if stats != nil {
+ stats.start(method.Name)
+ }
+
method.Func.Call([]reflect.Value{reflect.ValueOf(suite)})
},
}
tests = append(tests, test)
- testsSync.Add(1)
}
+ if suiteSetupDone {
+ defer func() {
+ if tearDownAllSuite, ok := suite.(TearDownAllSuite); ok {
+ tearDownAllSuite.TearDownSuite()
+ }
+
+ if suiteWithStats, measureStats := suite.(WithStats); measureStats {
+ stats.End = time.Now()
+ suiteWithStats.HandleStats(suiteName, stats)
+ }
+ }()
+ }
+
runTests(t, tests)
}
+// Filtering method according to set regular expression
+// specified command-line argument -m
+func methodFilter(name string) (bool, error) {
+ if ok, _ := regexp.MatchString("^Test", name); !ok {
+ return false, nil
+ }
+ return regexp.MatchString(*matchMethod, name)
+}
+
func runTests(t testing.TB, tests []testing.InternalTest) {
+ if len(tests) == 0 {
+ t.Log("warning: no tests to run")
+ return
+ }
+
r, ok := t.(runner)
if !ok { // backwards compatibility with Go 1.6 and below
if !testing.RunTests(allTestsFilter, tests) {
@@ -157,15 +204,6 @@ func runTests(t testing.TB, tests []testing.InternalTest) {
}
}
-// Filtering method according to set regular expression
-// specified command-line argument -m
-func methodFilter(name string) (bool, error) {
- if ok, _ := regexp.MatchString("^Test", name); !ok {
- return false, nil
- }
- return regexp.MatchString(*matchMethod, name)
-}
-
type runner interface {
Run(name string, f func(t *testing.T)) bool
}