372 lines
11 KiB
Go
372 lines
11 KiB
Go
|
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))
|
||
|
})
|
||
|
})
|
||
|
})
|