Add e2e tests

This commit is contained in:
Manuel de Brito Fontes 2017-10-17 19:50:27 -03:00
parent 99a355f25d
commit 601fb7dacf
1163 changed files with 289217 additions and 14195 deletions

183
vendor/github.com/onsi/ginkgo/internal/suite/suite.go generated vendored Normal file
View file

@ -0,0 +1,183 @@
package suite
import (
"math/rand"
"net/http"
"time"
"github.com/onsi/ginkgo/internal/spec_iterator"
"github.com/onsi/ginkgo/config"
"github.com/onsi/ginkgo/internal/containernode"
"github.com/onsi/ginkgo/internal/failer"
"github.com/onsi/ginkgo/internal/leafnodes"
"github.com/onsi/ginkgo/internal/spec"
"github.com/onsi/ginkgo/internal/specrunner"
"github.com/onsi/ginkgo/internal/writer"
"github.com/onsi/ginkgo/reporters"
"github.com/onsi/ginkgo/types"
)
type ginkgoTestingT interface {
Fail()
}
type Suite struct {
topLevelContainer *containernode.ContainerNode
currentContainer *containernode.ContainerNode
containerIndex int
beforeSuiteNode leafnodes.SuiteNode
afterSuiteNode leafnodes.SuiteNode
runner *specrunner.SpecRunner
failer *failer.Failer
running bool
}
func New(failer *failer.Failer) *Suite {
topLevelContainer := containernode.New("[Top Level]", types.FlagTypeNone, types.CodeLocation{})
return &Suite{
topLevelContainer: topLevelContainer,
currentContainer: topLevelContainer,
failer: failer,
containerIndex: 1,
}
}
func (suite *Suite) Run(t ginkgoTestingT, description string, reporters []reporters.Reporter, writer writer.WriterInterface, config config.GinkgoConfigType) (bool, bool) {
if config.ParallelTotal < 1 {
panic("ginkgo.parallel.total must be >= 1")
}
if config.ParallelNode > config.ParallelTotal || config.ParallelNode < 1 {
panic("ginkgo.parallel.node is one-indexed and must be <= ginkgo.parallel.total")
}
r := rand.New(rand.NewSource(config.RandomSeed))
suite.topLevelContainer.Shuffle(r)
iterator, hasProgrammaticFocus := suite.generateSpecsIterator(description, config)
suite.runner = specrunner.New(description, suite.beforeSuiteNode, iterator, suite.afterSuiteNode, reporters, writer, config)
suite.running = true
success := suite.runner.Run()
if !success {
t.Fail()
}
return success, hasProgrammaticFocus
}
func (suite *Suite) generateSpecsIterator(description string, config config.GinkgoConfigType) (spec_iterator.SpecIterator, bool) {
specsSlice := []*spec.Spec{}
suite.topLevelContainer.BackPropagateProgrammaticFocus()
for _, collatedNodes := range suite.topLevelContainer.Collate() {
specsSlice = append(specsSlice, spec.New(collatedNodes.Subject, collatedNodes.Containers, config.EmitSpecProgress))
}
specs := spec.NewSpecs(specsSlice)
specs.RegexScansFilePath = config.RegexScansFilePath
if config.RandomizeAllSpecs {
specs.Shuffle(rand.New(rand.NewSource(config.RandomSeed)))
}
specs.ApplyFocus(description, config.FocusString, config.SkipString)
if config.SkipMeasurements {
specs.SkipMeasurements()
}
var iterator spec_iterator.SpecIterator
if config.ParallelTotal > 1 {
iterator = spec_iterator.NewParallelIterator(specs.Specs(), config.SyncHost)
resp, err := http.Get(config.SyncHost + "/has-counter")
if err != nil || resp.StatusCode != http.StatusOK {
iterator = spec_iterator.NewShardedParallelIterator(specs.Specs(), config.ParallelTotal, config.ParallelNode)
}
} else {
iterator = spec_iterator.NewSerialIterator(specs.Specs())
}
return iterator, specs.HasProgrammaticFocus()
}
func (suite *Suite) CurrentRunningSpecSummary() (*types.SpecSummary, bool) {
return suite.runner.CurrentSpecSummary()
}
func (suite *Suite) SetBeforeSuiteNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) {
if suite.beforeSuiteNode != nil {
panic("You may only call BeforeSuite once!")
}
suite.beforeSuiteNode = leafnodes.NewBeforeSuiteNode(body, codeLocation, timeout, suite.failer)
}
func (suite *Suite) SetAfterSuiteNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) {
if suite.afterSuiteNode != nil {
panic("You may only call AfterSuite once!")
}
suite.afterSuiteNode = leafnodes.NewAfterSuiteNode(body, codeLocation, timeout, suite.failer)
}
func (suite *Suite) SetSynchronizedBeforeSuiteNode(bodyA interface{}, bodyB interface{}, codeLocation types.CodeLocation, timeout time.Duration) {
if suite.beforeSuiteNode != nil {
panic("You may only call BeforeSuite once!")
}
suite.beforeSuiteNode = leafnodes.NewSynchronizedBeforeSuiteNode(bodyA, bodyB, codeLocation, timeout, suite.failer)
}
func (suite *Suite) SetSynchronizedAfterSuiteNode(bodyA interface{}, bodyB interface{}, codeLocation types.CodeLocation, timeout time.Duration) {
if suite.afterSuiteNode != nil {
panic("You may only call AfterSuite once!")
}
suite.afterSuiteNode = leafnodes.NewSynchronizedAfterSuiteNode(bodyA, bodyB, codeLocation, timeout, suite.failer)
}
func (suite *Suite) PushContainerNode(text string, body func(), flag types.FlagType, codeLocation types.CodeLocation) {
container := containernode.New(text, flag, codeLocation)
suite.currentContainer.PushContainerNode(container)
previousContainer := suite.currentContainer
suite.currentContainer = container
suite.containerIndex++
body()
suite.containerIndex--
suite.currentContainer = previousContainer
}
func (suite *Suite) PushItNode(text string, body interface{}, flag types.FlagType, codeLocation types.CodeLocation, timeout time.Duration) {
if suite.running {
suite.failer.Fail("You may only call It from within a Describe or Context", codeLocation)
}
suite.currentContainer.PushSubjectNode(leafnodes.NewItNode(text, body, flag, codeLocation, timeout, suite.failer, suite.containerIndex))
}
func (suite *Suite) PushMeasureNode(text string, body interface{}, flag types.FlagType, codeLocation types.CodeLocation, samples int) {
if suite.running {
suite.failer.Fail("You may only call Measure from within a Describe or Context", codeLocation)
}
suite.currentContainer.PushSubjectNode(leafnodes.NewMeasureNode(text, body, flag, codeLocation, samples, suite.failer, suite.containerIndex))
}
func (suite *Suite) PushBeforeEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) {
if suite.running {
suite.failer.Fail("You may only call BeforeEach from within a Describe or Context", codeLocation)
}
suite.currentContainer.PushSetupNode(leafnodes.NewBeforeEachNode(body, codeLocation, timeout, suite.failer, suite.containerIndex))
}
func (suite *Suite) PushJustBeforeEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) {
if suite.running {
suite.failer.Fail("You may only call JustBeforeEach from within a Describe or Context", codeLocation)
}
suite.currentContainer.PushSetupNode(leafnodes.NewJustBeforeEachNode(body, codeLocation, timeout, suite.failer, suite.containerIndex))
}
func (suite *Suite) PushAfterEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) {
if suite.running {
suite.failer.Fail("You may only call AfterEach from within a Describe or Context", codeLocation)
}
suite.currentContainer.PushSetupNode(leafnodes.NewAfterEachNode(body, codeLocation, timeout, suite.failer, suite.containerIndex))
}

View file

@ -0,0 +1,35 @@
package suite_test
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"testing"
)
func Test(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Suite")
}
var numBeforeSuiteRuns = 0
var numAfterSuiteRuns = 0
var _ = BeforeSuite(func() {
numBeforeSuiteRuns++
})
var _ = AfterSuite(func() {
numAfterSuiteRuns++
Ω(numBeforeSuiteRuns).Should(Equal(1))
Ω(numAfterSuiteRuns).Should(Equal(1))
})
//Fakes
type fakeTestingT struct {
didFail bool
}
func (fakeT *fakeTestingT) Fail() {
fakeT.didFail = true
}

View file

@ -0,0 +1,371 @@
package suite_test
import (
"bytes"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/internal/suite"
. "github.com/onsi/gomega"
"math/rand"
"time"
"github.com/onsi/ginkgo/config"
"github.com/onsi/ginkgo/internal/codelocation"
Failer "github.com/onsi/ginkgo/internal/failer"
Writer "github.com/onsi/ginkgo/internal/writer"
"github.com/onsi/ginkgo/reporters"
"github.com/onsi/ginkgo/types"
)
var _ = Describe("Suite", func() {
var (
specSuite *Suite
fakeT *fakeTestingT
fakeR *reporters.FakeReporter
writer *Writer.FakeGinkgoWriter
failer *Failer.Failer
)
BeforeEach(func() {
writer = Writer.NewFake()
fakeT = &fakeTestingT{}
fakeR = reporters.NewFakeReporter()
failer = Failer.New()
specSuite = New(failer)
})
Describe("running a suite", func() {
var (
runOrder []string
randomizeAllSpecs bool
randomSeed int64
focusString string
parallelNode int
parallelTotal int
runResult bool
hasProgrammaticFocus bool
)
var f = func(runText string) func() {
return func() {
runOrder = append(runOrder, runText)
}
}
BeforeEach(func() {
randomizeAllSpecs = false
randomSeed = 11
parallelNode = 1
parallelTotal = 1
focusString = ""
runOrder = make([]string, 0)
specSuite.SetBeforeSuiteNode(f("BeforeSuite"), codelocation.New(0), 0)
specSuite.PushBeforeEachNode(f("top BE"), codelocation.New(0), 0)
specSuite.PushJustBeforeEachNode(f("top JBE"), codelocation.New(0), 0)
specSuite.PushAfterEachNode(f("top AE"), codelocation.New(0), 0)
specSuite.PushContainerNode("container", func() {
specSuite.PushBeforeEachNode(f("BE"), codelocation.New(0), 0)
specSuite.PushJustBeforeEachNode(f("JBE"), codelocation.New(0), 0)
specSuite.PushAfterEachNode(f("AE"), codelocation.New(0), 0)
specSuite.PushItNode("it", f("IT"), types.FlagTypeNone, codelocation.New(0), 0)
specSuite.PushContainerNode("inner container", func() {
specSuite.PushItNode("inner it", f("inner IT"), types.FlagTypeNone, codelocation.New(0), 0)
}, types.FlagTypeNone, codelocation.New(0))
}, types.FlagTypeNone, codelocation.New(0))
specSuite.PushContainerNode("container 2", func() {
specSuite.PushBeforeEachNode(f("BE 2"), codelocation.New(0), 0)
specSuite.PushItNode("it 2", f("IT 2"), types.FlagTypeNone, codelocation.New(0), 0)
}, types.FlagTypeNone, codelocation.New(0))
specSuite.PushItNode("top level it", f("top IT"), types.FlagTypeNone, codelocation.New(0), 0)
specSuite.SetAfterSuiteNode(f("AfterSuite"), codelocation.New(0), 0)
})
JustBeforeEach(func() {
runResult, hasProgrammaticFocus = specSuite.Run(fakeT, "suite description", []reporters.Reporter{fakeR}, writer, config.GinkgoConfigType{
RandomSeed: randomSeed,
RandomizeAllSpecs: randomizeAllSpecs,
FocusString: focusString,
ParallelNode: parallelNode,
ParallelTotal: parallelTotal,
})
})
It("provides the config and suite description to the reporter", func() {
Ω(fakeR.Config.RandomSeed).Should(Equal(int64(randomSeed)))
Ω(fakeR.Config.RandomizeAllSpecs).Should(Equal(randomizeAllSpecs))
Ω(fakeR.BeginSummary.SuiteDescription).Should(Equal("suite description"))
})
It("reports that the BeforeSuite node ran", func() {
Ω(fakeR.BeforeSuiteSummary).ShouldNot(BeNil())
})
It("reports that the AfterSuite node ran", func() {
Ω(fakeR.AfterSuiteSummary).ShouldNot(BeNil())
})
It("provides information about the current test", func() {
description := CurrentGinkgoTestDescription()
Ω(description.ComponentTexts).Should(Equal([]string{"Suite", "running a suite", "provides information about the current test"}))
Ω(description.FullTestText).Should(Equal("Suite running a suite provides information about the current test"))
Ω(description.TestText).Should(Equal("provides information about the current test"))
Ω(description.IsMeasurement).Should(BeFalse())
Ω(description.FileName).Should(ContainSubstring("suite_test.go"))
Ω(description.LineNumber).Should(BeNumerically(">", 50))
Ω(description.LineNumber).Should(BeNumerically("<", 150))
Ω(description.Failed).Should(BeFalse())
})
Measure("should run measurements", func(b Benchmarker) {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
runtime := b.Time("sleeping", func() {
sleepTime := time.Duration(r.Float64() * 0.01 * float64(time.Second))
time.Sleep(sleepTime)
})
Ω(runtime.Seconds()).Should(BeNumerically("<=", 1))
Ω(runtime.Seconds()).Should(BeNumerically(">=", 0))
randomValue := r.Float64() * 10.0
b.RecordValue("random value", randomValue)
Ω(randomValue).Should(BeNumerically("<=", 10.0))
Ω(randomValue).Should(BeNumerically(">=", 0.0))
b.RecordValueWithPrecision("specific value", 123.4567, "ms", 2)
b.RecordValueWithPrecision("specific value", 234.5678, "ms", 2)
}, 10)
It("creates a node hierarchy, converts it to a spec collection, and runs it", func() {
Ω(runOrder).Should(Equal([]string{
"BeforeSuite",
"top BE", "BE", "top JBE", "JBE", "IT", "AE", "top AE",
"top BE", "BE", "top JBE", "JBE", "inner IT", "AE", "top AE",
"top BE", "BE 2", "top JBE", "IT 2", "top AE",
"top BE", "top JBE", "top IT", "top AE",
"AfterSuite",
}))
})
Context("when told to randomize all specs", func() {
BeforeEach(func() {
randomizeAllSpecs = true
})
It("does", func() {
Ω(runOrder).Should(Equal([]string{
"BeforeSuite",
"top BE", "top JBE", "top IT", "top AE",
"top BE", "BE", "top JBE", "JBE", "inner IT", "AE", "top AE",
"top BE", "BE", "top JBE", "JBE", "IT", "AE", "top AE",
"top BE", "BE 2", "top JBE", "IT 2", "top AE",
"AfterSuite",
}))
})
})
Context("when provided with a filter", func() {
BeforeEach(func() {
focusString = `inner|\d`
})
It("converts the filter to a regular expression and uses it to filter the running specs", func() {
Ω(runOrder).Should(Equal([]string{
"BeforeSuite",
"top BE", "BE", "top JBE", "JBE", "inner IT", "AE", "top AE",
"top BE", "BE 2", "top JBE", "IT 2", "top AE",
"AfterSuite",
}))
})
It("should not report a programmatic focus", func() {
Ω(hasProgrammaticFocus).Should(BeFalse())
})
})
Context("with a programatically focused spec", func() {
BeforeEach(func() {
specSuite.PushItNode("focused it", f("focused it"), types.FlagTypeFocused, codelocation.New(0), 0)
specSuite.PushContainerNode("focused container", func() {
specSuite.PushItNode("inner focused it", f("inner focused it"), types.FlagTypeFocused, codelocation.New(0), 0)
specSuite.PushItNode("inner unfocused it", f("inner unfocused it"), types.FlagTypeNone, codelocation.New(0), 0)
}, types.FlagTypeFocused, codelocation.New(0))
})
It("should only run the focused test, applying backpropagation to favor most deeply focused leaf nodes", func() {
Ω(runOrder).Should(Equal([]string{
"BeforeSuite",
"top BE", "top JBE", "focused it", "top AE",
"top BE", "top JBE", "inner focused it", "top AE",
"AfterSuite",
}))
})
It("should report a programmatic focus", func() {
Ω(hasProgrammaticFocus).Should(BeTrue())
})
})
Context("when the specs pass", func() {
It("doesn't report a failure", func() {
Ω(fakeT.didFail).Should(BeFalse())
})
It("should return true", func() {
Ω(runResult).Should(BeTrue())
})
})
Context("when a spec fails", func() {
var location types.CodeLocation
BeforeEach(func() {
specSuite.PushItNode("top level it", func() {
location = codelocation.New(0)
failer.Fail("oops!", location)
}, types.FlagTypeNone, codelocation.New(0), 0)
})
It("should return false", func() {
Ω(runResult).Should(BeFalse())
})
It("reports a failure", func() {
Ω(fakeT.didFail).Should(BeTrue())
})
It("generates the correct failure data", func() {
Ω(fakeR.SpecSummaries[0].Failure.Message).Should(Equal("oops!"))
Ω(fakeR.SpecSummaries[0].Failure.Location).Should(Equal(location))
})
})
Context("when runnable nodes are nested within other runnable nodes", func() {
Context("when an It is nested", func() {
BeforeEach(func() {
specSuite.PushItNode("top level it", func() {
specSuite.PushItNode("nested it", f("oops"), types.FlagTypeNone, codelocation.New(0), 0)
}, types.FlagTypeNone, codelocation.New(0), 0)
})
It("should fail", func() {
Ω(fakeT.didFail).Should(BeTrue())
})
})
Context("when a Measure is nested", func() {
BeforeEach(func() {
specSuite.PushItNode("top level it", func() {
specSuite.PushMeasureNode("nested measure", func(Benchmarker) {}, types.FlagTypeNone, codelocation.New(0), 10)
}, types.FlagTypeNone, codelocation.New(0), 0)
})
It("should fail", func() {
Ω(fakeT.didFail).Should(BeTrue())
})
})
Context("when a BeforeEach is nested", func() {
BeforeEach(func() {
specSuite.PushItNode("top level it", func() {
specSuite.PushBeforeEachNode(f("nested bef"), codelocation.New(0), 0)
}, types.FlagTypeNone, codelocation.New(0), 0)
})
It("should fail", func() {
Ω(fakeT.didFail).Should(BeTrue())
})
})
Context("when a JustBeforeEach is nested", func() {
BeforeEach(func() {
specSuite.PushItNode("top level it", func() {
specSuite.PushJustBeforeEachNode(f("nested jbef"), codelocation.New(0), 0)
}, types.FlagTypeNone, codelocation.New(0), 0)
})
It("should fail", func() {
Ω(fakeT.didFail).Should(BeTrue())
})
})
Context("when a AfterEach is nested", func() {
BeforeEach(func() {
specSuite.PushItNode("top level it", func() {
specSuite.PushAfterEachNode(f("nested aft"), codelocation.New(0), 0)
}, types.FlagTypeNone, codelocation.New(0), 0)
})
It("should fail", func() {
Ω(fakeT.didFail).Should(BeTrue())
})
})
})
})
Describe("BeforeSuite", func() {
Context("when setting BeforeSuite more than once", func() {
It("should panic", func() {
specSuite.SetBeforeSuiteNode(func() {}, codelocation.New(0), 0)
Ω(func() {
specSuite.SetBeforeSuiteNode(func() {}, codelocation.New(0), 0)
}).Should(Panic())
})
})
})
Describe("AfterSuite", func() {
Context("when setting AfterSuite more than once", func() {
It("should panic", func() {
specSuite.SetAfterSuiteNode(func() {}, codelocation.New(0), 0)
Ω(func() {
specSuite.SetAfterSuiteNode(func() {}, codelocation.New(0), 0)
}).Should(Panic())
})
})
})
Describe("By", func() {
It("writes to the GinkgoWriter", func() {
originalGinkgoWriter := GinkgoWriter
buffer := &bytes.Buffer{}
GinkgoWriter = buffer
By("Saying Hello GinkgoWriter")
GinkgoWriter = originalGinkgoWriter
Ω(buffer.String()).Should(ContainSubstring("STEP"))
Ω(buffer.String()).Should(ContainSubstring(": Saying Hello GinkgoWriter\n"))
})
It("calls the passed-in callback if present", func() {
a := 0
By("calling the callback", func() {
a = 1
})
Ω(a).Should(Equal(1))
})
It("panics if there is more than one callback", func() {
Ω(func() {
By("registering more than one callback", func() {}, func() {})
}).Should(Panic())
})
})
Describe("GinkgoRandomSeed", func() {
It("returns the current config's random seed", func() {
Ω(GinkgoRandomSeed()).Should(Equal(config.GinkgoConfig.RandomSeed))
})
})
})