func AsynchronousSharedRunnerBehaviors(build func(body interface{}, timeout time.Duration, failer *Failer.Failer, componentCodeLocation types.CodeLocation) runnable, componentType types.SpecComponentType, componentIndex int) { var ( outcome types.SpecState failure types.SpecFailure failer *Failer.Failer componentCodeLocation types.CodeLocation innerCodeLocation types.CodeLocation didRun bool ) BeforeEach(func() { failer = Failer.New() componentCodeLocation = codelocation.New(0) innerCodeLocation = codelocation.New(0) didRun = false }) Describe("asynchronous functions", func() { var timeoutDuration time.Duration BeforeEach(func() { timeoutDuration = time.Duration(1 * float64(time.Second)) }) Context("when running", func() { It("should run the function as a goroutine, and block until it's done", func() { initialNumberOfGoRoutines := runtime.NumGoroutine() numberOfGoRoutines := 0 build(func(done Done) { didRun = true numberOfGoRoutines = runtime.NumGoroutine() close(done) }, timeoutDuration, failer, componentCodeLocation).Run() Ω(didRun).Should(BeTrue()) Ω(numberOfGoRoutines).Should(BeNumerically(">=", initialNumberOfGoRoutines+1)) }) }) Context("when the function passes", func() { BeforeEach(func() { outcome, failure = build(func(done Done) { didRun = true close(done) }, timeoutDuration, failer, componentCodeLocation).Run() }) It("should have a succesful outcome", func() { Ω(didRun).Should(BeTrue()) Ω(outcome).Should(Equal(types.SpecStatePassed)) Ω(failure).Should(BeZero()) }) }) Context("when the function fails", func() { BeforeEach(func() { outcome, failure = build(func(done Done) { didRun = true failer.Fail("bam", innerCodeLocation) time.Sleep(20 * time.Millisecond) panic("doesn't matter") close(done) }, 10*time.Millisecond, failer, componentCodeLocation).Run() }) It("should return the failure", func() { Ω(didRun).Should(BeTrue()) Ω(outcome).Should(Equal(types.SpecStateFailed)) Ω(failure).Should(Equal(types.SpecFailure{ Message: "bam", Location: innerCodeLocation, ForwardedPanic: nil, ComponentIndex: componentIndex, ComponentType: componentType, ComponentCodeLocation: componentCodeLocation, })) }) }) Context("when the function times out", func() { var guard chan struct{} BeforeEach(func() { guard = make(chan struct{}) outcome, failure = build(func(done Done) { didRun = true time.Sleep(20 * time.Millisecond) close(guard) panic("doesn't matter") close(done) }, 10*time.Millisecond, failer, componentCodeLocation).Run() }) It("should return the timeout", func() { <-guard Ω(didRun).Should(BeTrue()) Ω(outcome).Should(Equal(types.SpecStateTimedOut)) Ω(failure).Should(Equal(types.SpecFailure{ Message: "Timed out", Location: componentCodeLocation, ForwardedPanic: nil, ComponentIndex: componentIndex, ComponentType: componentType, ComponentCodeLocation: componentCodeLocation, })) }) }) Context("when the function panics", func() { BeforeEach(func() { outcome, failure = build(func(done Done) { didRun = true innerCodeLocation = codelocation.New(0) panic("ack!") }, 100*time.Millisecond, failer, componentCodeLocation).Run() }) It("should return the panic", func() { Ω(didRun).Should(BeTrue()) Ω(outcome).Should(Equal(types.SpecStatePanicked)) innerCodeLocation.LineNumber++ Ω(failure).Should(Equal(types.SpecFailure{ Message: "Test Panicked", Location: innerCodeLocation, ForwardedPanic: "ack!", ComponentIndex: componentIndex, ComponentType: componentType, ComponentCodeLocation: componentCodeLocation, })) }) }) }) }
func SynchronousSharedRunnerBehaviors(build func(body interface{}, timeout time.Duration, failer *Failer.Failer, componentCodeLocation types.CodeLocation) runnable, componentType types.SpecComponentType, componentIndex int) { var ( outcome types.SpecState failure types.SpecFailure failer *Failer.Failer componentCodeLocation types.CodeLocation innerCodeLocation types.CodeLocation didRun bool ) BeforeEach(func() { failer = Failer.New() componentCodeLocation = codelocation.New(0) innerCodeLocation = codelocation.New(0) didRun = false }) Describe("synchronous functions", func() { Context("when the function passes", func() { BeforeEach(func() { outcome, failure = build(func() { didRun = true }, 0, failer, componentCodeLocation).Run() }) It("should have a succesful outcome", func() { Ω(didRun).Should(BeTrue()) Ω(outcome).Should(Equal(types.SpecStatePassed)) Ω(failure).Should(BeZero()) }) }) Context("when a failure occurs", func() { BeforeEach(func() { outcome, failure = build(func() { didRun = true failer.Fail("bam", innerCodeLocation) panic("should not matter") }, 0, failer, componentCodeLocation).Run() }) It("should return the failure", func() { Ω(didRun).Should(BeTrue()) Ω(outcome).Should(Equal(types.SpecStateFailed)) Ω(failure).Should(Equal(types.SpecFailure{ Message: "bam", Location: innerCodeLocation, ForwardedPanic: nil, ComponentIndex: componentIndex, ComponentType: componentType, ComponentCodeLocation: componentCodeLocation, })) }) }) Context("when a panic occurs", func() { BeforeEach(func() { outcome, failure = build(func() { didRun = true innerCodeLocation = codelocation.New(0) panic("ack!") }, 0, failer, componentCodeLocation).Run() }) It("should return the panic", func() { Ω(didRun).Should(BeTrue()) Ω(outcome).Should(Equal(types.SpecStatePanicked)) innerCodeLocation.LineNumber++ Ω(failure).Should(Equal(types.SpecFailure{ Message: "Test Panicked", Location: innerCodeLocation, ForwardedPanic: "ack!", ComponentIndex: componentIndex, ComponentType: componentType, ComponentCodeLocation: componentCodeLocation, })) }) }) }) }
reporter1 *reporters.FakeReporter reporter2 *reporters.FakeReporter failer *Failer.Failer writer *Writer.FakeGinkgoWriter thingsThatRan []string runner *SpecRunner ) newBefSuite := func(text string, fail bool) leafnodes.SuiteNode { return leafnodes.NewBeforeSuiteNode(func() { writer.AddEvent(text) thingsThatRan = append(thingsThatRan, text) if fail { failer.Fail(text, codelocation.New(0)) } }, codelocation.New(0), 0, failer) } newAftSuite := func(text string, fail bool) leafnodes.SuiteNode { return leafnodes.NewAfterSuiteNode(func() { writer.AddEvent(text) thingsThatRan = append(thingsThatRan, text) if fail { failer.Fail(text, codelocation.New(0)) } }, codelocation.New(0), 0, failer) } newSpec := func(text string, flag types.FlagType, fail bool) *spec.Spec {
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)
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)) })
It("should run A, then B", func() { Ω(thingsThatRan()).Should(Equal([]string{"A", "B"})) }) It("should report success", func() { Ω(outcome).Should(BeTrue()) Ω(node.Passed()).Should(BeTrue()) Ω(node.Summary().State).Should(Equal(types.SpecStatePassed)) }) }) Context("when A fails", func() { BeforeEach(func() { node = newNode(func() { ranThing("A") failer.Fail("bam", innerCodeLocation) }, func() { ranThing("B") }) outcome = node.Run(1, 1, server.URL()) }) It("should still run B", func() { Ω(thingsThatRan()).Should(Equal([]string{"A", "B"})) }) It("should report failure", func() { Ω(outcome).Should(BeFalse()) Ω(node.Passed()).Should(BeFalse()) Ω(node.Summary().State).Should(Equal(types.SpecStateFailed))
}) It("should have the correct summary", func() { summary := befSuite.Summary() Ω(summary.ComponentType).Should(Equal(types.SpecComponentTypeBeforeSuite)) Ω(summary.CodeLocation).Should(Equal(codeLocation)) Ω(summary.State).Should(Equal(types.SpecStatePassed)) Ω(summary.RunTime).Should(BeNumerically(">=", 10*time.Millisecond)) Ω(summary.Failure).Should(BeZero()) }) }) Context("when the body fails", func() { BeforeEach(func() { befSuite = NewBeforeSuiteNode(func() { failer.Fail("oops", innerCodeLocation) }, codeLocation, 0, failer) outcome = befSuite.Run(0, 0, "") }) It("should return false when run and report as failed", func() { Ω(outcome).Should(BeFalse()) Ω(befSuite.Passed()).Should(BeFalse()) }) It("should have the correct summary", func() { summary := befSuite.Summary() Ω(summary.State).Should(Equal(types.SpecStateFailed)) Ω(summary.Failure.Message).Should(Equal("oops")) Ω(summary.Failure.Location).Should(Equal(innerCodeLocation)) Ω(summary.Failure.ForwardedPanic).Should(BeNil())