summaryrefslogtreecommitdiff
path: root/vendor/github.com/onsi/ginkgo/internal/spec
diff options
context:
space:
mode:
authorValentin Rothberg <rothberg@redhat.com>2019-02-05 11:51:41 +0100
committerValentin Rothberg <rothberg@redhat.com>2019-02-06 11:14:06 +0100
commit9ac0ebb0791851aea81ecc847802db5a39bfb6e7 (patch)
tree30ad98bcc2c2dd1136f46a48cbc44d422adfa184 /vendor/github.com/onsi/ginkgo/internal/spec
parent51714d5da7aaa19014fd67b48b79dfbd5f69c1f0 (diff)
downloadpodman-9ac0ebb0791851aea81ecc847802db5a39bfb6e7.tar.gz
podman-9ac0ebb0791851aea81ecc847802db5a39bfb6e7.tar.bz2
podman-9ac0ebb0791851aea81ecc847802db5a39bfb6e7.zip
Cirrus: add vendor_check_task
* Make sure that all vendored dependencies are in sync with the code and the vendor.conf by running `make vendor` with a follow-up status check of the git tree. * Vendor ginkgo and gomega to include the test dependencies. Signed-off-by: Chris Evic <cevich@redhat.com> Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Diffstat (limited to 'vendor/github.com/onsi/ginkgo/internal/spec')
-rw-r--r--vendor/github.com/onsi/ginkgo/internal/spec/spec.go247
-rw-r--r--vendor/github.com/onsi/ginkgo/internal/spec/spec_suite_test.go13
-rw-r--r--vendor/github.com/onsi/ginkgo/internal/spec/spec_test.go739
-rw-r--r--vendor/github.com/onsi/ginkgo/internal/spec/specs.go123
-rw-r--r--vendor/github.com/onsi/ginkgo/internal/spec/specs_test.go287
5 files changed, 1409 insertions, 0 deletions
diff --git a/vendor/github.com/onsi/ginkgo/internal/spec/spec.go b/vendor/github.com/onsi/ginkgo/internal/spec/spec.go
new file mode 100644
index 000000000..7fd68ee8e
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/internal/spec/spec.go
@@ -0,0 +1,247 @@
+package spec
+
+import (
+ "fmt"
+ "io"
+ "time"
+
+ "sync"
+
+ "github.com/onsi/ginkgo/internal/containernode"
+ "github.com/onsi/ginkgo/internal/leafnodes"
+ "github.com/onsi/ginkgo/types"
+)
+
+type Spec struct {
+ subject leafnodes.SubjectNode
+ focused bool
+ announceProgress bool
+
+ containers []*containernode.ContainerNode
+
+ state types.SpecState
+ runTime time.Duration
+ startTime time.Time
+ failure types.SpecFailure
+ previousFailures bool
+
+ stateMutex *sync.Mutex
+}
+
+func New(subject leafnodes.SubjectNode, containers []*containernode.ContainerNode, announceProgress bool) *Spec {
+ spec := &Spec{
+ subject: subject,
+ containers: containers,
+ focused: subject.Flag() == types.FlagTypeFocused,
+ announceProgress: announceProgress,
+ stateMutex: &sync.Mutex{},
+ }
+
+ spec.processFlag(subject.Flag())
+ for i := len(containers) - 1; i >= 0; i-- {
+ spec.processFlag(containers[i].Flag())
+ }
+
+ return spec
+}
+
+func (spec *Spec) processFlag(flag types.FlagType) {
+ if flag == types.FlagTypeFocused {
+ spec.focused = true
+ } else if flag == types.FlagTypePending {
+ spec.setState(types.SpecStatePending)
+ }
+}
+
+func (spec *Spec) Skip() {
+ spec.setState(types.SpecStateSkipped)
+}
+
+func (spec *Spec) Failed() bool {
+ return spec.getState() == types.SpecStateFailed || spec.getState() == types.SpecStatePanicked || spec.getState() == types.SpecStateTimedOut
+}
+
+func (spec *Spec) Passed() bool {
+ return spec.getState() == types.SpecStatePassed
+}
+
+func (spec *Spec) Flaked() bool {
+ return spec.getState() == types.SpecStatePassed && spec.previousFailures
+}
+
+func (spec *Spec) Pending() bool {
+ return spec.getState() == types.SpecStatePending
+}
+
+func (spec *Spec) Skipped() bool {
+ return spec.getState() == types.SpecStateSkipped
+}
+
+func (spec *Spec) Focused() bool {
+ return spec.focused
+}
+
+func (spec *Spec) IsMeasurement() bool {
+ return spec.subject.Type() == types.SpecComponentTypeMeasure
+}
+
+func (spec *Spec) Summary(suiteID string) *types.SpecSummary {
+ componentTexts := make([]string, len(spec.containers)+1)
+ componentCodeLocations := make([]types.CodeLocation, len(spec.containers)+1)
+
+ for i, container := range spec.containers {
+ componentTexts[i] = container.Text()
+ componentCodeLocations[i] = container.CodeLocation()
+ }
+
+ componentTexts[len(spec.containers)] = spec.subject.Text()
+ componentCodeLocations[len(spec.containers)] = spec.subject.CodeLocation()
+
+ runTime := spec.runTime
+ if runTime == 0 && !spec.startTime.IsZero() {
+ runTime = time.Since(spec.startTime)
+ }
+
+ return &types.SpecSummary{
+ IsMeasurement: spec.IsMeasurement(),
+ NumberOfSamples: spec.subject.Samples(),
+ ComponentTexts: componentTexts,
+ ComponentCodeLocations: componentCodeLocations,
+ State: spec.getState(),
+ RunTime: runTime,
+ Failure: spec.failure,
+ Measurements: spec.measurementsReport(),
+ SuiteID: suiteID,
+ }
+}
+
+func (spec *Spec) ConcatenatedString() string {
+ s := ""
+ for _, container := range spec.containers {
+ s += container.Text() + " "
+ }
+
+ return s + spec.subject.Text()
+}
+
+func (spec *Spec) Run(writer io.Writer) {
+ if spec.getState() == types.SpecStateFailed {
+ spec.previousFailures = true
+ }
+
+ spec.startTime = time.Now()
+ defer func() {
+ spec.runTime = time.Since(spec.startTime)
+ }()
+
+ for sample := 0; sample < spec.subject.Samples(); sample++ {
+ spec.runSample(sample, writer)
+
+ if spec.getState() != types.SpecStatePassed {
+ return
+ }
+ }
+}
+
+func (spec *Spec) getState() types.SpecState {
+ spec.stateMutex.Lock()
+ defer spec.stateMutex.Unlock()
+ return spec.state
+}
+
+func (spec *Spec) setState(state types.SpecState) {
+ spec.stateMutex.Lock()
+ defer spec.stateMutex.Unlock()
+ spec.state = state
+}
+
+func (spec *Spec) runSample(sample int, writer io.Writer) {
+ spec.setState(types.SpecStatePassed)
+ spec.failure = types.SpecFailure{}
+ innerMostContainerIndexToUnwind := -1
+
+ defer func() {
+ for i := innerMostContainerIndexToUnwind; i >= 0; i-- {
+ container := spec.containers[i]
+ for _, justAfterEach := range container.SetupNodesOfType(types.SpecComponentTypeJustAfterEach) {
+ spec.announceSetupNode(writer, "JustAfterEach", container, justAfterEach)
+ justAfterEachState, justAfterEachFailure := justAfterEach.Run()
+ if justAfterEachState != types.SpecStatePassed && spec.state == types.SpecStatePassed {
+ spec.state = justAfterEachState
+ spec.failure = justAfterEachFailure
+ }
+ }
+ }
+
+ for i := innerMostContainerIndexToUnwind; i >= 0; i-- {
+ container := spec.containers[i]
+ for _, afterEach := range container.SetupNodesOfType(types.SpecComponentTypeAfterEach) {
+ spec.announceSetupNode(writer, "AfterEach", container, afterEach)
+ afterEachState, afterEachFailure := afterEach.Run()
+ if afterEachState != types.SpecStatePassed && spec.getState() == types.SpecStatePassed {
+ spec.setState(afterEachState)
+ spec.failure = afterEachFailure
+ }
+ }
+ }
+ }()
+
+ for i, container := range spec.containers {
+ innerMostContainerIndexToUnwind = i
+ for _, beforeEach := range container.SetupNodesOfType(types.SpecComponentTypeBeforeEach) {
+ spec.announceSetupNode(writer, "BeforeEach", container, beforeEach)
+ s, f := beforeEach.Run()
+ spec.failure = f
+ spec.setState(s)
+ if spec.getState() != types.SpecStatePassed {
+ return
+ }
+ }
+ }
+
+ for _, container := range spec.containers {
+ for _, justBeforeEach := range container.SetupNodesOfType(types.SpecComponentTypeJustBeforeEach) {
+ spec.announceSetupNode(writer, "JustBeforeEach", container, justBeforeEach)
+ s, f := justBeforeEach.Run()
+ spec.failure = f
+ spec.setState(s)
+ if spec.getState() != types.SpecStatePassed {
+ return
+ }
+ }
+ }
+
+ spec.announceSubject(writer, spec.subject)
+ s, f := spec.subject.Run()
+ spec.failure = f
+ spec.setState(s)
+}
+
+func (spec *Spec) announceSetupNode(writer io.Writer, nodeType string, container *containernode.ContainerNode, setupNode leafnodes.BasicNode) {
+ if spec.announceProgress {
+ s := fmt.Sprintf("[%s] %s\n %s\n", nodeType, container.Text(), setupNode.CodeLocation().String())
+ writer.Write([]byte(s))
+ }
+}
+
+func (spec *Spec) announceSubject(writer io.Writer, subject leafnodes.SubjectNode) {
+ if spec.announceProgress {
+ nodeType := ""
+ switch subject.Type() {
+ case types.SpecComponentTypeIt:
+ nodeType = "It"
+ case types.SpecComponentTypeMeasure:
+ nodeType = "Measure"
+ }
+ s := fmt.Sprintf("[%s] %s\n %s\n", nodeType, subject.Text(), subject.CodeLocation().String())
+ writer.Write([]byte(s))
+ }
+}
+
+func (spec *Spec) measurementsReport() map[string]*types.SpecMeasurement {
+ if !spec.IsMeasurement() || spec.Failed() {
+ return map[string]*types.SpecMeasurement{}
+ }
+
+ return spec.subject.(*leafnodes.MeasureNode).MeasurementsReport()
+}
diff --git a/vendor/github.com/onsi/ginkgo/internal/spec/spec_suite_test.go b/vendor/github.com/onsi/ginkgo/internal/spec/spec_suite_test.go
new file mode 100644
index 000000000..8681a7206
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/internal/spec/spec_suite_test.go
@@ -0,0 +1,13 @@
+package spec_test
+
+import (
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "testing"
+)
+
+func TestSpec(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Spec Suite")
+}
diff --git a/vendor/github.com/onsi/ginkgo/internal/spec/spec_test.go b/vendor/github.com/onsi/ginkgo/internal/spec/spec_test.go
new file mode 100644
index 000000000..b4a2c9c79
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/internal/spec/spec_test.go
@@ -0,0 +1,739 @@
+package spec_test
+
+import (
+ "time"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ "github.com/onsi/gomega/gbytes"
+
+ . "github.com/onsi/ginkgo/internal/spec"
+
+ "github.com/onsi/ginkgo/internal/codelocation"
+ "github.com/onsi/ginkgo/internal/containernode"
+ Failer "github.com/onsi/ginkgo/internal/failer"
+ "github.com/onsi/ginkgo/internal/leafnodes"
+ "github.com/onsi/ginkgo/types"
+)
+
+var noneFlag = types.FlagTypeNone
+var focusedFlag = types.FlagTypeFocused
+var pendingFlag = types.FlagTypePending
+
+var _ = Describe("Spec", func() {
+ var (
+ failer *Failer.Failer
+ codeLocation types.CodeLocation
+ nodesThatRan []string
+ spec *Spec
+ buffer *gbytes.Buffer
+ )
+
+ newBody := func(text string, fail bool) func() {
+ return func() {
+ nodesThatRan = append(nodesThatRan, text)
+ if fail {
+ failer.Fail(text, codeLocation)
+ }
+ }
+ }
+
+ newIt := func(text string, flag types.FlagType, fail bool) *leafnodes.ItNode {
+ return leafnodes.NewItNode(text, newBody(text, fail), flag, codeLocation, 0, failer, 0)
+ }
+
+ newItWithBody := func(text string, body interface{}) *leafnodes.ItNode {
+ return leafnodes.NewItNode(text, body, noneFlag, codeLocation, 0, failer, 0)
+ }
+
+ newMeasure := func(text string, flag types.FlagType, fail bool, samples int) *leafnodes.MeasureNode {
+ return leafnodes.NewMeasureNode(text, func(Benchmarker) {
+ nodesThatRan = append(nodesThatRan, text)
+ if fail {
+ failer.Fail(text, codeLocation)
+ }
+ }, flag, codeLocation, samples, failer, 0)
+ }
+
+ newBef := func(text string, fail bool) leafnodes.BasicNode {
+ return leafnodes.NewBeforeEachNode(newBody(text, fail), codeLocation, 0, failer, 0)
+ }
+
+ newAft := func(text string, fail bool) leafnodes.BasicNode {
+ return leafnodes.NewAfterEachNode(newBody(text, fail), codeLocation, 0, failer, 0)
+ }
+
+ newJusBef := func(text string, fail bool) leafnodes.BasicNode {
+ return leafnodes.NewJustBeforeEachNode(newBody(text, fail), codeLocation, 0, failer, 0)
+ }
+
+ newJusAft := func(text string, fail bool) leafnodes.BasicNode {
+ return leafnodes.NewJustAfterEachNode(newBody(text, fail), codeLocation, 0, failer, 0)
+ }
+
+ newContainer := func(text string, flag types.FlagType, setupNodes ...leafnodes.BasicNode) *containernode.ContainerNode {
+ c := containernode.New(text, flag, codeLocation)
+ for _, node := range setupNodes {
+ c.PushSetupNode(node)
+ }
+ return c
+ }
+
+ containers := func(containers ...*containernode.ContainerNode) []*containernode.ContainerNode {
+ return containers
+ }
+
+ BeforeEach(func() {
+ buffer = gbytes.NewBuffer()
+ failer = Failer.New()
+ codeLocation = codelocation.New(0)
+ nodesThatRan = []string{}
+ })
+
+ Describe("marking specs focused and pending", func() {
+ It("should satisfy various caes", func() {
+ cases := []struct {
+ ContainerFlags []types.FlagType
+ SubjectFlag types.FlagType
+ Pending bool
+ Focused bool
+ }{
+ {[]types.FlagType{}, noneFlag, false, false},
+ {[]types.FlagType{}, focusedFlag, false, true},
+ {[]types.FlagType{}, pendingFlag, true, false},
+ {[]types.FlagType{noneFlag}, noneFlag, false, false},
+ {[]types.FlagType{focusedFlag}, noneFlag, false, true},
+ {[]types.FlagType{pendingFlag}, noneFlag, true, false},
+ {[]types.FlagType{noneFlag}, focusedFlag, false, true},
+ {[]types.FlagType{focusedFlag}, focusedFlag, false, true},
+ {[]types.FlagType{pendingFlag}, focusedFlag, true, true},
+ {[]types.FlagType{noneFlag}, pendingFlag, true, false},
+ {[]types.FlagType{focusedFlag}, pendingFlag, true, true},
+ {[]types.FlagType{pendingFlag}, pendingFlag, true, false},
+ {[]types.FlagType{focusedFlag, noneFlag}, noneFlag, false, true},
+ {[]types.FlagType{noneFlag, focusedFlag}, noneFlag, false, true},
+ {[]types.FlagType{pendingFlag, noneFlag}, noneFlag, true, false},
+ {[]types.FlagType{noneFlag, pendingFlag}, noneFlag, true, false},
+ {[]types.FlagType{focusedFlag, pendingFlag}, noneFlag, true, true},
+ }
+
+ for i, c := range cases {
+ subject := newIt("it node", c.SubjectFlag, false)
+ containers := []*containernode.ContainerNode{}
+ for _, flag := range c.ContainerFlags {
+ containers = append(containers, newContainer("container", flag))
+ }
+
+ spec := New(subject, containers, false)
+ Ω(spec.Pending()).Should(Equal(c.Pending), "Case %d: %#v", i, c)
+ Ω(spec.Focused()).Should(Equal(c.Focused), "Case %d: %#v", i, c)
+
+ if c.Pending {
+ Ω(spec.Summary("").State).Should(Equal(types.SpecStatePending))
+ }
+ }
+ })
+ })
+
+ Describe("Skip", func() {
+ It("should be skipped", func() {
+ spec := New(newIt("it node", noneFlag, false), containers(newContainer("container", noneFlag)), false)
+ Ω(spec.Skipped()).Should(BeFalse())
+ spec.Skip()
+ Ω(spec.Skipped()).Should(BeTrue())
+ Ω(spec.Summary("").State).Should(Equal(types.SpecStateSkipped))
+ })
+ })
+
+ Describe("IsMeasurement", func() {
+ It("should be true if the subject is a measurement node", func() {
+ spec := New(newIt("it node", noneFlag, false), containers(newContainer("container", noneFlag)), false)
+ Ω(spec.IsMeasurement()).Should(BeFalse())
+ Ω(spec.Summary("").IsMeasurement).Should(BeFalse())
+ Ω(spec.Summary("").NumberOfSamples).Should(Equal(1))
+
+ spec = New(newMeasure("measure node", noneFlag, false, 10), containers(newContainer("container", noneFlag)), false)
+ Ω(spec.IsMeasurement()).Should(BeTrue())
+ Ω(spec.Summary("").IsMeasurement).Should(BeTrue())
+ Ω(spec.Summary("").NumberOfSamples).Should(Equal(10))
+ })
+ })
+
+ Describe("Passed", func() {
+ It("should pass when the subject passed", func() {
+ spec := New(newIt("it node", noneFlag, false), containers(), false)
+ spec.Run(buffer)
+
+ Ω(spec.Passed()).Should(BeTrue())
+ Ω(spec.Failed()).Should(BeFalse())
+ Ω(spec.Summary("").State).Should(Equal(types.SpecStatePassed))
+ Ω(spec.Summary("").Failure).Should(BeZero())
+ })
+ })
+
+ Describe("Flaked", func() {
+ It("should work if Run is called twice and gets different results", func() {
+ i := 0
+ spec := New(newItWithBody("flaky it", func() {
+ i++
+ if i == 1 {
+ failer.Fail("oops", codeLocation)
+ }
+ }), containers(), false)
+ spec.Run(buffer)
+ Ω(spec.Passed()).Should(BeFalse())
+ Ω(spec.Failed()).Should(BeTrue())
+ Ω(spec.Flaked()).Should(BeFalse())
+ Ω(spec.Summary("").State).Should(Equal(types.SpecStateFailed))
+ Ω(spec.Summary("").Failure.Message).Should(Equal("oops"))
+ spec.Run(buffer)
+ Ω(spec.Passed()).Should(BeTrue())
+ Ω(spec.Failed()).Should(BeFalse())
+ Ω(spec.Flaked()).Should(BeTrue())
+ Ω(spec.Summary("").State).Should(Equal(types.SpecStatePassed))
+ })
+ })
+
+ Describe("Failed", func() {
+ It("should be failed if the failure was panic", func() {
+ spec := New(newItWithBody("panicky it", func() {
+ panic("bam")
+ }), containers(), false)
+ spec.Run(buffer)
+ Ω(spec.Passed()).Should(BeFalse())
+ Ω(spec.Failed()).Should(BeTrue())
+ Ω(spec.Summary("").State).Should(Equal(types.SpecStatePanicked))
+ Ω(spec.Summary("").Failure.Message).Should(Equal("Test Panicked"))
+ Ω(spec.Summary("").Failure.ForwardedPanic).Should(Equal("bam"))
+ })
+
+ It("should be failed if the failure was a timeout", func() {
+ spec := New(newItWithBody("sleepy it", func(done Done) {}), containers(), false)
+ spec.Run(buffer)
+ Ω(spec.Passed()).Should(BeFalse())
+ Ω(spec.Failed()).Should(BeTrue())
+ Ω(spec.Summary("").State).Should(Equal(types.SpecStateTimedOut))
+ Ω(spec.Summary("").Failure.Message).Should(Equal("Timed out"))
+ })
+
+ It("should be failed if the failure was... a failure", func() {
+ spec := New(newItWithBody("failing it", func() {
+ failer.Fail("bam", codeLocation)
+ }), containers(), false)
+ spec.Run(buffer)
+ Ω(spec.Passed()).Should(BeFalse())
+ Ω(spec.Failed()).Should(BeTrue())
+ Ω(spec.Summary("").State).Should(Equal(types.SpecStateFailed))
+ Ω(spec.Summary("").Failure.Message).Should(Equal("bam"))
+ })
+ })
+
+ Describe("Concatenated string", func() {
+ It("should concatenate the texts of the containers and the subject", func() {
+ spec := New(
+ newIt("it node", noneFlag, false),
+ containers(
+ newContainer("outer container", noneFlag),
+ newContainer("inner container", noneFlag),
+ ),
+ false,
+ )
+
+ Ω(spec.ConcatenatedString()).Should(Equal("outer container inner container it node"))
+ })
+ })
+
+ Describe("running it specs", func() {
+ Context("with just an it", func() {
+ Context("that succeeds", func() {
+ It("should run the it and report on its success", func() {
+ spec := New(newIt("it node", noneFlag, false), containers(), false)
+ spec.Run(buffer)
+ Ω(spec.Passed()).Should(BeTrue())
+ Ω(spec.Failed()).Should(BeFalse())
+ Ω(nodesThatRan).Should(Equal([]string{"it node"}))
+ })
+ })
+
+ Context("that fails", func() {
+ It("should run the it and report on its success", func() {
+ spec := New(newIt("it node", noneFlag, true), containers(), false)
+ spec.Run(buffer)
+ Ω(spec.Passed()).Should(BeFalse())
+ Ω(spec.Failed()).Should(BeTrue())
+ Ω(spec.Summary("").Failure.Message).Should(Equal("it node"))
+ Ω(nodesThatRan).Should(Equal([]string{"it node"}))
+ })
+ })
+ })
+
+ Context("with a full set of setup nodes", func() {
+ var failingNodes map[string]bool
+
+ BeforeEach(func() {
+ failingNodes = map[string]bool{}
+ })
+
+ JustBeforeEach(func() {
+ spec = New(
+ newIt("it node", noneFlag, failingNodes["it node"]),
+ containers(
+ newContainer("outer container", noneFlag,
+ newBef("outer bef A", failingNodes["outer bef A"]),
+ newBef("outer bef B", failingNodes["outer bef B"]),
+ newJusBef("outer jusbef A", failingNodes["outer jusbef A"]),
+ newJusBef("outer jusbef B", failingNodes["outer jusbef B"]),
+ newJusAft("outer jusaft A", failingNodes["outer jusaft A"]),
+ newJusAft("outer jusaft B", failingNodes["outer jusaft B"]),
+ newAft("outer aft A", failingNodes["outer aft A"]),
+ newAft("outer aft B", failingNodes["outer aft B"]),
+ ),
+ newContainer("inner container", noneFlag,
+ newBef("inner bef A", failingNodes["inner bef A"]),
+ newBef("inner bef B", failingNodes["inner bef B"]),
+ newJusBef("inner jusbef A", failingNodes["inner jusbef A"]),
+ newJusBef("inner jusbef B", failingNodes["inner jusbef B"]),
+ newJusAft("inner jusaft A", failingNodes["inner jusaft A"]),
+ newJusAft("inner jusaft B", failingNodes["inner jusaft B"]),
+ newAft("inner aft A", failingNodes["inner aft A"]),
+ newAft("inner aft B", failingNodes["inner aft B"]),
+ ),
+ ),
+ false,
+ )
+ spec.Run(buffer)
+ })
+
+ Context("that all pass", func() {
+ It("should walk through the nodes in the correct order", func() {
+ Ω(spec.Passed()).Should(BeTrue())
+ Ω(spec.Failed()).Should(BeFalse())
+ Ω(nodesThatRan).Should(Equal([]string{
+ "outer bef A",
+ "outer bef B",
+ "inner bef A",
+ "inner bef B",
+ "outer jusbef A",
+ "outer jusbef B",
+ "inner jusbef A",
+ "inner jusbef B",
+ "it node",
+ "inner jusaft A",
+ "inner jusaft B",
+ "outer jusaft A",
+ "outer jusaft B",
+ "inner aft A",
+ "inner aft B",
+ "outer aft A",
+ "outer aft B",
+ }))
+ })
+ })
+
+ Context("when the subject fails", func() {
+ BeforeEach(func() {
+ failingNodes["it node"] = true
+ })
+
+ It("should run the afters", func() {
+ Ω(spec.Passed()).Should(BeFalse())
+ Ω(spec.Failed()).Should(BeTrue())
+ Ω(nodesThatRan).Should(Equal([]string{
+ "outer bef A",
+ "outer bef B",
+ "inner bef A",
+ "inner bef B",
+ "outer jusbef A",
+ "outer jusbef B",
+ "inner jusbef A",
+ "inner jusbef B",
+ "it node",
+ "inner jusaft A",
+ "inner jusaft B",
+ "outer jusaft A",
+ "outer jusaft B",
+ "inner aft A",
+ "inner aft B",
+ "outer aft A",
+ "outer aft B",
+ }))
+ Ω(spec.Summary("").Failure.Message).Should(Equal("it node"))
+ })
+ })
+
+ Context("when an inner before fails", func() {
+ BeforeEach(func() {
+ failingNodes["inner bef A"] = true
+ })
+
+ It("should not run any other befores, but it should run the subsequent afters", func() {
+ Ω(spec.Passed()).Should(BeFalse())
+ Ω(spec.Failed()).Should(BeTrue())
+ Ω(nodesThatRan).Should(Equal([]string{
+ "outer bef A",
+ "outer bef B",
+ "inner bef A",
+ "inner jusaft A",
+ "inner jusaft B",
+ "outer jusaft A",
+ "outer jusaft B",
+ "inner aft A",
+ "inner aft B",
+ "outer aft A",
+ "outer aft B",
+ }))
+ Ω(spec.Summary("").Failure.Message).Should(Equal("inner bef A"))
+ })
+ })
+
+ Context("when an outer before fails", func() {
+ BeforeEach(func() {
+ failingNodes["outer bef B"] = true
+ })
+
+ It("should not run any other befores, but it should run the subsequent afters", func() {
+ Ω(spec.Passed()).Should(BeFalse())
+ Ω(spec.Failed()).Should(BeTrue())
+ Ω(nodesThatRan).Should(Equal([]string{
+ "outer bef A",
+ "outer bef B",
+ "outer jusaft A",
+ "outer jusaft B",
+ "outer aft A",
+ "outer aft B",
+ }))
+ Ω(spec.Summary("").Failure.Message).Should(Equal("outer bef B"))
+ })
+ })
+
+ Context("when an after fails", func() {
+ BeforeEach(func() {
+ failingNodes["inner aft B"] = true
+ })
+
+ It("should run all other afters, but mark the test as failed", func() {
+ Ω(spec.Passed()).Should(BeFalse())
+ Ω(spec.Failed()).Should(BeTrue())
+ Ω(nodesThatRan).Should(Equal([]string{
+ "outer bef A",
+ "outer bef B",
+ "inner bef A",
+ "inner bef B",
+ "outer jusbef A",
+ "outer jusbef B",
+ "inner jusbef A",
+ "inner jusbef B",
+ "it node",
+ "inner jusaft A",
+ "inner jusaft B",
+ "outer jusaft A",
+ "outer jusaft B",
+ "inner aft A",
+ "inner aft B",
+ "outer aft A",
+ "outer aft B",
+ }))
+ Ω(spec.Summary("").Failure.Message).Should(Equal("inner aft B"))
+ })
+ })
+
+ Context("when a just before each fails", func() {
+ BeforeEach(func() {
+ failingNodes["outer jusbef B"] = true
+ })
+
+ It("should run the afters, but not the subject", func() {
+ Ω(spec.Passed()).Should(BeFalse())
+ Ω(spec.Failed()).Should(BeTrue())
+ Ω(nodesThatRan).Should(Equal([]string{
+ "outer bef A",
+ "outer bef B",
+ "inner bef A",
+ "inner bef B",
+ "outer jusbef A",
+ "outer jusbef B",
+ "inner jusaft A",
+ "inner jusaft B",
+ "outer jusaft A",
+ "outer jusaft B",
+ "inner aft A",
+ "inner aft B",
+ "outer aft A",
+ "outer aft B",
+ }))
+ Ω(spec.Summary("").Failure.Message).Should(Equal("outer jusbef B"))
+ })
+ })
+
+ Context("when a just after each fails", func() {
+ BeforeEach(func() {
+ failingNodes["outer jusaft A"] = true
+ })
+
+ It("should run all other afters, but mark the test as failed", func() {
+ Ω(spec.Passed()).Should(BeFalse())
+ Ω(spec.Failed()).Should(BeTrue())
+ Ω(nodesThatRan).Should(Equal([]string{
+ "outer bef A",
+ "outer bef B",
+ "inner bef A",
+ "inner bef B",
+ "outer jusbef A",
+ "outer jusbef B",
+ "inner jusbef A",
+ "inner jusbef B",
+ "it node",
+ "inner jusaft A",
+ "inner jusaft B",
+ "outer jusaft A",
+ "outer jusaft B",
+ "inner aft A",
+ "inner aft B",
+ "outer aft A",
+ "outer aft B",
+ }))
+ Ω(spec.Summary("").Failure.Message).Should(Equal("outer jusaft A"))
+ })
+ })
+
+ Context("when an after fails after an earlier node has failed", func() {
+ BeforeEach(func() {
+ failingNodes["it node"] = true
+ failingNodes["inner aft B"] = true
+ })
+
+ It("should record the earlier failure", func() {
+ Ω(spec.Passed()).Should(BeFalse())
+ Ω(spec.Failed()).Should(BeTrue())
+ Ω(nodesThatRan).Should(Equal([]string{
+ "outer bef A",
+ "outer bef B",
+ "inner bef A",
+ "inner bef B",
+ "outer jusbef A",
+ "outer jusbef B",
+ "inner jusbef A",
+ "inner jusbef B",
+ "it node",
+ "inner jusaft A",
+ "inner jusaft B",
+ "outer jusaft A",
+ "outer jusaft B",
+ "inner aft A",
+ "inner aft B",
+ "outer aft A",
+ "outer aft B",
+ }))
+ Ω(spec.Summary("").Failure.Message).Should(Equal("it node"))
+ })
+ })
+ })
+ })
+
+ Describe("running measurement specs", func() {
+ Context("when the measurement succeeds", func() {
+ It("should run N samples", func() {
+ spec = New(
+ newMeasure("measure node", noneFlag, false, 3),
+ containers(
+ newContainer("container", noneFlag,
+ newBef("bef A", false),
+ newJusBef("jusbef A", false),
+ newJusAft("jusaft A", false),
+ newAft("aft A", false),
+ ),
+ ),
+ false,
+ )
+ spec.Run(buffer)
+
+ Ω(spec.Passed()).Should(BeTrue())
+ Ω(spec.Failed()).Should(BeFalse())
+ Ω(nodesThatRan).Should(Equal([]string{
+ "bef A",
+ "jusbef A",
+ "measure node",
+ "jusaft A",
+ "aft A",
+ "bef A",
+ "jusbef A",
+ "measure node",
+ "jusaft A",
+ "aft A",
+ "bef A",
+ "jusbef A",
+ "measure node",
+ "jusaft A",
+ "aft A",
+ }))
+ })
+ })
+
+ Context("when the measurement fails", func() {
+ It("should bail after the failure occurs", func() {
+ spec = New(
+ newMeasure("measure node", noneFlag, true, 3),
+ containers(
+ newContainer("container", noneFlag,
+ newBef("bef A", false),
+ newJusBef("jusbef A", false),
+ newJusAft("jusaft A", false),
+ newAft("aft A", false),
+ ),
+ ),
+ false,
+ )
+ spec.Run(buffer)
+
+ Ω(spec.Passed()).Should(BeFalse())
+ Ω(spec.Failed()).Should(BeTrue())
+ Ω(nodesThatRan).Should(Equal([]string{
+ "bef A",
+ "jusbef A",
+ "measure node",
+ "jusaft A",
+ "aft A",
+ }))
+ })
+ })
+ })
+
+ Describe("Summary", func() {
+ var (
+ subjectCodeLocation types.CodeLocation
+ outerContainerCodeLocation types.CodeLocation
+ innerContainerCodeLocation types.CodeLocation
+ summary *types.SpecSummary
+ )
+
+ BeforeEach(func() {
+ subjectCodeLocation = codelocation.New(0)
+ outerContainerCodeLocation = codelocation.New(0)
+ innerContainerCodeLocation = codelocation.New(0)
+
+ spec = New(
+ leafnodes.NewItNode("it node", func() {
+ time.Sleep(10 * time.Millisecond)
+ }, noneFlag, subjectCodeLocation, 0, failer, 0),
+ containers(
+ containernode.New("outer container", noneFlag, outerContainerCodeLocation),
+ containernode.New("inner container", noneFlag, innerContainerCodeLocation),
+ ),
+ false,
+ )
+
+ spec.Run(buffer)
+ Ω(spec.Passed()).Should(BeTrue())
+ summary = spec.Summary("suite id")
+ })
+
+ It("should have the suite id", func() {
+ Ω(summary.SuiteID).Should(Equal("suite id"))
+ })
+
+ It("should have the component texts and code locations", func() {
+ Ω(summary.ComponentTexts).Should(Equal([]string{"outer container", "inner container", "it node"}))
+ Ω(summary.ComponentCodeLocations).Should(Equal([]types.CodeLocation{outerContainerCodeLocation, innerContainerCodeLocation, subjectCodeLocation}))
+ })
+
+ It("should have a runtime", func() {
+ Ω(summary.RunTime).Should(BeNumerically(">=", 10*time.Millisecond))
+ })
+
+ It("should have a runtime which remains consistent after spec run", func() {
+ totalRunTime := summary.RunTime
+ Ω(totalRunTime).Should(BeNumerically(">=", 10*time.Millisecond))
+
+ Consistently(func() time.Duration { return spec.Summary("suite id").RunTime }).Should(Equal(totalRunTime))
+ })
+
+ It("should not be a measurement, or have a measurement summary", func() {
+ Ω(summary.IsMeasurement).Should(BeFalse())
+ Ω(summary.Measurements).Should(BeEmpty())
+ })
+ })
+
+ Describe("Summaries for measurements", func() {
+ var summary *types.SpecSummary
+
+ BeforeEach(func() {
+ spec = New(leafnodes.NewMeasureNode("measure node", func(b Benchmarker) {
+ b.RecordValue("a value", 7, "some info")
+ b.RecordValueWithPrecision("another value", 8, "ns", 5, "more info")
+ }, noneFlag, codeLocation, 4, failer, 0), containers(), false)
+ spec.Run(buffer)
+ Ω(spec.Passed()).Should(BeTrue())
+ summary = spec.Summary("suite id")
+ })
+
+ It("should include the number of samples", func() {
+ Ω(summary.NumberOfSamples).Should(Equal(4))
+ })
+
+ It("should be a measurement", func() {
+ Ω(summary.IsMeasurement).Should(BeTrue())
+ })
+
+ It("should have the measurements report", func() {
+ Ω(summary.Measurements).Should(HaveKey("a value"))
+ report := summary.Measurements["a value"]
+ Ω(report.Name).Should(Equal("a value"))
+ Ω(report.Info).Should(Equal("some info"))
+ Ω(report.Results).Should(Equal([]float64{7, 7, 7, 7}))
+
+ Ω(summary.Measurements).Should(HaveKey("another value"))
+ report = summary.Measurements["another value"]
+ Ω(report.Name).Should(Equal("another value"))
+ Ω(report.Info).Should(Equal("more info"))
+ Ω(report.Results).Should(Equal([]float64{8, 8, 8, 8}))
+ Ω(report.Units).Should(Equal("ns"))
+ Ω(report.Precision).Should(Equal(5))
+ })
+ })
+
+ Describe("When told to emit progress", func() {
+ It("should emit progress to the writer as it runs Befores, JustBefores, Afters, and Its", func() {
+ spec = New(
+ newIt("it node", noneFlag, false),
+ containers(
+ newContainer("outer container", noneFlag,
+ newBef("outer bef A", false),
+ newJusBef("outer jusbef A", false),
+ newJusAft("outer jusaft A", false),
+ newAft("outer aft A", false),
+ ),
+ newContainer("inner container", noneFlag,
+ newBef("inner bef A", false),
+ newJusBef("inner jusbef A", false),
+ newJusAft("inner jusaft A", false),
+ newAft("inner aft A", false),
+ ),
+ ),
+ true,
+ )
+ spec.Run(buffer)
+
+ Ω(buffer).Should(gbytes.Say(`\[BeforeEach\] outer container`))
+ Ω(buffer).Should(gbytes.Say(`\[BeforeEach\] inner container`))
+ Ω(buffer).Should(gbytes.Say(`\[JustBeforeEach\] outer container`))
+ Ω(buffer).Should(gbytes.Say(`\[JustBeforeEach\] inner container`))
+ Ω(buffer).Should(gbytes.Say(`\[It\] it node`))
+ Ω(buffer).Should(gbytes.Say(`\[JustAfterEach\] inner container`))
+ Ω(buffer).Should(gbytes.Say(`\[JustAfterEach\] outer container`))
+ Ω(buffer).Should(gbytes.Say(`\[AfterEach\] inner container`))
+ Ω(buffer).Should(gbytes.Say(`\[AfterEach\] outer container`))
+ })
+
+ It("should emit progress to the writer as it runs Befores, JustBefores, JustAfters, Afters, and Measures", func() {
+ spec = New(
+ newMeasure("measure node", noneFlag, false, 2),
+ containers(),
+ true,
+ )
+ spec.Run(buffer)
+
+ Ω(buffer).Should(gbytes.Say(`\[Measure\] measure node`))
+ Ω(buffer).Should(gbytes.Say(`\[Measure\] measure node`))
+ })
+ })
+})
diff --git a/vendor/github.com/onsi/ginkgo/internal/spec/specs.go b/vendor/github.com/onsi/ginkgo/internal/spec/specs.go
new file mode 100644
index 000000000..006185ab5
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/internal/spec/specs.go
@@ -0,0 +1,123 @@
+package spec
+
+import (
+ "math/rand"
+ "regexp"
+ "sort"
+)
+
+type Specs struct {
+ specs []*Spec
+ hasProgrammaticFocus bool
+ RegexScansFilePath bool
+}
+
+func NewSpecs(specs []*Spec) *Specs {
+ return &Specs{
+ specs: specs,
+ }
+}
+
+func (e *Specs) Specs() []*Spec {
+ return e.specs
+}
+
+func (e *Specs) HasProgrammaticFocus() bool {
+ return e.hasProgrammaticFocus
+}
+
+func (e *Specs) Shuffle(r *rand.Rand) {
+ sort.Sort(e)
+ permutation := r.Perm(len(e.specs))
+ shuffledSpecs := make([]*Spec, len(e.specs))
+ for i, j := range permutation {
+ shuffledSpecs[i] = e.specs[j]
+ }
+ e.specs = shuffledSpecs
+}
+
+func (e *Specs) ApplyFocus(description string, focusString string, skipString string) {
+ if focusString == "" && skipString == "" {
+ e.applyProgrammaticFocus()
+ } else {
+ e.applyRegExpFocusAndSkip(description, focusString, skipString)
+ }
+}
+
+func (e *Specs) applyProgrammaticFocus() {
+ e.hasProgrammaticFocus = false
+ for _, spec := range e.specs {
+ if spec.Focused() && !spec.Pending() {
+ e.hasProgrammaticFocus = true
+ break
+ }
+ }
+
+ if e.hasProgrammaticFocus {
+ for _, spec := range e.specs {
+ if !spec.Focused() {
+ spec.Skip()
+ }
+ }
+ }
+}
+
+// toMatch returns a byte[] to be used by regex matchers. When adding new behaviours to the matching function,
+// this is the place which we append to.
+func (e *Specs) toMatch(description string, spec *Spec) []byte {
+ if e.RegexScansFilePath {
+ return []byte(
+ description + " " +
+ spec.ConcatenatedString() + " " +
+ spec.subject.CodeLocation().FileName)
+ } else {
+ return []byte(
+ description + " " +
+ spec.ConcatenatedString())
+ }
+}
+
+func (e *Specs) applyRegExpFocusAndSkip(description string, focusString string, skipString string) {
+ for _, spec := range e.specs {
+ matchesFocus := true
+ matchesSkip := false
+
+ toMatch := e.toMatch(description, spec)
+
+ if focusString != "" {
+ focusFilter := regexp.MustCompile(focusString)
+ matchesFocus = focusFilter.Match([]byte(toMatch))
+ }
+
+ if skipString != "" {
+ skipFilter := regexp.MustCompile(skipString)
+ matchesSkip = skipFilter.Match([]byte(toMatch))
+ }
+
+ if !matchesFocus || matchesSkip {
+ spec.Skip()
+ }
+ }
+}
+
+func (e *Specs) SkipMeasurements() {
+ for _, spec := range e.specs {
+ if spec.IsMeasurement() {
+ spec.Skip()
+ }
+ }
+}
+
+//sort.Interface
+
+func (e *Specs) Len() int {
+ return len(e.specs)
+}
+
+func (e *Specs) Less(i, j int) bool {
+ return e.specs[i].ConcatenatedString() < e.specs[j].ConcatenatedString()
+}
+
+func (e *Specs) Swap(i, j int) {
+ e.specs[i], e.specs[j] = e.specs[j], e.specs[i]
+}
diff --git a/vendor/github.com/onsi/ginkgo/internal/spec/specs_test.go b/vendor/github.com/onsi/ginkgo/internal/spec/specs_test.go
new file mode 100644
index 000000000..066fbbb3a
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/internal/spec/specs_test.go
@@ -0,0 +1,287 @@
+package spec_test
+
+import (
+ "math/rand"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/ginkgo/internal/spec"
+ . "github.com/onsi/gomega"
+
+ "github.com/onsi/ginkgo/internal/codelocation"
+ "github.com/onsi/ginkgo/internal/containernode"
+ "github.com/onsi/ginkgo/internal/leafnodes"
+ "github.com/onsi/ginkgo/types"
+)
+
+var _ = Describe("Specs", func() {
+ var specs *Specs
+
+ newSpec := func(text string, flag types.FlagType) *Spec {
+ subject := leafnodes.NewItNode(text, func() {}, flag, codelocation.New(0), 0, nil, 0)
+ return New(subject, []*containernode.ContainerNode{}, false)
+ }
+
+ newMeasureSpec := func(text string, flag types.FlagType) *Spec {
+ subject := leafnodes.NewMeasureNode(text, func(Benchmarker) {}, flag, codelocation.New(0), 0, nil, 0)
+ return New(subject, []*containernode.ContainerNode{}, false)
+ }
+
+ newSpecs := func(args ...interface{}) *Specs {
+ specs := []*Spec{}
+ for index := 0; index < len(args)-1; index += 2 {
+ specs = append(specs, newSpec(args[index].(string), args[index+1].(types.FlagType)))
+ }
+ return NewSpecs(specs)
+ }
+
+ specTexts := func(specs *Specs) []string {
+ texts := []string{}
+ for _, spec := range specs.Specs() {
+ texts = append(texts, spec.ConcatenatedString())
+ }
+ return texts
+ }
+
+ willRunTexts := func(specs *Specs) []string {
+ texts := []string{}
+ for _, spec := range specs.Specs() {
+ if !(spec.Skipped() || spec.Pending()) {
+ texts = append(texts, spec.ConcatenatedString())
+ }
+ }
+ return texts
+ }
+
+ skippedTexts := func(specs *Specs) []string {
+ texts := []string{}
+ for _, spec := range specs.Specs() {
+ if spec.Skipped() {
+ texts = append(texts, spec.ConcatenatedString())
+ }
+ }
+ return texts
+ }
+
+ pendingTexts := func(specs *Specs) []string {
+ texts := []string{}
+ for _, spec := range specs.Specs() {
+ if spec.Pending() {
+ texts = append(texts, spec.ConcatenatedString())
+ }
+ }
+ return texts
+ }
+
+ Describe("Shuffling specs", func() {
+ It("should shuffle the specs using the passed in randomizer", func() {
+ specs17 := newSpecs("C", noneFlag, "A", noneFlag, "B", noneFlag)
+ specs17.Shuffle(rand.New(rand.NewSource(17)))
+ texts17 := specTexts(specs17)
+
+ specs17Again := newSpecs("C", noneFlag, "A", noneFlag, "B", noneFlag)
+ specs17Again.Shuffle(rand.New(rand.NewSource(17)))
+ texts17Again := specTexts(specs17Again)
+
+ specs15 := newSpecs("C", noneFlag, "A", noneFlag, "B", noneFlag)
+ specs15.Shuffle(rand.New(rand.NewSource(15)))
+ texts15 := specTexts(specs15)
+
+ specsUnshuffled := newSpecs("C", noneFlag, "A", noneFlag, "B", noneFlag)
+ textsUnshuffled := specTexts(specsUnshuffled)
+
+ Ω(textsUnshuffled).Should(Equal([]string{"C", "A", "B"}))
+
+ Ω(texts17).Should(Equal(texts17Again))
+ Ω(texts17).ShouldNot(Equal(texts15))
+ Ω(texts17).ShouldNot(Equal(textsUnshuffled))
+ Ω(texts15).ShouldNot(Equal(textsUnshuffled))
+
+ Ω(texts17).Should(HaveLen(3))
+ Ω(texts17).Should(ContainElement("A"))
+ Ω(texts17).Should(ContainElement("B"))
+ Ω(texts17).Should(ContainElement("C"))
+
+ Ω(texts15).Should(HaveLen(3))
+ Ω(texts15).Should(ContainElement("A"))
+ Ω(texts15).Should(ContainElement("B"))
+ Ω(texts15).Should(ContainElement("C"))
+ })
+ })
+
+ Describe("with no programmatic focus", func() {
+ BeforeEach(func() {
+ specs = newSpecs("A1", noneFlag, "A2", noneFlag, "B1", noneFlag, "B2", pendingFlag)
+ specs.ApplyFocus("", "", "")
+ })
+
+ It("should not report as having programmatic specs", func() {
+ Ω(specs.HasProgrammaticFocus()).Should(BeFalse())
+ })
+ })
+
+ Describe("Applying focus/skip", func() {
+ var description, focusString, skipString string
+
+ BeforeEach(func() {
+ description, focusString, skipString = "", "", ""
+ })
+
+ JustBeforeEach(func() {
+ specs = newSpecs("A1", focusedFlag, "A2", noneFlag, "B1", focusedFlag, "B2", pendingFlag)
+ specs.ApplyFocus(description, focusString, skipString)
+ })
+
+ Context("with neither a focus string nor a skip string", func() {
+ It("should apply the programmatic focus", func() {
+ Ω(willRunTexts(specs)).Should(Equal([]string{"A1", "B1"}))
+ Ω(skippedTexts(specs)).Should(Equal([]string{"A2", "B2"}))
+ Ω(pendingTexts(specs)).Should(BeEmpty())
+ })
+
+ It("should report as having programmatic specs", func() {
+ Ω(specs.HasProgrammaticFocus()).Should(BeTrue())
+ })
+ })
+
+ Context("with a focus regexp", func() {
+ BeforeEach(func() {
+ focusString = "A"
+ })
+
+ It("should override the programmatic focus", func() {
+ Ω(willRunTexts(specs)).Should(Equal([]string{"A1", "A2"}))
+ Ω(skippedTexts(specs)).Should(Equal([]string{"B1", "B2"}))
+ Ω(pendingTexts(specs)).Should(BeEmpty())
+ })
+
+ It("should not report as having programmatic specs", func() {
+ Ω(specs.HasProgrammaticFocus()).Should(BeFalse())
+ })
+ })
+
+ Context("with a focus regexp", func() {
+ BeforeEach(func() {
+ focusString = "B"
+ })
+
+ It("should not override any pendings", func() {
+ Ω(willRunTexts(specs)).Should(Equal([]string{"B1"}))
+ Ω(skippedTexts(specs)).Should(Equal([]string{"A1", "A2"}))
+ Ω(pendingTexts(specs)).Should(Equal([]string{"B2"}))
+ })
+ })
+
+ Context("with a description", func() {
+ BeforeEach(func() {
+ description = "C"
+ focusString = "C"
+ })
+
+ It("should include the description in the focus determination", func() {
+ Ω(willRunTexts(specs)).Should(Equal([]string{"A1", "A2", "B1"}))
+ Ω(skippedTexts(specs)).Should(BeEmpty())
+ Ω(pendingTexts(specs)).Should(Equal([]string{"B2"}))
+ })
+ })
+
+ Context("with a description", func() {
+ BeforeEach(func() {
+ description = "C"
+ skipString = "C"
+ })
+
+ It("should include the description in the focus determination", func() {
+ Ω(willRunTexts(specs)).Should(BeEmpty())
+ Ω(skippedTexts(specs)).Should(Equal([]string{"A1", "A2", "B1", "B2"}))
+ Ω(pendingTexts(specs)).Should(BeEmpty())
+ })
+ })
+
+ Context("with a skip regexp", func() {
+ BeforeEach(func() {
+ skipString = "A"
+ })
+
+ It("should override the programmatic focus", func() {
+ Ω(willRunTexts(specs)).Should(Equal([]string{"B1"}))
+ Ω(skippedTexts(specs)).Should(Equal([]string{"A1", "A2"}))
+ Ω(pendingTexts(specs)).Should(Equal([]string{"B2"}))
+ })
+
+ It("should not report as having programmatic specs", func() {
+ Ω(specs.HasProgrammaticFocus()).Should(BeFalse())
+ })
+ })
+
+ Context("with both a focus and a skip regexp", func() {
+ BeforeEach(func() {
+ focusString = "1"
+ skipString = "B"
+ })
+
+ It("should AND the two", func() {
+ Ω(willRunTexts(specs)).Should(Equal([]string{"A1"}))
+ Ω(skippedTexts(specs)).Should(Equal([]string{"A2", "B1", "B2"}))
+ Ω(pendingTexts(specs)).Should(BeEmpty())
+ })
+
+ It("should not report as having programmatic specs", func() {
+ Ω(specs.HasProgrammaticFocus()).Should(BeFalse())
+ })
+ })
+ })
+
+ Describe("With a focused spec within a pending context and a pending spec within a focused context", func() {
+ BeforeEach(func() {
+ pendingInFocused := New(
+ leafnodes.NewItNode("PendingInFocused", func() {}, pendingFlag, codelocation.New(0), 0, nil, 0),
+ []*containernode.ContainerNode{
+ containernode.New("", focusedFlag, codelocation.New(0)),
+ }, false)
+
+ focusedInPending := New(
+ leafnodes.NewItNode("FocusedInPending", func() {}, focusedFlag, codelocation.New(0), 0, nil, 0),
+ []*containernode.ContainerNode{
+ containernode.New("", pendingFlag, codelocation.New(0)),
+ }, false)
+
+ specs = NewSpecs([]*Spec{
+ newSpec("A", noneFlag),
+ newSpec("B", noneFlag),
+ pendingInFocused,
+ focusedInPending,
+ })
+ specs.ApplyFocus("", "", "")
+ })
+
+ It("should not have a programmatic focus and should run all tests", func() {
+ Ω(willRunTexts(specs)).Should(Equal([]string{"A", "B"}))
+ Ω(skippedTexts(specs)).Should(BeEmpty())
+ Ω(pendingTexts(specs)).Should(ConsistOf(ContainSubstring("PendingInFocused"), ContainSubstring("FocusedInPending")))
+ })
+ })
+
+ Describe("skipping measurements", func() {
+ BeforeEach(func() {
+ specs = NewSpecs([]*Spec{
+ newSpec("A", noneFlag),
+ newSpec("B", noneFlag),
+ newSpec("C", pendingFlag),
+ newMeasureSpec("measurementA", noneFlag),
+ newMeasureSpec("measurementB", pendingFlag),
+ })
+ })
+
+ It("should skip measurements", func() {
+ Ω(willRunTexts(specs)).Should(Equal([]string{"A", "B", "measurementA"}))
+ Ω(skippedTexts(specs)).Should(BeEmpty())
+ Ω(pendingTexts(specs)).Should(Equal([]string{"C", "measurementB"}))
+
+ specs.SkipMeasurements()
+
+ Ω(willRunTexts(specs)).Should(Equal([]string{"A", "B"}))
+ Ω(skippedTexts(specs)).Should(Equal([]string{"measurementA", "measurementB"}))
+ Ω(pendingTexts(specs)).Should(Equal([]string{"C"}))
+ })
+ })
+})