func init() {
	Describe("Example Collection", func() {
		var (
			fakeT *fakeTestingT
			fakeR *reporters.FakeReporter

			examplesThatWereRun []string

			collection *exampleCollection
			writer     *fakeGinkgoWriter
		)

		exampleWithItFunc := func(itText string, flag flagType, fail bool) *example {
			return newExample(newItNode(itText, func() {
				examplesThatWereRun = append(examplesThatWereRun, itText)
				time.Sleep(time.Duration(0.001 * float64(time.Second)))
				if fail {
					collection.fail(failureData{
						message: itText + " Failed",
					})
				}
			}, flag, types.GenerateCodeLocation(0), 0))
		}

		BeforeEach(func() {
			writer = &fakeGinkgoWriter{}
			fakeT = &fakeTestingT{}
			fakeR = reporters.NewFakeReporter()
			examplesThatWereRun = make([]string, 0)
		})

		Describe("enumerating and assigning example indices", func() {
			var examples []*example
			BeforeEach(func() {
				examples = []*example{
					exampleWithItFunc("C", flagTypeNone, false),
					exampleWithItFunc("A", flagTypeNone, false),
					exampleWithItFunc("B", flagTypeNone, false),
				}
				collection = newExampleCollection(fakeT, "collection description", examples, []Reporter{fakeR}, writer, config.GinkgoConfigType{})
			})

			It("should enumerate and assign example indices", func() {
				Ω(examples[0].summary("suite-id").ExampleIndex).Should(Equal(0))
				Ω(examples[1].summary("suite-id").ExampleIndex).Should(Equal(1))
				Ω(examples[2].summary("suite-id").ExampleIndex).Should(Equal(2))
			})
		})

		Describe("shuffling the collection", func() {
			BeforeEach(func() {
				collection = newExampleCollection(fakeT, "collection description", []*example{
					exampleWithItFunc("C", flagTypeNone, false),
					exampleWithItFunc("A", flagTypeNone, false),
					exampleWithItFunc("B", flagTypeNone, false),
				}, []Reporter{fakeR}, writer, config.GinkgoConfigType{})
			})

			It("should be sortable", func() {
				sort.Sort(collection)
				collection.run()
				Ω(examplesThatWereRun).Should(Equal([]string{"A", "B", "C"}))
			})

			It("shuffles all the examples after sorting them", func() {
				collection.shuffle(rand.New(rand.NewSource(17)))
				collection.run()
				Ω(examplesThatWereRun).Should(Equal(shuffleStrings([]string{"A", "B", "C"}, 17)), "The permutation should be the same across test runs")
			})
		})

		Describe("reporting to multiple reporter", func() {
			var otherFakeR *reporters.FakeReporter
			BeforeEach(func() {
				otherFakeR = reporters.NewFakeReporter()

				collection = newExampleCollection(fakeT, "collection description", []*example{
					exampleWithItFunc("C", flagTypeNone, false),
					exampleWithItFunc("A", flagTypeNone, false),
					exampleWithItFunc("B", flagTypeNone, false),
				}, []Reporter{fakeR, otherFakeR}, writer, config.GinkgoConfigType{})
				collection.run()
			})

			It("reports to both reporters", func() {
				Ω(otherFakeR.BeginSummary).Should(Equal(fakeR.BeginSummary))
				Ω(otherFakeR.EndSummary).Should(Equal(fakeR.EndSummary))
				Ω(otherFakeR.ExampleSummaries).Should(Equal(fakeR.ExampleSummaries))
			})
		})

		Describe("logging GinkgoWriter output", func() {
			Context("when a test fails", func() {
				BeforeEach(func() {
					collection = newExampleCollection(fakeT, "collection description", []*example{
						exampleWithItFunc("C", flagTypeNone, true),
					}, []Reporter{fakeR}, writer, config.GinkgoConfigType{})
					collection.run()
				})

				It("should truncate and write to stdout", func() {
					Ω(writer.didTruncate).Should(BeTrue())
					Ω(writer.didDump).Should(BeTrue())
				})
			})

			Context("when a test passes", func() {
				BeforeEach(func() {
					collection = newExampleCollection(fakeT, "collection description", []*example{
						exampleWithItFunc("C", flagTypeNone, false),
					}, []Reporter{fakeR}, writer, config.GinkgoConfigType{})
					collection.run()
				})

				It("should truncate but not write to stdout", func() {
					Ω(writer.didTruncate).Should(BeTrue())
					Ω(writer.didDump).Should(BeFalse())
				})
			})
		})

		Describe("running an example collection", func() {
			var (
				example1  *example
				example2  *example
				example3  *example
				conf      config.GinkgoConfigType
				runResult bool
			)

			BeforeEach(func() {
				conf = config.GinkgoConfigType{FocusString: "", ParallelTotal: 1, ParallelNode: 1}

				example1 = exampleWithItFunc("it 1", flagTypeNone, false)
				example2 = exampleWithItFunc("it 2", flagTypeNone, false)
				example3 = exampleWithItFunc("it 3", flagTypeNone, false)
			})

			JustBeforeEach(func() {
				collection = newExampleCollection(fakeT, "collection description", []*example{example1, example2, example3}, []Reporter{fakeR}, writer, conf)
				runResult = collection.run()
			})

			Context("when all the examples pass", func() {
				It("should return true", func() {
					Ω(runResult).Should(BeTrue())
				})

				It("runs all the tests", func() {
					Ω(examplesThatWereRun).Should(Equal([]string{"it 1", "it 2", "it 3"}))
				})

				It("marks the suite as passed", func() {
					Ω(fakeT.didFail).Should(BeFalse())
				})

				It("publishes the correct starting suite summary", func() {
					summary := fakeR.BeginSummary
					Ω(summary.SuiteDescription).Should(Equal("collection description"))
					Ω(summary.SuiteSucceeded).Should(BeTrue())
					Ω(summary.NumberOfExamplesBeforeParallelization).Should(Equal(3))
					Ω(summary.NumberOfTotalExamples).Should(Equal(3))
					Ω(summary.NumberOfExamplesThatWillBeRun).Should(Equal(3))
					Ω(summary.NumberOfPendingExamples).Should(Equal(0))
					Ω(summary.NumberOfSkippedExamples).Should(Equal(0))
					Ω(summary.NumberOfPassedExamples).Should(Equal(0))
					Ω(summary.NumberOfFailedExamples).Should(Equal(0))
					Ω(summary.RunTime).Should(Equal(time.Duration(0)))
				})

				It("publishes the correct example summaries", func() {
					Ω(fakeR.ExampleWillRunSummaries).Should(HaveLen(3))
					Ω(fakeR.ExampleSummaries).Should(HaveLen(3))
					Ω(fakeR.ExampleSummaries[0]).Should(Equal(example1.summary(fakeR.BeginSummary.SuiteID)))
					Ω(fakeR.ExampleSummaries[1]).Should(Equal(example2.summary(fakeR.BeginSummary.SuiteID)))
					Ω(fakeR.ExampleSummaries[2]).Should(Equal(example3.summary(fakeR.BeginSummary.SuiteID)))
				})

				It("publishes the correct ending suite summary", func() {
					summary := fakeR.EndSummary
					Ω(summary.SuiteDescription).Should(Equal("collection description"))
					Ω(summary.SuiteSucceeded).Should(BeTrue())
					Ω(summary.NumberOfExamplesBeforeParallelization).Should(Equal(3))
					Ω(summary.NumberOfTotalExamples).Should(Equal(3))
					Ω(summary.NumberOfExamplesThatWillBeRun).Should(Equal(3))
					Ω(summary.NumberOfPendingExamples).Should(Equal(0))
					Ω(summary.NumberOfSkippedExamples).Should(Equal(0))
					Ω(summary.NumberOfPassedExamples).Should(Equal(3))
					Ω(summary.NumberOfFailedExamples).Should(Equal(0))
					Ω(summary.RunTime.Seconds()).Should(BeNumerically("~", 3*0.001, 0.01))
				})

				It("should publish a consistent suite ID across all summaries", func() {
					suiteId := fakeR.BeginSummary.SuiteID
					Ω(suiteId).ShouldNot(BeEmpty())
					Ω(fakeR.EndSummary.SuiteID).Should(Equal(suiteId))
					for _, exampleSummary := range fakeR.ExampleSummaries {
						Ω(exampleSummary.SuiteID).Should(Equal(suiteId))
					}
				})
			})

			Context("when examples fail", func() {
				BeforeEach(func() {
					example2 = exampleWithItFunc("failing it 2", flagTypeNone, true)
					example3 = exampleWithItFunc("failing it 3", flagTypeNone, true)
				})

				It("should return false", func() {
					Ω(runResult).Should(BeFalse())
				})

				It("runs all the tests", func() {
					Ω(examplesThatWereRun).Should(Equal([]string{"it 1", "failing it 2", "failing it 3"}))
				})

				It("marks the suite as failed", func() {
					Ω(fakeT.didFail).Should(BeTrue())
				})

				It("publishes the correct starting suite summary", func() {
					summary := fakeR.BeginSummary
					Ω(summary.SuiteDescription).Should(Equal("collection description"))
					Ω(summary.SuiteSucceeded).Should(BeTrue())
					Ω(summary.NumberOfExamplesBeforeParallelization).Should(Equal(3))
					Ω(summary.NumberOfTotalExamples).Should(Equal(3))
					Ω(summary.NumberOfExamplesThatWillBeRun).Should(Equal(3))
					Ω(summary.NumberOfPendingExamples).Should(Equal(0))
					Ω(summary.NumberOfSkippedExamples).Should(Equal(0))
					Ω(summary.NumberOfPassedExamples).Should(Equal(0))
					Ω(summary.NumberOfFailedExamples).Should(Equal(0))
					Ω(summary.RunTime).Should(Equal(time.Duration(0)))
				})

				It("publishes the correct example summaries", func() {
					Ω(fakeR.ExampleSummaries).Should(HaveLen(3))
					Ω(fakeR.ExampleSummaries[0]).Should(Equal(example1.summary(fakeR.BeginSummary.SuiteID)))
					Ω(fakeR.ExampleSummaries[1]).Should(Equal(example2.summary(fakeR.BeginSummary.SuiteID)))
					Ω(fakeR.ExampleSummaries[2]).Should(Equal(example3.summary(fakeR.BeginSummary.SuiteID)))
				})

				It("publishes the correct ending suite summary", func() {
					summary := fakeR.EndSummary
					Ω(summary.SuiteDescription).Should(Equal("collection description"))
					Ω(summary.SuiteSucceeded).Should(BeFalse())
					Ω(summary.NumberOfExamplesBeforeParallelization).Should(Equal(3))
					Ω(summary.NumberOfTotalExamples).Should(Equal(3))
					Ω(summary.NumberOfExamplesThatWillBeRun).Should(Equal(3))
					Ω(summary.NumberOfPendingExamples).Should(Equal(0))
					Ω(summary.NumberOfSkippedExamples).Should(Equal(0))
					Ω(summary.NumberOfPassedExamples).Should(Equal(1))
					Ω(summary.NumberOfFailedExamples).Should(Equal(2))
					Ω(summary.RunTime.Seconds()).Should(BeNumerically("~", 3*0.001, 0.01))
				})
			})

			Context("when examples are pending", func() {
				BeforeEach(func() {
					example1 = exampleWithItFunc("pending it 1", flagTypePending, false)
				})

				It("skips the pending examples", func() {
					Ω(examplesThatWereRun).Should(Equal([]string{"it 2", "it 3"}))
				})

				It("marks the suite as passed", func() {
					Ω(fakeT.didFail).Should(BeFalse())
				})

				It("publishes the correct starting suite summary", func() {
					summary := fakeR.BeginSummary
					Ω(summary.SuiteDescription).Should(Equal("collection description"))
					Ω(summary.SuiteSucceeded).Should(BeTrue())
					Ω(summary.NumberOfExamplesBeforeParallelization).Should(Equal(3))
					Ω(summary.NumberOfTotalExamples).Should(Equal(3))
					Ω(summary.NumberOfExamplesThatWillBeRun).Should(Equal(2))
					Ω(summary.NumberOfPendingExamples).Should(Equal(1))
					Ω(summary.NumberOfSkippedExamples).Should(Equal(0))
					Ω(summary.NumberOfPassedExamples).Should(Equal(0))
					Ω(summary.NumberOfFailedExamples).Should(Equal(0))
					Ω(summary.RunTime).Should(Equal(time.Duration(0)))
				})

				It("publishes the correct example summaries", func() {
					Ω(fakeR.ExampleSummaries).Should(HaveLen(3))
					Ω(fakeR.ExampleSummaries[0]).Should(Equal(example1.summary(fakeR.BeginSummary.SuiteID)))
					Ω(fakeR.ExampleSummaries[1]).Should(Equal(example2.summary(fakeR.BeginSummary.SuiteID)))
					Ω(fakeR.ExampleSummaries[2]).Should(Equal(example3.summary(fakeR.BeginSummary.SuiteID)))
				})

				It("publishes the correct ending suite summary", func() {
					summary := fakeR.EndSummary
					Ω(summary.SuiteDescription).Should(Equal("collection description"))
					Ω(summary.SuiteSucceeded).Should(BeTrue())
					Ω(summary.NumberOfExamplesBeforeParallelization).Should(Equal(3))
					Ω(summary.NumberOfTotalExamples).Should(Equal(3))
					Ω(summary.NumberOfExamplesThatWillBeRun).Should(Equal(2))
					Ω(summary.NumberOfPendingExamples).Should(Equal(1))
					Ω(summary.NumberOfSkippedExamples).Should(Equal(0))
					Ω(summary.NumberOfPassedExamples).Should(Equal(2))
					Ω(summary.NumberOfFailedExamples).Should(Equal(0))
					Ω(summary.RunTime.Seconds()).Should(BeNumerically("~", 3*0.001, 0.01))
				})

				Context("and --failOnPending is set", func() {
					BeforeEach(func() {
						conf.FailOnPending = true
					})

					It("should mark the suite as failed", func() {
						Ω(fakeT.didFail).Should(BeTrue())
						summary := fakeR.EndSummary
						Ω(summary.SuiteSucceeded).Should(BeFalse())
					})
				})
			})

			Context("when examples are focused", func() {
				BeforeEach(func() {
					example1 = exampleWithItFunc("focused it 1", flagTypeFocused, false)
					example3 = exampleWithItFunc("focused it 3", flagTypeFocused, false)
				})

				It("skips the non-focused examples", func() {
					Ω(examplesThatWereRun).Should(Equal([]string{"focused it 1", "focused it 3"}))
				})

				It("marks the suite as passed", func() {
					Ω(fakeT.didFail).Should(BeFalse())
				})

				It("publishes the correct starting suite summary", func() {
					summary := fakeR.BeginSummary
					Ω(summary.SuiteDescription).Should(Equal("collection description"))
					Ω(summary.SuiteSucceeded).Should(BeTrue())
					Ω(summary.NumberOfExamplesBeforeParallelization).Should(Equal(3))
					Ω(summary.NumberOfTotalExamples).Should(Equal(3))
					Ω(summary.NumberOfExamplesThatWillBeRun).Should(Equal(2))
					Ω(summary.NumberOfPendingExamples).Should(Equal(0))
					Ω(summary.NumberOfSkippedExamples).Should(Equal(1))
					Ω(summary.NumberOfPassedExamples).Should(Equal(0))
					Ω(summary.NumberOfFailedExamples).Should(Equal(0))
					Ω(summary.RunTime).Should(Equal(time.Duration(0)))
				})

				It("publishes the correct example summaries", func() {
					Ω(fakeR.ExampleSummaries).Should(HaveLen(3))
					Ω(fakeR.ExampleSummaries[0]).Should(Equal(example1.summary(fakeR.BeginSummary.SuiteID)))
					Ω(fakeR.ExampleSummaries[1]).Should(Equal(example2.summary(fakeR.BeginSummary.SuiteID)))
					Ω(fakeR.ExampleSummaries[2]).Should(Equal(example3.summary(fakeR.BeginSummary.SuiteID)))
				})

				It("publishes the correct ending suite summary", func() {
					summary := fakeR.EndSummary
					Ω(summary.SuiteDescription).Should(Equal("collection description"))
					Ω(summary.SuiteSucceeded).Should(BeTrue())
					Ω(summary.NumberOfExamplesBeforeParallelization).Should(Equal(3))
					Ω(summary.NumberOfTotalExamples).Should(Equal(3))
					Ω(summary.NumberOfExamplesThatWillBeRun).Should(Equal(2))
					Ω(summary.NumberOfPendingExamples).Should(Equal(0))
					Ω(summary.NumberOfSkippedExamples).Should(Equal(1))
					Ω(summary.NumberOfPassedExamples).Should(Equal(2))
					Ω(summary.NumberOfFailedExamples).Should(Equal(0))
					Ω(summary.RunTime.Seconds()).Should(BeNumerically("~", 3*0.001, 0.01))
				})
			})

			Context("when a regexp focusString is provided", func() {
				BeforeEach(func() {
					conf.FocusString = `collection description.*pickles\d$`
					example1 = exampleWithItFunc("focused it 1", flagTypeFocused, false)
					example2 = exampleWithItFunc("another it pickles2", flagTypeNone, false)
					example3 = exampleWithItFunc("focused it pickles3", flagTypeFocused, false)
				})

				It("ignores the programmatic focus and applies the regexp focusString", func() {
					Ω(examplesThatWereRun).Should(Equal([]string{"another it pickles2", "focused it pickles3"}))
				})

				It("publishes the correct starting suite summary", func() {
					summary := fakeR.BeginSummary
					Ω(summary.SuiteDescription).Should(Equal("collection description"))
					Ω(summary.SuiteSucceeded).Should(BeTrue())
					Ω(summary.NumberOfExamplesBeforeParallelization).Should(Equal(3))
					Ω(summary.NumberOfTotalExamples).Should(Equal(3))
					Ω(summary.NumberOfExamplesThatWillBeRun).Should(Equal(2))
					Ω(summary.NumberOfPendingExamples).Should(Equal(0))
					Ω(summary.NumberOfSkippedExamples).Should(Equal(1))
					Ω(summary.NumberOfPassedExamples).Should(Equal(0))
					Ω(summary.NumberOfFailedExamples).Should(Equal(0))
					Ω(summary.RunTime).Should(Equal(time.Duration(0)))
				})

				It("publishes the correct example summaries", func() {
					Ω(fakeR.ExampleSummaries).Should(HaveLen(3))
					Ω(fakeR.ExampleSummaries[0]).Should(Equal(example1.summary(fakeR.BeginSummary.SuiteID)))
					Ω(fakeR.ExampleSummaries[1]).Should(Equal(example2.summary(fakeR.BeginSummary.SuiteID)))
					Ω(fakeR.ExampleSummaries[2]).Should(Equal(example3.summary(fakeR.BeginSummary.SuiteID)))
				})

				It("publishes the correct ending suite summary", func() {
					summary := fakeR.EndSummary
					Ω(summary.SuiteDescription).Should(Equal("collection description"))
					Ω(summary.SuiteSucceeded).Should(BeTrue())
					Ω(summary.NumberOfExamplesBeforeParallelization).Should(Equal(3))
					Ω(summary.NumberOfTotalExamples).Should(Equal(3))
					Ω(summary.NumberOfExamplesThatWillBeRun).Should(Equal(2))
					Ω(summary.NumberOfPendingExamples).Should(Equal(0))
					Ω(summary.NumberOfSkippedExamples).Should(Equal(1))
					Ω(summary.NumberOfPassedExamples).Should(Equal(2))
					Ω(summary.NumberOfFailedExamples).Should(Equal(0))
					Ω(summary.RunTime.Seconds()).Should(BeNumerically("~", 3*0.001, 0.01))
				})
			})

			Context("when a regexp skipString is provided", func() {
				BeforeEach(func() {
					conf.SkipString = `collection description.*pickles\d$`
					example1 = exampleWithItFunc("focused it 1", flagTypeFocused, false)
					example2 = exampleWithItFunc("another it pickles2", flagTypeNone, false)
					example3 = exampleWithItFunc("focused it pickles3", flagTypeFocused, false)
				})

				It("ignores the programmatic focus and applies the regexp skipString", func() {
					Ω(examplesThatWereRun).Should(Equal([]string{"focused it 1"}))
				})

				It("publishes the correct starting suite summary", func() {
					summary := fakeR.BeginSummary
					Ω(summary.SuiteDescription).Should(Equal("collection description"))
					Ω(summary.SuiteSucceeded).Should(BeTrue())
					Ω(summary.NumberOfExamplesBeforeParallelization).Should(Equal(3))
					Ω(summary.NumberOfTotalExamples).Should(Equal(3))
					Ω(summary.NumberOfExamplesThatWillBeRun).Should(Equal(1))
					Ω(summary.NumberOfPendingExamples).Should(Equal(0))
					Ω(summary.NumberOfSkippedExamples).Should(Equal(2))
					Ω(summary.NumberOfPassedExamples).Should(Equal(0))
					Ω(summary.NumberOfFailedExamples).Should(Equal(0))
					Ω(summary.RunTime).Should(Equal(time.Duration(0)))
				})

				It("publishes the correct example summaries", func() {
					Ω(fakeR.ExampleSummaries).Should(HaveLen(3))
					Ω(fakeR.ExampleSummaries[0]).Should(Equal(example1.summary(fakeR.BeginSummary.SuiteID)))
					Ω(fakeR.ExampleSummaries[1]).Should(Equal(example2.summary(fakeR.BeginSummary.SuiteID)))
					Ω(fakeR.ExampleSummaries[2]).Should(Equal(example3.summary(fakeR.BeginSummary.SuiteID)))
				})

				It("publishes the correct ending suite summary", func() {
					summary := fakeR.EndSummary
					Ω(summary.SuiteDescription).Should(Equal("collection description"))
					Ω(summary.SuiteSucceeded).Should(BeTrue())
					Ω(summary.NumberOfExamplesBeforeParallelization).Should(Equal(3))
					Ω(summary.NumberOfTotalExamples).Should(Equal(3))
					Ω(summary.NumberOfExamplesThatWillBeRun).Should(Equal(1))
					Ω(summary.NumberOfPendingExamples).Should(Equal(0))
					Ω(summary.NumberOfSkippedExamples).Should(Equal(2))
					Ω(summary.NumberOfPassedExamples).Should(Equal(1))
					Ω(summary.NumberOfFailedExamples).Should(Equal(0))
					Ω(summary.RunTime.Seconds()).Should(BeNumerically("~", 3*0.001, 0.01))
				})
			})

			Context("when both a regexp skipString and focusString are provided", func() {
				BeforeEach(func() {
					conf.SkipString = `collection description.*2`
					conf.FocusString = `collection description.*A`
					example1 = exampleWithItFunc("A1", flagTypeFocused, false)
					example2 = exampleWithItFunc("A2", flagTypeNone, false)
					example3 = exampleWithItFunc("B1", flagTypeFocused, false)
				})

				It("ignores the programmatic focus and ANDs the focusString and skipString", func() {
					Ω(examplesThatWereRun).Should(Equal([]string{"A1"}))
				})

				It("publishes the correct starting suite summary", func() {
					summary := fakeR.BeginSummary
					Ω(summary.SuiteDescription).Should(Equal("collection description"))
					Ω(summary.SuiteSucceeded).Should(BeTrue())
					Ω(summary.NumberOfExamplesBeforeParallelization).Should(Equal(3))
					Ω(summary.NumberOfTotalExamples).Should(Equal(3))
					Ω(summary.NumberOfExamplesThatWillBeRun).Should(Equal(1))
					Ω(summary.NumberOfPendingExamples).Should(Equal(0))
					Ω(summary.NumberOfSkippedExamples).Should(Equal(2))
					Ω(summary.NumberOfPassedExamples).Should(Equal(0))
					Ω(summary.NumberOfFailedExamples).Should(Equal(0))
					Ω(summary.RunTime).Should(Equal(time.Duration(0)))
				})

				It("publishes the correct example summaries", func() {
					Ω(fakeR.ExampleSummaries).Should(HaveLen(3))
					Ω(fakeR.ExampleSummaries[0]).Should(Equal(example1.summary(fakeR.BeginSummary.SuiteID)))
					Ω(fakeR.ExampleSummaries[1]).Should(Equal(example2.summary(fakeR.BeginSummary.SuiteID)))
					Ω(fakeR.ExampleSummaries[2]).Should(Equal(example3.summary(fakeR.BeginSummary.SuiteID)))
				})

				It("publishes the correct ending suite summary", func() {
					summary := fakeR.EndSummary
					Ω(summary.SuiteDescription).Should(Equal("collection description"))
					Ω(summary.SuiteSucceeded).Should(BeTrue())
					Ω(summary.NumberOfExamplesBeforeParallelization).Should(Equal(3))
					Ω(summary.NumberOfTotalExamples).Should(Equal(3))
					Ω(summary.NumberOfExamplesThatWillBeRun).Should(Equal(1))
					Ω(summary.NumberOfPendingExamples).Should(Equal(0))
					Ω(summary.NumberOfSkippedExamples).Should(Equal(2))
					Ω(summary.NumberOfPassedExamples).Should(Equal(1))
					Ω(summary.NumberOfFailedExamples).Should(Equal(0))
					Ω(summary.RunTime.Seconds()).Should(BeNumerically("~", 3*0.001, 0.01))
				})
			})

			Context("when a examples are run in parallel", func() {
				BeforeEach(func() {
					conf.ParallelTotal = 2
					conf.ParallelNode = 2
				})

				It("trims the example set before running them", func() {
					Ω(examplesThatWereRun).Should(Equal([]string{"it 2", "it 3"}))
				})

				It("publishes the correct starting suite summary", func() {
					summary := fakeR.BeginSummary
					Ω(summary.SuiteDescription).Should(Equal("collection description"))
					Ω(summary.SuiteSucceeded).Should(BeTrue())
					Ω(summary.NumberOfExamplesBeforeParallelization).Should(Equal(3))
					Ω(summary.NumberOfTotalExamples).Should(Equal(2))
					Ω(summary.NumberOfExamplesThatWillBeRun).Should(Equal(2))
					Ω(summary.NumberOfPendingExamples).Should(Equal(0))
					Ω(summary.NumberOfSkippedExamples).Should(Equal(0))
					Ω(summary.NumberOfPassedExamples).Should(Equal(0))
					Ω(summary.NumberOfFailedExamples).Should(Equal(0))
					Ω(summary.RunTime).Should(Equal(time.Duration(0)))
				})

				It("publishes the correct example summaries", func() {
					Ω(fakeR.ExampleSummaries).Should(HaveLen(2))
					Ω(fakeR.ExampleSummaries[0]).Should(Equal(example2.summary(fakeR.BeginSummary.SuiteID)))
					Ω(fakeR.ExampleSummaries[1]).Should(Equal(example3.summary(fakeR.BeginSummary.SuiteID)))
				})

				It("publishes the correct ending suite summary", func() {
					summary := fakeR.EndSummary
					Ω(summary.SuiteDescription).Should(Equal("collection description"))
					Ω(summary.SuiteSucceeded).Should(BeTrue())
					Ω(summary.NumberOfExamplesBeforeParallelization).Should(Equal(3))
					Ω(summary.NumberOfTotalExamples).Should(Equal(2))
					Ω(summary.NumberOfExamplesThatWillBeRun).Should(Equal(2))
					Ω(summary.NumberOfPendingExamples).Should(Equal(0))
					Ω(summary.NumberOfSkippedExamples).Should(Equal(0))
					Ω(summary.NumberOfPassedExamples).Should(Equal(2))
					Ω(summary.NumberOfFailedExamples).Should(Equal(0))
					Ω(summary.RunTime.Seconds()).Should(BeNumerically("~", 3*0.001, 0.01))
				})
			})
		})

		Describe("measurements", func() {
			exampleWithMeasure := func(text string) *example {
				return newExample(newMeasureNode(text, func(b Benchmarker) {
					examplesThatWereRun = append(examplesThatWereRun, text)
				}, flagTypeNone, types.GenerateCodeLocation(0), 1))
			}

			var conf config.GinkgoConfigType

			BeforeEach(func() {
				conf = config.GinkgoConfigType{}
			})

			JustBeforeEach(func() {
				collection = newExampleCollection(fakeT, "collection description", []*example{
					exampleWithItFunc("C", flagTypeNone, false),
					exampleWithItFunc("A", flagTypeNone, false),
					exampleWithItFunc("B", flagTypeNone, false),
					exampleWithMeasure("measure"),
				}, []Reporter{fakeR}, writer, conf)

				collection.run()
			})

			It("runs the measurement", func() {
				Ω(examplesThatWereRun).Should(ContainElement("A"))
				Ω(examplesThatWereRun).Should(ContainElement("measure"))
			})

			Context("when instructed to skip measurements", func() {
				BeforeEach(func() {
					conf = config.GinkgoConfigType{
						SkipMeasurements: true,
					}
				})

				It("skips the measurements", func() {
					Ω(examplesThatWereRun).Should(ContainElement("A"))
					Ω(examplesThatWereRun).ShouldNot(ContainElement("measure"))
				})
			})
		})
	})
}
示例#2
0
var _ = Describe("Server", func() {
	var (
		server               *Server
		reporterA, reporterB *reporters.FakeReporter
		forwardingReporter   *ForwardingReporter

		suiteSummary   *types.SuiteSummary
		exampleSummary *types.ExampleSummary
	)

	BeforeEach(func() {
		var err error
		server, err = NewServer()
		Ω(err).ShouldNot(HaveOccurred())
		reporterA = reporters.NewFakeReporter()
		reporterB = reporters.NewFakeReporter()

		server.RegisterReporters(reporterA, reporterB)

		forwardingReporter = NewForwardingReporter(server.Address(), &http.Client{}, &fakeOutputInterceptor{})

		suiteSummary = &types.SuiteSummary{
			SuiteDescription: "My Test Suite",
		}

		exampleSummary = &types.ExampleSummary{
			ComponentTexts: []string{"My", "Example"},
			State:          types.ExampleStatePassed,
		}
示例#3
0
func init() {
	Describe("Suite", func() {
		var (
			specSuite *suite
			fakeT     *fakeTestingT
			fakeR     *reporters.FakeReporter
			writer    *fakeGinkgoWriter
		)

		BeforeEach(func() {
			writer = &fakeGinkgoWriter{}
			fakeT = &fakeTestingT{}
			fakeR = reporters.NewFakeReporter()
			specSuite = newSuite()
		})

		Describe("running a suite", func() {
			var (
				runOrder          []string
				randomizeAllSpecs bool
				randomSeed        int64
				focusString       string
				parallelNode      int
				parallelTotal     int
				runResult         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.pushBeforeEachNode(f("top BE"), types.GenerateCodeLocation(0), 0)
				specSuite.pushJustBeforeEachNode(f("top JBE"), types.GenerateCodeLocation(0), 0)
				specSuite.pushAfterEachNode(f("top AE"), types.GenerateCodeLocation(0), 0)

				specSuite.pushContainerNode("container", func() {
					specSuite.pushBeforeEachNode(f("BE"), types.GenerateCodeLocation(0), 0)
					specSuite.pushJustBeforeEachNode(f("JBE"), types.GenerateCodeLocation(0), 0)
					specSuite.pushAfterEachNode(f("AE"), types.GenerateCodeLocation(0), 0)
					specSuite.pushItNode("it", f("IT"), flagTypeNone, types.GenerateCodeLocation(0), 0)

					specSuite.pushContainerNode("inner container", func() {
						specSuite.pushItNode("inner it", f("inner IT"), flagTypeNone, types.GenerateCodeLocation(0), 0)
					}, flagTypeNone, types.GenerateCodeLocation(0))
				}, flagTypeNone, types.GenerateCodeLocation(0))

				specSuite.pushContainerNode("container 2", func() {
					specSuite.pushBeforeEachNode(f("BE 2"), types.GenerateCodeLocation(0), 0)
					specSuite.pushItNode("it 2", f("IT 2"), flagTypeNone, types.GenerateCodeLocation(0), 0)
				}, flagTypeNone, types.GenerateCodeLocation(0))

				specSuite.pushItNode("top level it", f("top IT"), flagTypeNone, types.GenerateCodeLocation(0), 0)
			})

			JustBeforeEach(func() {
				runResult = specSuite.run(fakeT, "suite description", []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("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))
			})

			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("<=", 0.012))
				Ω(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))
			}, 10)

			It("creates a node hierarchy, converts it to an example collection, and runs it", func() {
				Ω(runOrder).Should(Equal([]string{
					"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",
				}))
			})

			Context("when told to randomize all examples", func() {
				BeforeEach(func() {
					randomizeAllSpecs = true
				})

				It("does", func() {
					Ω(runOrder).Should(Equal([]string{
						"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",
					}))
				})
			})

			Describe("with ginkgo.parallel.total > 1", func() {
				BeforeEach(func() {
					parallelTotal = 2
					randomizeAllSpecs = true
				})

				Context("for one worker", func() {
					BeforeEach(func() {
						parallelNode = 1
					})

					It("should run a subset of tests", func() {
						Ω(runOrder).Should(Equal([]string{
							"top BE", "top JBE", "top IT", "top AE",
							"top BE", "BE", "top JBE", "JBE", "inner IT", "AE", "top AE",
						}))
					})
				})

				Context("for another worker", func() {
					BeforeEach(func() {
						parallelNode = 2
					})

					It("should run a (different) subset of tests", func() {
						Ω(runOrder).Should(Equal([]string{
							"top BE", "BE", "top JBE", "JBE", "IT", "AE", "top AE",
							"top BE", "BE 2", "top JBE", "IT 2", "top AE",
						}))
					})
				})
			})

			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 examples", func() {
					Ω(runOrder).Should(Equal([]string{
						"top BE", "BE", "top JBE", "JBE", "inner IT", "AE", "top AE",
						"top BE", "BE 2", "top JBE", "IT 2", "top AE",
					}))
				})
			})

			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 = types.GenerateCodeLocation(0)
						func() { specSuite.fail("oops!", 0) }()
					}, flagTypeNone, types.GenerateCodeLocation(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.ExampleSummaries[0].Failure.Message).Should(Equal("oops!"))
					Ω(fakeR.ExampleSummaries[0].Failure.Location.FileName).Should(Equal(location.FileName))
					Ω(fakeR.ExampleSummaries[0].Failure.Location.LineNumber).Should(Equal(location.LineNumber + 1))
				})
			})
		})
	})
}