summaryrefslogtreecommitdiff
path: root/vendor/github.com/onsi/ginkgo/reporters
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/reporters
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/reporters')
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/default_reporter.go84
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/default_reporter_test.go433
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/fake_reporter.go59
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go152
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/junit_reporter_test.go258
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/reporter.go15
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/reporters_suite_test.go13
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/console_logging.go64
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/fake_stenographer.go142
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/stenographer.go572
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/support/README.md6
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/LICENSE21
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/README.md43
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/colorable_others.go24
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/colorable_windows.go783
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/noncolorable.go57
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/LICENSE9
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/README.md37
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/doc.go2
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_appengine.go9
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_bsd.go18
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_linux.go18
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_solaris.go16
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_windows.go19
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/teamcity_reporter.go93
-rw-r--r--vendor/github.com/onsi/ginkgo/reporters/teamcity_reporter_test.go214
26 files changed, 3161 insertions, 0 deletions
diff --git a/vendor/github.com/onsi/ginkgo/reporters/default_reporter.go b/vendor/github.com/onsi/ginkgo/reporters/default_reporter.go
new file mode 100644
index 000000000..ac58dd5f7
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/default_reporter.go
@@ -0,0 +1,84 @@
+/*
+Ginkgo's Default Reporter
+
+A number of command line flags are available to tweak Ginkgo's default output.
+
+These are documented [here](http://onsi.github.io/ginkgo/#running_tests)
+*/
+package reporters
+
+import (
+ "github.com/onsi/ginkgo/config"
+ "github.com/onsi/ginkgo/reporters/stenographer"
+ "github.com/onsi/ginkgo/types"
+)
+
+type DefaultReporter struct {
+ config config.DefaultReporterConfigType
+ stenographer stenographer.Stenographer
+ specSummaries []*types.SpecSummary
+}
+
+func NewDefaultReporter(config config.DefaultReporterConfigType, stenographer stenographer.Stenographer) *DefaultReporter {
+ return &DefaultReporter{
+ config: config,
+ stenographer: stenographer,
+ }
+}
+
+func (reporter *DefaultReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) {
+ reporter.stenographer.AnnounceSuite(summary.SuiteDescription, config.RandomSeed, config.RandomizeAllSpecs, reporter.config.Succinct)
+ if config.ParallelTotal > 1 {
+ reporter.stenographer.AnnounceParallelRun(config.ParallelNode, config.ParallelTotal, reporter.config.Succinct)
+ } else {
+ reporter.stenographer.AnnounceNumberOfSpecs(summary.NumberOfSpecsThatWillBeRun, summary.NumberOfTotalSpecs, reporter.config.Succinct)
+ }
+}
+
+func (reporter *DefaultReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) {
+ if setupSummary.State != types.SpecStatePassed {
+ reporter.stenographer.AnnounceBeforeSuiteFailure(setupSummary, reporter.config.Succinct, reporter.config.FullTrace)
+ }
+}
+
+func (reporter *DefaultReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) {
+ if setupSummary.State != types.SpecStatePassed {
+ reporter.stenographer.AnnounceAfterSuiteFailure(setupSummary, reporter.config.Succinct, reporter.config.FullTrace)
+ }
+}
+
+func (reporter *DefaultReporter) SpecWillRun(specSummary *types.SpecSummary) {
+ if reporter.config.Verbose && !reporter.config.Succinct && specSummary.State != types.SpecStatePending && specSummary.State != types.SpecStateSkipped {
+ reporter.stenographer.AnnounceSpecWillRun(specSummary)
+ }
+}
+
+func (reporter *DefaultReporter) SpecDidComplete(specSummary *types.SpecSummary) {
+ switch specSummary.State {
+ case types.SpecStatePassed:
+ if specSummary.IsMeasurement {
+ reporter.stenographer.AnnounceSuccesfulMeasurement(specSummary, reporter.config.Succinct)
+ } else if specSummary.RunTime.Seconds() >= reporter.config.SlowSpecThreshold {
+ reporter.stenographer.AnnounceSuccesfulSlowSpec(specSummary, reporter.config.Succinct)
+ } else {
+ reporter.stenographer.AnnounceSuccesfulSpec(specSummary)
+ }
+ case types.SpecStatePending:
+ reporter.stenographer.AnnouncePendingSpec(specSummary, reporter.config.NoisyPendings && !reporter.config.Succinct)
+ case types.SpecStateSkipped:
+ reporter.stenographer.AnnounceSkippedSpec(specSummary, reporter.config.Succinct || !reporter.config.NoisySkippings, reporter.config.FullTrace)
+ case types.SpecStateTimedOut:
+ reporter.stenographer.AnnounceSpecTimedOut(specSummary, reporter.config.Succinct, reporter.config.FullTrace)
+ case types.SpecStatePanicked:
+ reporter.stenographer.AnnounceSpecPanicked(specSummary, reporter.config.Succinct, reporter.config.FullTrace)
+ case types.SpecStateFailed:
+ reporter.stenographer.AnnounceSpecFailed(specSummary, reporter.config.Succinct, reporter.config.FullTrace)
+ }
+
+ reporter.specSummaries = append(reporter.specSummaries, specSummary)
+}
+
+func (reporter *DefaultReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) {
+ reporter.stenographer.SummarizeFailures(reporter.specSummaries)
+ reporter.stenographer.AnnounceSpecRunCompletion(summary, reporter.config.Succinct)
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/default_reporter_test.go b/vendor/github.com/onsi/ginkgo/reporters/default_reporter_test.go
new file mode 100644
index 000000000..2dcf276d3
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/default_reporter_test.go
@@ -0,0 +1,433 @@
+package reporters_test
+
+import (
+ "time"
+
+ . "github.com/onsi/ginkgo"
+ "github.com/onsi/ginkgo/config"
+ "github.com/onsi/ginkgo/reporters"
+ st "github.com/onsi/ginkgo/reporters/stenographer"
+ "github.com/onsi/ginkgo/types"
+ . "github.com/onsi/gomega"
+)
+
+var _ = Describe("DefaultReporter", func() {
+ var (
+ reporter *reporters.DefaultReporter
+ reporterConfig config.DefaultReporterConfigType
+ stenographer *st.FakeStenographer
+
+ ginkgoConfig config.GinkgoConfigType
+ suite *types.SuiteSummary
+ spec *types.SpecSummary
+ )
+
+ BeforeEach(func() {
+ stenographer = st.NewFakeStenographer()
+ reporterConfig = config.DefaultReporterConfigType{
+ NoColor: false,
+ SlowSpecThreshold: 0.1,
+ NoisyPendings: false,
+ NoisySkippings: false,
+ Verbose: true,
+ FullTrace: true,
+ }
+
+ reporter = reporters.NewDefaultReporter(reporterConfig, stenographer)
+ })
+
+ call := func(method string, args ...interface{}) st.FakeStenographerCall {
+ return st.NewFakeStenographerCall(method, args...)
+ }
+
+ Describe("SpecSuiteWillBegin", func() {
+ BeforeEach(func() {
+ suite = &types.SuiteSummary{
+ SuiteDescription: "A Sweet Suite",
+ NumberOfTotalSpecs: 10,
+ NumberOfSpecsThatWillBeRun: 8,
+ }
+
+ ginkgoConfig = config.GinkgoConfigType{
+ RandomSeed: 1138,
+ RandomizeAllSpecs: true,
+ }
+ })
+
+ Context("when a serial (non-parallel) suite begins", func() {
+ BeforeEach(func() {
+ ginkgoConfig.ParallelTotal = 1
+
+ reporter.SpecSuiteWillBegin(ginkgoConfig, suite)
+ })
+
+ It("should announce the suite, then announce the number of specs", func() {
+ Ω(stenographer.Calls()).Should(HaveLen(2))
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSuite", "A Sweet Suite", ginkgoConfig.RandomSeed, true, false)))
+ Ω(stenographer.Calls()[1]).Should(Equal(call("AnnounceNumberOfSpecs", 8, 10, false)))
+ })
+ })
+
+ Context("when a parallel suite begins", func() {
+ BeforeEach(func() {
+ ginkgoConfig.ParallelTotal = 2
+ ginkgoConfig.ParallelNode = 1
+ suite.NumberOfSpecsBeforeParallelization = 20
+
+ reporter.SpecSuiteWillBegin(ginkgoConfig, suite)
+ })
+
+ It("should announce the suite, announce that it's a parallel run, then announce the number of specs", func() {
+ Ω(stenographer.Calls()).Should(HaveLen(2))
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSuite", "A Sweet Suite", ginkgoConfig.RandomSeed, true, false)))
+ Ω(stenographer.Calls()[1]).Should(Equal(call("AnnounceParallelRun", 1, 2, false)))
+ })
+ })
+ })
+
+ Describe("BeforeSuiteDidRun", func() {
+ Context("when the BeforeSuite passes", func() {
+ It("should announce nothing", func() {
+ reporter.BeforeSuiteDidRun(&types.SetupSummary{
+ State: types.SpecStatePassed,
+ })
+
+ Ω(stenographer.Calls()).Should(BeEmpty())
+ })
+ })
+
+ Context("when the BeforeSuite fails", func() {
+ It("should announce the failure", func() {
+ summary := &types.SetupSummary{
+ State: types.SpecStateFailed,
+ }
+ reporter.BeforeSuiteDidRun(summary)
+
+ Ω(stenographer.Calls()).Should(HaveLen(1))
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceBeforeSuiteFailure", summary, false, true)))
+ })
+ })
+ })
+
+ Describe("AfterSuiteDidRun", func() {
+ Context("when the AfterSuite passes", func() {
+ It("should announce nothing", func() {
+ reporter.AfterSuiteDidRun(&types.SetupSummary{
+ State: types.SpecStatePassed,
+ })
+
+ Ω(stenographer.Calls()).Should(BeEmpty())
+ })
+ })
+
+ Context("when the AfterSuite fails", func() {
+ It("should announce the failure", func() {
+ summary := &types.SetupSummary{
+ State: types.SpecStateFailed,
+ }
+ reporter.AfterSuiteDidRun(summary)
+
+ Ω(stenographer.Calls()).Should(HaveLen(1))
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceAfterSuiteFailure", summary, false, true)))
+ })
+ })
+ })
+
+ Describe("SpecWillRun", func() {
+ Context("When running in verbose mode", func() {
+ Context("and the spec will run", func() {
+ BeforeEach(func() {
+ spec = &types.SpecSummary{}
+ reporter.SpecWillRun(spec)
+ })
+
+ It("should announce that the spec will run", func() {
+ Ω(stenographer.Calls()).Should(HaveLen(1))
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSpecWillRun", spec)))
+ })
+ })
+
+ Context("and the spec will not run", func() {
+ Context("because it is pending", func() {
+ BeforeEach(func() {
+ spec = &types.SpecSummary{
+ State: types.SpecStatePending,
+ }
+ reporter.SpecWillRun(spec)
+ })
+
+ It("should announce nothing", func() {
+ Ω(stenographer.Calls()).Should(BeEmpty())
+ })
+ })
+
+ Context("because it is skipped", func() {
+ BeforeEach(func() {
+ spec = &types.SpecSummary{
+ State: types.SpecStateSkipped,
+ }
+ reporter.SpecWillRun(spec)
+ })
+
+ It("should announce nothing", func() {
+ Ω(stenographer.Calls()).Should(BeEmpty())
+ })
+ })
+ })
+ })
+
+ Context("When running in verbose & succinct mode", func() {
+ BeforeEach(func() {
+ reporterConfig.Succinct = true
+ reporter = reporters.NewDefaultReporter(reporterConfig, stenographer)
+ spec = &types.SpecSummary{}
+ reporter.SpecWillRun(spec)
+ })
+
+ It("should announce nothing", func() {
+ Ω(stenographer.Calls()).Should(BeEmpty())
+ })
+ })
+
+ Context("When not running in verbose mode", func() {
+ BeforeEach(func() {
+ reporterConfig.Verbose = false
+ reporter = reporters.NewDefaultReporter(reporterConfig, stenographer)
+ spec = &types.SpecSummary{}
+ reporter.SpecWillRun(spec)
+ })
+
+ It("should announce nothing", func() {
+ Ω(stenographer.Calls()).Should(BeEmpty())
+ })
+ })
+ })
+
+ Describe("SpecDidComplete", func() {
+ JustBeforeEach(func() {
+ reporter.SpecDidComplete(spec)
+ })
+
+ BeforeEach(func() {
+ spec = &types.SpecSummary{}
+ })
+
+ Context("When the spec passed", func() {
+ BeforeEach(func() {
+ spec.State = types.SpecStatePassed
+ })
+
+ Context("When the spec was a measurement", func() {
+ BeforeEach(func() {
+ spec.IsMeasurement = true
+ })
+
+ It("should announce the measurement", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSuccesfulMeasurement", spec, false)))
+ })
+ })
+
+ Context("When the spec is slow", func() {
+ BeforeEach(func() {
+ spec.RunTime = time.Second
+ })
+
+ It("should announce that it was slow", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSuccesfulSlowSpec", spec, false)))
+ })
+ })
+
+ Context("Otherwise", func() {
+ It("should announce the succesful spec", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSuccesfulSpec", spec)))
+ })
+ })
+ })
+
+ Context("When the spec is pending", func() {
+ BeforeEach(func() {
+ spec.State = types.SpecStatePending
+ })
+
+ It("should announce the pending spec, succinctly", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnouncePendingSpec", spec, false)))
+ })
+ })
+
+ Context("When the spec is skipped", func() {
+ BeforeEach(func() {
+ spec.State = types.SpecStateSkipped
+ })
+
+ It("should announce the skipped spec, succinctly", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSkippedSpec", spec, true, true)))
+ })
+ })
+
+ Context("When the spec timed out", func() {
+ BeforeEach(func() {
+ spec.State = types.SpecStateTimedOut
+ })
+
+ It("should announce the timedout spec", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSpecTimedOut", spec, false, true)))
+ })
+ })
+
+ Context("When the spec panicked", func() {
+ BeforeEach(func() {
+ spec.State = types.SpecStatePanicked
+ })
+
+ It("should announce the panicked spec", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSpecPanicked", spec, false, true)))
+ })
+ })
+
+ Context("When the spec failed", func() {
+ BeforeEach(func() {
+ spec.State = types.SpecStateFailed
+ })
+
+ It("should announce the failed spec", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSpecFailed", spec, false, true)))
+ })
+ })
+
+ Context("in noisy pendings mode", func() {
+ BeforeEach(func() {
+ reporterConfig.Succinct = false
+ reporterConfig.NoisyPendings = true
+ reporter = reporters.NewDefaultReporter(reporterConfig, stenographer)
+ })
+
+ Context("When the spec is pending", func() {
+ BeforeEach(func() {
+ spec.State = types.SpecStatePending
+ })
+
+ It("should announce the pending spec, noisily", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnouncePendingSpec", spec, true)))
+ })
+ })
+ })
+
+ Context("in noisy skippings mode", func() {
+ BeforeEach(func() {
+ reporterConfig.Succinct = false
+ reporterConfig.NoisySkippings = true
+ reporter = reporters.NewDefaultReporter(reporterConfig, stenographer)
+ })
+
+ Context("When the spec is skipped", func() {
+ BeforeEach(func() {
+ spec.State = types.SpecStateSkipped
+ })
+
+ It("should announce the skipped spec, noisily", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSkippedSpec", spec, false, true)))
+ })
+ })
+ })
+
+ Context("in succinct mode", func() {
+ BeforeEach(func() {
+ reporterConfig.Succinct = true
+ reporter = reporters.NewDefaultReporter(reporterConfig, stenographer)
+ })
+
+ Context("When the spec passed", func() {
+ BeforeEach(func() {
+ spec.State = types.SpecStatePassed
+ })
+
+ Context("When the spec was a measurement", func() {
+ BeforeEach(func() {
+ spec.IsMeasurement = true
+ })
+
+ It("should announce the measurement", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSuccesfulMeasurement", spec, true)))
+ })
+ })
+
+ Context("When the spec is slow", func() {
+ BeforeEach(func() {
+ spec.RunTime = time.Second
+ })
+
+ It("should announce that it was slow", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSuccesfulSlowSpec", spec, true)))
+ })
+ })
+
+ Context("Otherwise", func() {
+ It("should announce the succesful spec", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSuccesfulSpec", spec)))
+ })
+ })
+ })
+
+ Context("When the spec is pending", func() {
+ BeforeEach(func() {
+ spec.State = types.SpecStatePending
+ })
+
+ It("should announce the pending spec, succinctly", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnouncePendingSpec", spec, false)))
+ })
+ })
+
+ Context("When the spec is skipped", func() {
+ BeforeEach(func() {
+ spec.State = types.SpecStateSkipped
+ })
+
+ It("should announce the skipped spec", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSkippedSpec", spec, true, true)))
+ })
+ })
+
+ Context("When the spec timed out", func() {
+ BeforeEach(func() {
+ spec.State = types.SpecStateTimedOut
+ })
+
+ It("should announce the timedout spec", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSpecTimedOut", spec, true, true)))
+ })
+ })
+
+ Context("When the spec panicked", func() {
+ BeforeEach(func() {
+ spec.State = types.SpecStatePanicked
+ })
+
+ It("should announce the panicked spec", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSpecPanicked", spec, true, true)))
+ })
+ })
+
+ Context("When the spec failed", func() {
+ BeforeEach(func() {
+ spec.State = types.SpecStateFailed
+ })
+
+ It("should announce the failed spec", func() {
+ Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSpecFailed", spec, true, true)))
+ })
+ })
+ })
+ })
+
+ Describe("SpecSuiteDidEnd", func() {
+ BeforeEach(func() {
+ suite = &types.SuiteSummary{}
+ reporter.SpecSuiteDidEnd(suite)
+ })
+
+ It("should announce the spec run's completion", func() {
+ Ω(stenographer.Calls()[1]).Should(Equal(call("AnnounceSpecRunCompletion", suite, false)))
+ })
+ })
+})
diff --git a/vendor/github.com/onsi/ginkgo/reporters/fake_reporter.go b/vendor/github.com/onsi/ginkgo/reporters/fake_reporter.go
new file mode 100644
index 000000000..27db47949
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/fake_reporter.go
@@ -0,0 +1,59 @@
+package reporters
+
+import (
+ "github.com/onsi/ginkgo/config"
+ "github.com/onsi/ginkgo/types"
+)
+
+//FakeReporter is useful for testing purposes
+type FakeReporter struct {
+ Config config.GinkgoConfigType
+
+ BeginSummary *types.SuiteSummary
+ BeforeSuiteSummary *types.SetupSummary
+ SpecWillRunSummaries []*types.SpecSummary
+ SpecSummaries []*types.SpecSummary
+ AfterSuiteSummary *types.SetupSummary
+ EndSummary *types.SuiteSummary
+
+ SpecWillRunStub func(specSummary *types.SpecSummary)
+ SpecDidCompleteStub func(specSummary *types.SpecSummary)
+}
+
+func NewFakeReporter() *FakeReporter {
+ return &FakeReporter{
+ SpecWillRunSummaries: make([]*types.SpecSummary, 0),
+ SpecSummaries: make([]*types.SpecSummary, 0),
+ }
+}
+
+func (fakeR *FakeReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) {
+ fakeR.Config = config
+ fakeR.BeginSummary = summary
+}
+
+func (fakeR *FakeReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) {
+ fakeR.BeforeSuiteSummary = setupSummary
+}
+
+func (fakeR *FakeReporter) SpecWillRun(specSummary *types.SpecSummary) {
+ if fakeR.SpecWillRunStub != nil {
+ fakeR.SpecWillRunStub(specSummary)
+ }
+ fakeR.SpecWillRunSummaries = append(fakeR.SpecWillRunSummaries, specSummary)
+}
+
+func (fakeR *FakeReporter) SpecDidComplete(specSummary *types.SpecSummary) {
+ if fakeR.SpecDidCompleteStub != nil {
+ fakeR.SpecDidCompleteStub(specSummary)
+ }
+ fakeR.SpecSummaries = append(fakeR.SpecSummaries, specSummary)
+}
+
+func (fakeR *FakeReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) {
+ fakeR.AfterSuiteSummary = setupSummary
+}
+
+func (fakeR *FakeReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) {
+ fakeR.EndSummary = summary
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go b/vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go
new file mode 100644
index 000000000..2c9f3c792
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go
@@ -0,0 +1,152 @@
+/*
+
+JUnit XML Reporter for Ginkgo
+
+For usage instructions: http://onsi.github.io/ginkgo/#generating_junit_xml_output
+
+*/
+
+package reporters
+
+import (
+ "encoding/xml"
+ "fmt"
+ "math"
+ "os"
+ "strings"
+
+ "github.com/onsi/ginkgo/config"
+ "github.com/onsi/ginkgo/types"
+)
+
+type JUnitTestSuite struct {
+ XMLName xml.Name `xml:"testsuite"`
+ TestCases []JUnitTestCase `xml:"testcase"`
+ Name string `xml:"name,attr"`
+ Tests int `xml:"tests,attr"`
+ Failures int `xml:"failures,attr"`
+ Errors int `xml:"errors,attr"`
+ Time float64 `xml:"time,attr"`
+}
+
+type JUnitTestCase struct {
+ Name string `xml:"name,attr"`
+ ClassName string `xml:"classname,attr"`
+ FailureMessage *JUnitFailureMessage `xml:"failure,omitempty"`
+ Skipped *JUnitSkipped `xml:"skipped,omitempty"`
+ Time float64 `xml:"time,attr"`
+ SystemOut string `xml:"system-out,omitempty"`
+}
+
+type JUnitFailureMessage struct {
+ Type string `xml:"type,attr"`
+ Message string `xml:",chardata"`
+}
+
+type JUnitSkipped struct {
+ XMLName xml.Name `xml:"skipped"`
+}
+
+type JUnitReporter struct {
+ suite JUnitTestSuite
+ filename string
+ testSuiteName string
+}
+
+//NewJUnitReporter creates a new JUnit XML reporter. The XML will be stored in the passed in filename.
+func NewJUnitReporter(filename string) *JUnitReporter {
+ return &JUnitReporter{
+ filename: filename,
+ }
+}
+
+func (reporter *JUnitReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) {
+ reporter.suite = JUnitTestSuite{
+ Name: summary.SuiteDescription,
+ TestCases: []JUnitTestCase{},
+ }
+ reporter.testSuiteName = summary.SuiteDescription
+}
+
+func (reporter *JUnitReporter) SpecWillRun(specSummary *types.SpecSummary) {
+}
+
+func (reporter *JUnitReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) {
+ reporter.handleSetupSummary("BeforeSuite", setupSummary)
+}
+
+func (reporter *JUnitReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) {
+ reporter.handleSetupSummary("AfterSuite", setupSummary)
+}
+
+func failureMessage(failure types.SpecFailure) string {
+ return fmt.Sprintf("%s\n%s\n%s", failure.ComponentCodeLocation.String(), failure.Message, failure.Location.String())
+}
+
+func (reporter *JUnitReporter) handleSetupSummary(name string, setupSummary *types.SetupSummary) {
+ if setupSummary.State != types.SpecStatePassed {
+ testCase := JUnitTestCase{
+ Name: name,
+ ClassName: reporter.testSuiteName,
+ }
+
+ testCase.FailureMessage = &JUnitFailureMessage{
+ Type: reporter.failureTypeForState(setupSummary.State),
+ Message: failureMessage(setupSummary.Failure),
+ }
+ testCase.SystemOut = setupSummary.CapturedOutput
+ testCase.Time = setupSummary.RunTime.Seconds()
+ reporter.suite.TestCases = append(reporter.suite.TestCases, testCase)
+ }
+}
+
+func (reporter *JUnitReporter) SpecDidComplete(specSummary *types.SpecSummary) {
+ testCase := JUnitTestCase{
+ Name: strings.Join(specSummary.ComponentTexts[1:], " "),
+ ClassName: reporter.testSuiteName,
+ }
+ if specSummary.State == types.SpecStateFailed || specSummary.State == types.SpecStateTimedOut || specSummary.State == types.SpecStatePanicked {
+ testCase.FailureMessage = &JUnitFailureMessage{
+ Type: reporter.failureTypeForState(specSummary.State),
+ Message: failureMessage(specSummary.Failure),
+ }
+ testCase.SystemOut = specSummary.CapturedOutput
+ }
+ if specSummary.State == types.SpecStateSkipped || specSummary.State == types.SpecStatePending {
+ testCase.Skipped = &JUnitSkipped{}
+ }
+ testCase.Time = specSummary.RunTime.Seconds()
+ reporter.suite.TestCases = append(reporter.suite.TestCases, testCase)
+}
+
+func (reporter *JUnitReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) {
+ reporter.suite.Tests = summary.NumberOfSpecsThatWillBeRun
+ reporter.suite.Time = math.Trunc(summary.RunTime.Seconds()*1000) / 1000
+ reporter.suite.Failures = summary.NumberOfFailedSpecs
+ reporter.suite.Errors = 0
+ file, err := os.Create(reporter.filename)
+ if err != nil {
+ fmt.Printf("Failed to create JUnit report file: %s\n\t%s", reporter.filename, err.Error())
+ }
+ defer file.Close()
+ file.WriteString(xml.Header)
+ encoder := xml.NewEncoder(file)
+ encoder.Indent(" ", " ")
+ err = encoder.Encode(reporter.suite)
+ if err != nil {
+ fmt.Printf("Failed to generate JUnit report\n\t%s", err.Error())
+ }
+}
+
+func (reporter *JUnitReporter) failureTypeForState(state types.SpecState) string {
+ switch state {
+ case types.SpecStateFailed:
+ return "Failure"
+ case types.SpecStateTimedOut:
+ return "Timeout"
+ case types.SpecStatePanicked:
+ return "Panic"
+ default:
+ return ""
+ }
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/junit_reporter_test.go b/vendor/github.com/onsi/ginkgo/reporters/junit_reporter_test.go
new file mode 100644
index 000000000..9b75dc006
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/junit_reporter_test.go
@@ -0,0 +1,258 @@
+package reporters_test
+
+import (
+ "encoding/xml"
+ "io/ioutil"
+ "os"
+ "time"
+
+ . "github.com/onsi/ginkgo"
+ "github.com/onsi/ginkgo/config"
+ "github.com/onsi/ginkgo/internal/codelocation"
+ "github.com/onsi/ginkgo/reporters"
+ "github.com/onsi/ginkgo/types"
+ . "github.com/onsi/gomega"
+)
+
+var _ = Describe("JUnit Reporter", func() {
+ var (
+ outputFile string
+ reporter Reporter
+ )
+ testSuiteTime := 12456999 * time.Microsecond
+ reportedSuiteTime := 12.456
+
+ readOutputFile := func() reporters.JUnitTestSuite {
+ bytes, err := ioutil.ReadFile(outputFile)
+ Ω(err).ShouldNot(HaveOccurred())
+ var suite reporters.JUnitTestSuite
+ err = xml.Unmarshal(bytes, &suite)
+ Ω(err).ShouldNot(HaveOccurred())
+ return suite
+ }
+
+ BeforeEach(func() {
+ f, err := ioutil.TempFile("", "output")
+ Ω(err).ShouldNot(HaveOccurred())
+ f.Close()
+ outputFile = f.Name()
+
+ reporter = reporters.NewJUnitReporter(outputFile)
+
+ reporter.SpecSuiteWillBegin(config.GinkgoConfigType{}, &types.SuiteSummary{
+ SuiteDescription: "My test suite",
+ NumberOfSpecsThatWillBeRun: 1,
+ })
+ })
+
+ AfterEach(func() {
+ os.RemoveAll(outputFile)
+ })
+
+ Describe("a passing test", func() {
+ BeforeEach(func() {
+ beforeSuite := &types.SetupSummary{
+ State: types.SpecStatePassed,
+ }
+ reporter.BeforeSuiteDidRun(beforeSuite)
+
+ afterSuite := &types.SetupSummary{
+ State: types.SpecStatePassed,
+ }
+ reporter.AfterSuiteDidRun(afterSuite)
+
+ spec := &types.SpecSummary{
+ ComponentTexts: []string{"[Top Level]", "A", "B", "C"},
+ State: types.SpecStatePassed,
+ RunTime: 5 * time.Second,
+ }
+ reporter.SpecWillRun(spec)
+ reporter.SpecDidComplete(spec)
+
+ reporter.SpecSuiteDidEnd(&types.SuiteSummary{
+ NumberOfSpecsThatWillBeRun: 1,
+ NumberOfFailedSpecs: 0,
+ RunTime: testSuiteTime,
+ })
+ })
+
+ It("should record the test as passing", func() {
+ output := readOutputFile()
+ Ω(output.Name).Should(Equal("My test suite"))
+ Ω(output.Tests).Should(Equal(1))
+ Ω(output.Failures).Should(Equal(0))
+ Ω(output.Time).Should(Equal(reportedSuiteTime))
+ Ω(output.Errors).Should(Equal(0))
+ Ω(output.TestCases).Should(HaveLen(1))
+ Ω(output.TestCases[0].Name).Should(Equal("A B C"))
+ Ω(output.TestCases[0].ClassName).Should(Equal("My test suite"))
+ Ω(output.TestCases[0].FailureMessage).Should(BeNil())
+ Ω(output.TestCases[0].Skipped).Should(BeNil())
+ Ω(output.TestCases[0].Time).Should(Equal(5.0))
+ })
+ })
+
+ Describe("when the BeforeSuite fails", func() {
+ var beforeSuite *types.SetupSummary
+
+ BeforeEach(func() {
+ beforeSuite = &types.SetupSummary{
+ State: types.SpecStateFailed,
+ RunTime: 3 * time.Second,
+ Failure: types.SpecFailure{
+ Message: "failed to setup",
+ ComponentCodeLocation: codelocation.New(0),
+ Location: codelocation.New(2),
+ },
+ }
+ reporter.BeforeSuiteDidRun(beforeSuite)
+
+ reporter.SpecSuiteDidEnd(&types.SuiteSummary{
+ NumberOfSpecsThatWillBeRun: 1,
+ NumberOfFailedSpecs: 1,
+ RunTime: testSuiteTime,
+ })
+ })
+
+ It("should record the test as having failed", func() {
+ output := readOutputFile()
+ Ω(output.Name).Should(Equal("My test suite"))
+ Ω(output.Tests).Should(Equal(1))
+ Ω(output.Failures).Should(Equal(1))
+ Ω(output.Time).Should(Equal(reportedSuiteTime))
+ Ω(output.Errors).Should(Equal(0))
+ Ω(output.TestCases[0].Name).Should(Equal("BeforeSuite"))
+ Ω(output.TestCases[0].Time).Should(Equal(3.0))
+ Ω(output.TestCases[0].ClassName).Should(Equal("My test suite"))
+ Ω(output.TestCases[0].FailureMessage.Type).Should(Equal("Failure"))
+ Ω(output.TestCases[0].FailureMessage.Message).Should(ContainSubstring("failed to setup"))
+ Ω(output.TestCases[0].FailureMessage.Message).Should(ContainSubstring(beforeSuite.Failure.ComponentCodeLocation.String()))
+ Ω(output.TestCases[0].FailureMessage.Message).Should(ContainSubstring(beforeSuite.Failure.Location.String()))
+ Ω(output.TestCases[0].Skipped).Should(BeNil())
+ })
+ })
+
+ Describe("when the AfterSuite fails", func() {
+ var afterSuite *types.SetupSummary
+
+ BeforeEach(func() {
+ afterSuite = &types.SetupSummary{
+ State: types.SpecStateFailed,
+ RunTime: 3 * time.Second,
+ Failure: types.SpecFailure{
+ Message: "failed to setup",
+ ComponentCodeLocation: codelocation.New(0),
+ Location: codelocation.New(2),
+ },
+ }
+ reporter.AfterSuiteDidRun(afterSuite)
+
+ reporter.SpecSuiteDidEnd(&types.SuiteSummary{
+ NumberOfSpecsThatWillBeRun: 1,
+ NumberOfFailedSpecs: 1,
+ RunTime: testSuiteTime,
+ })
+ })
+
+ It("should record the test as having failed", func() {
+ output := readOutputFile()
+ Ω(output.Name).Should(Equal("My test suite"))
+ Ω(output.Tests).Should(Equal(1))
+ Ω(output.Failures).Should(Equal(1))
+ Ω(output.Time).Should(Equal(reportedSuiteTime))
+ Ω(output.Errors).Should(Equal(0))
+ Ω(output.TestCases[0].Name).Should(Equal("AfterSuite"))
+ Ω(output.TestCases[0].Time).Should(Equal(3.0))
+ Ω(output.TestCases[0].ClassName).Should(Equal("My test suite"))
+ Ω(output.TestCases[0].FailureMessage.Type).Should(Equal("Failure"))
+ Ω(output.TestCases[0].FailureMessage.Message).Should(ContainSubstring("failed to setup"))
+ Ω(output.TestCases[0].FailureMessage.Message).Should(ContainSubstring(afterSuite.Failure.ComponentCodeLocation.String()))
+ Ω(output.TestCases[0].FailureMessage.Message).Should(ContainSubstring(afterSuite.Failure.Location.String()))
+ Ω(output.TestCases[0].Skipped).Should(BeNil())
+ })
+ })
+
+ specStateCases := []struct {
+ state types.SpecState
+ message string
+ }{
+ {types.SpecStateFailed, "Failure"},
+ {types.SpecStateTimedOut, "Timeout"},
+ {types.SpecStatePanicked, "Panic"},
+ }
+
+ for _, specStateCase := range specStateCases {
+ specStateCase := specStateCase
+ Describe("a failing test", func() {
+ var spec *types.SpecSummary
+ BeforeEach(func() {
+ spec = &types.SpecSummary{
+ ComponentTexts: []string{"[Top Level]", "A", "B", "C"},
+ State: specStateCase.state,
+ RunTime: 5 * time.Second,
+ Failure: types.SpecFailure{
+ ComponentCodeLocation: codelocation.New(0),
+ Location: codelocation.New(2),
+ Message: "I failed",
+ },
+ }
+ reporter.SpecWillRun(spec)
+ reporter.SpecDidComplete(spec)
+
+ reporter.SpecSuiteDidEnd(&types.SuiteSummary{
+ NumberOfSpecsThatWillBeRun: 1,
+ NumberOfFailedSpecs: 1,
+ RunTime: testSuiteTime,
+ })
+ })
+
+ It("should record test as failing", func() {
+ output := readOutputFile()
+ Ω(output.Name).Should(Equal("My test suite"))
+ Ω(output.Tests).Should(Equal(1))
+ Ω(output.Failures).Should(Equal(1))
+ Ω(output.Time).Should(Equal(reportedSuiteTime))
+ Ω(output.Errors).Should(Equal(0))
+ Ω(output.TestCases[0].Name).Should(Equal("A B C"))
+ Ω(output.TestCases[0].ClassName).Should(Equal("My test suite"))
+ Ω(output.TestCases[0].FailureMessage.Type).Should(Equal(specStateCase.message))
+ Ω(output.TestCases[0].FailureMessage.Message).Should(ContainSubstring("I failed"))
+ Ω(output.TestCases[0].FailureMessage.Message).Should(ContainSubstring(spec.Failure.ComponentCodeLocation.String()))
+ Ω(output.TestCases[0].FailureMessage.Message).Should(ContainSubstring(spec.Failure.Location.String()))
+ Ω(output.TestCases[0].Skipped).Should(BeNil())
+ })
+ })
+ }
+
+ for _, specStateCase := range []types.SpecState{types.SpecStatePending, types.SpecStateSkipped} {
+ specStateCase := specStateCase
+ Describe("a skipped test", func() {
+ var spec *types.SpecSummary
+ BeforeEach(func() {
+ spec = &types.SpecSummary{
+ ComponentTexts: []string{"[Top Level]", "A", "B", "C"},
+ State: specStateCase,
+ RunTime: 5 * time.Second,
+ }
+ reporter.SpecWillRun(spec)
+ reporter.SpecDidComplete(spec)
+
+ reporter.SpecSuiteDidEnd(&types.SuiteSummary{
+ NumberOfSpecsThatWillBeRun: 1,
+ NumberOfFailedSpecs: 0,
+ RunTime: testSuiteTime,
+ })
+ })
+
+ It("should record test as failing", func() {
+ output := readOutputFile()
+ Ω(output.Tests).Should(Equal(1))
+ Ω(output.Failures).Should(Equal(0))
+ Ω(output.Time).Should(Equal(reportedSuiteTime))
+ Ω(output.Errors).Should(Equal(0))
+ Ω(output.TestCases[0].Name).Should(Equal("A B C"))
+ Ω(output.TestCases[0].Skipped).ShouldNot(BeNil())
+ })
+ })
+ }
+})
diff --git a/vendor/github.com/onsi/ginkgo/reporters/reporter.go b/vendor/github.com/onsi/ginkgo/reporters/reporter.go
new file mode 100644
index 000000000..348b9dfce
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/reporter.go
@@ -0,0 +1,15 @@
+package reporters
+
+import (
+ "github.com/onsi/ginkgo/config"
+ "github.com/onsi/ginkgo/types"
+)
+
+type Reporter interface {
+ SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary)
+ BeforeSuiteDidRun(setupSummary *types.SetupSummary)
+ SpecWillRun(specSummary *types.SpecSummary)
+ SpecDidComplete(specSummary *types.SpecSummary)
+ AfterSuiteDidRun(setupSummary *types.SetupSummary)
+ SpecSuiteDidEnd(summary *types.SuiteSummary)
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/reporters_suite_test.go b/vendor/github.com/onsi/ginkgo/reporters/reporters_suite_test.go
new file mode 100644
index 000000000..cec5a4dbf
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/reporters_suite_test.go
@@ -0,0 +1,13 @@
+package reporters_test
+
+import (
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "testing"
+)
+
+func TestReporters(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Reporters Suite")
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/console_logging.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/console_logging.go
new file mode 100644
index 000000000..45b8f8869
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/console_logging.go
@@ -0,0 +1,64 @@
+package stenographer
+
+import (
+ "fmt"
+ "strings"
+)
+
+func (s *consoleStenographer) colorize(colorCode string, format string, args ...interface{}) string {
+ var out string
+
+ if len(args) > 0 {
+ out = fmt.Sprintf(format, args...)
+ } else {
+ out = format
+ }
+
+ if s.color {
+ return fmt.Sprintf("%s%s%s", colorCode, out, defaultStyle)
+ } else {
+ return out
+ }
+}
+
+func (s *consoleStenographer) printBanner(text string, bannerCharacter string) {
+ fmt.Fprintln(s.w, text)
+ fmt.Fprintln(s.w, strings.Repeat(bannerCharacter, len(text)))
+}
+
+func (s *consoleStenographer) printNewLine() {
+ fmt.Fprintln(s.w, "")
+}
+
+func (s *consoleStenographer) printDelimiter() {
+ fmt.Fprintln(s.w, s.colorize(grayColor, "%s", strings.Repeat("-", 30)))
+}
+
+func (s *consoleStenographer) print(indentation int, format string, args ...interface{}) {
+ fmt.Fprint(s.w, s.indent(indentation, format, args...))
+}
+
+func (s *consoleStenographer) println(indentation int, format string, args ...interface{}) {
+ fmt.Fprintln(s.w, s.indent(indentation, format, args...))
+}
+
+func (s *consoleStenographer) indent(indentation int, format string, args ...interface{}) string {
+ var text string
+
+ if len(args) > 0 {
+ text = fmt.Sprintf(format, args...)
+ } else {
+ text = format
+ }
+
+ stringArray := strings.Split(text, "\n")
+ padding := ""
+ if indentation >= 0 {
+ padding = strings.Repeat(" ", indentation)
+ }
+ for i, s := range stringArray {
+ stringArray[i] = fmt.Sprintf("%s%s", padding, s)
+ }
+
+ return strings.Join(stringArray, "\n")
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/fake_stenographer.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/fake_stenographer.go
new file mode 100644
index 000000000..98854e7d9
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/fake_stenographer.go
@@ -0,0 +1,142 @@
+package stenographer
+
+import (
+ "sync"
+
+ "github.com/onsi/ginkgo/types"
+)
+
+func NewFakeStenographerCall(method string, args ...interface{}) FakeStenographerCall {
+ return FakeStenographerCall{
+ Method: method,
+ Args: args,
+ }
+}
+
+type FakeStenographer struct {
+ calls []FakeStenographerCall
+ lock *sync.Mutex
+}
+
+type FakeStenographerCall struct {
+ Method string
+ Args []interface{}
+}
+
+func NewFakeStenographer() *FakeStenographer {
+ stenographer := &FakeStenographer{
+ lock: &sync.Mutex{},
+ }
+ stenographer.Reset()
+ return stenographer
+}
+
+func (stenographer *FakeStenographer) Calls() []FakeStenographerCall {
+ stenographer.lock.Lock()
+ defer stenographer.lock.Unlock()
+
+ return stenographer.calls
+}
+
+func (stenographer *FakeStenographer) Reset() {
+ stenographer.lock.Lock()
+ defer stenographer.lock.Unlock()
+
+ stenographer.calls = make([]FakeStenographerCall, 0)
+}
+
+func (stenographer *FakeStenographer) CallsTo(method string) []FakeStenographerCall {
+ stenographer.lock.Lock()
+ defer stenographer.lock.Unlock()
+
+ results := make([]FakeStenographerCall, 0)
+ for _, call := range stenographer.calls {
+ if call.Method == method {
+ results = append(results, call)
+ }
+ }
+
+ return results
+}
+
+func (stenographer *FakeStenographer) registerCall(method string, args ...interface{}) {
+ stenographer.lock.Lock()
+ defer stenographer.lock.Unlock()
+
+ stenographer.calls = append(stenographer.calls, NewFakeStenographerCall(method, args...))
+}
+
+func (stenographer *FakeStenographer) AnnounceSuite(description string, randomSeed int64, randomizingAll bool, succinct bool) {
+ stenographer.registerCall("AnnounceSuite", description, randomSeed, randomizingAll, succinct)
+}
+
+func (stenographer *FakeStenographer) AnnounceAggregatedParallelRun(nodes int, succinct bool) {
+ stenographer.registerCall("AnnounceAggregatedParallelRun", nodes, succinct)
+}
+
+func (stenographer *FakeStenographer) AnnounceParallelRun(node int, nodes int, succinct bool) {
+ stenographer.registerCall("AnnounceParallelRun", node, nodes, succinct)
+}
+
+func (stenographer *FakeStenographer) AnnounceNumberOfSpecs(specsToRun int, total int, succinct bool) {
+ stenographer.registerCall("AnnounceNumberOfSpecs", specsToRun, total, succinct)
+}
+
+func (stenographer *FakeStenographer) AnnounceTotalNumberOfSpecs(total int, succinct bool) {
+ stenographer.registerCall("AnnounceTotalNumberOfSpecs", total, succinct)
+}
+
+func (stenographer *FakeStenographer) AnnounceSpecRunCompletion(summary *types.SuiteSummary, succinct bool) {
+ stenographer.registerCall("AnnounceSpecRunCompletion", summary, succinct)
+}
+
+func (stenographer *FakeStenographer) AnnounceSpecWillRun(spec *types.SpecSummary) {
+ stenographer.registerCall("AnnounceSpecWillRun", spec)
+}
+
+func (stenographer *FakeStenographer) AnnounceBeforeSuiteFailure(summary *types.SetupSummary, succinct bool, fullTrace bool) {
+ stenographer.registerCall("AnnounceBeforeSuiteFailure", summary, succinct, fullTrace)
+}
+
+func (stenographer *FakeStenographer) AnnounceAfterSuiteFailure(summary *types.SetupSummary, succinct bool, fullTrace bool) {
+ stenographer.registerCall("AnnounceAfterSuiteFailure", summary, succinct, fullTrace)
+}
+func (stenographer *FakeStenographer) AnnounceCapturedOutput(output string) {
+ stenographer.registerCall("AnnounceCapturedOutput", output)
+}
+
+func (stenographer *FakeStenographer) AnnounceSuccesfulSpec(spec *types.SpecSummary) {
+ stenographer.registerCall("AnnounceSuccesfulSpec", spec)
+}
+
+func (stenographer *FakeStenographer) AnnounceSuccesfulSlowSpec(spec *types.SpecSummary, succinct bool) {
+ stenographer.registerCall("AnnounceSuccesfulSlowSpec", spec, succinct)
+}
+
+func (stenographer *FakeStenographer) AnnounceSuccesfulMeasurement(spec *types.SpecSummary, succinct bool) {
+ stenographer.registerCall("AnnounceSuccesfulMeasurement", spec, succinct)
+}
+
+func (stenographer *FakeStenographer) AnnouncePendingSpec(spec *types.SpecSummary, noisy bool) {
+ stenographer.registerCall("AnnouncePendingSpec", spec, noisy)
+}
+
+func (stenographer *FakeStenographer) AnnounceSkippedSpec(spec *types.SpecSummary, succinct bool, fullTrace bool) {
+ stenographer.registerCall("AnnounceSkippedSpec", spec, succinct, fullTrace)
+}
+
+func (stenographer *FakeStenographer) AnnounceSpecTimedOut(spec *types.SpecSummary, succinct bool, fullTrace bool) {
+ stenographer.registerCall("AnnounceSpecTimedOut", spec, succinct, fullTrace)
+}
+
+func (stenographer *FakeStenographer) AnnounceSpecPanicked(spec *types.SpecSummary, succinct bool, fullTrace bool) {
+ stenographer.registerCall("AnnounceSpecPanicked", spec, succinct, fullTrace)
+}
+
+func (stenographer *FakeStenographer) AnnounceSpecFailed(spec *types.SpecSummary, succinct bool, fullTrace bool) {
+ stenographer.registerCall("AnnounceSpecFailed", spec, succinct, fullTrace)
+}
+
+func (stenographer *FakeStenographer) SummarizeFailures(summaries []*types.SpecSummary) {
+ stenographer.registerCall("SummarizeFailures", summaries)
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/stenographer.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/stenographer.go
new file mode 100644
index 000000000..601c74d66
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/stenographer.go
@@ -0,0 +1,572 @@
+/*
+The stenographer is used by Ginkgo's reporters to generate output.
+
+Move along, nothing to see here.
+*/
+
+package stenographer
+
+import (
+ "fmt"
+ "io"
+ "runtime"
+ "strings"
+
+ "github.com/onsi/ginkgo/types"
+)
+
+const defaultStyle = "\x1b[0m"
+const boldStyle = "\x1b[1m"
+const redColor = "\x1b[91m"
+const greenColor = "\x1b[32m"
+const yellowColor = "\x1b[33m"
+const cyanColor = "\x1b[36m"
+const grayColor = "\x1b[90m"
+const lightGrayColor = "\x1b[37m"
+
+type cursorStateType int
+
+const (
+ cursorStateTop cursorStateType = iota
+ cursorStateStreaming
+ cursorStateMidBlock
+ cursorStateEndBlock
+)
+
+type Stenographer interface {
+ AnnounceSuite(description string, randomSeed int64, randomizingAll bool, succinct bool)
+ AnnounceAggregatedParallelRun(nodes int, succinct bool)
+ AnnounceParallelRun(node int, nodes int, succinct bool)
+ AnnounceTotalNumberOfSpecs(total int, succinct bool)
+ AnnounceNumberOfSpecs(specsToRun int, total int, succinct bool)
+ AnnounceSpecRunCompletion(summary *types.SuiteSummary, succinct bool)
+
+ AnnounceSpecWillRun(spec *types.SpecSummary)
+ AnnounceBeforeSuiteFailure(summary *types.SetupSummary, succinct bool, fullTrace bool)
+ AnnounceAfterSuiteFailure(summary *types.SetupSummary, succinct bool, fullTrace bool)
+
+ AnnounceCapturedOutput(output string)
+
+ AnnounceSuccesfulSpec(spec *types.SpecSummary)
+ AnnounceSuccesfulSlowSpec(spec *types.SpecSummary, succinct bool)
+ AnnounceSuccesfulMeasurement(spec *types.SpecSummary, succinct bool)
+
+ AnnouncePendingSpec(spec *types.SpecSummary, noisy bool)
+ AnnounceSkippedSpec(spec *types.SpecSummary, succinct bool, fullTrace bool)
+
+ AnnounceSpecTimedOut(spec *types.SpecSummary, succinct bool, fullTrace bool)
+ AnnounceSpecPanicked(spec *types.SpecSummary, succinct bool, fullTrace bool)
+ AnnounceSpecFailed(spec *types.SpecSummary, succinct bool, fullTrace bool)
+
+ SummarizeFailures(summaries []*types.SpecSummary)
+}
+
+func New(color bool, enableFlakes bool, writer io.Writer) Stenographer {
+ denoter := "•"
+ if runtime.GOOS == "windows" {
+ denoter = "+"
+ }
+ return &consoleStenographer{
+ color: color,
+ denoter: denoter,
+ cursorState: cursorStateTop,
+ enableFlakes: enableFlakes,
+ w: writer,
+ }
+}
+
+type consoleStenographer struct {
+ color bool
+ denoter string
+ cursorState cursorStateType
+ enableFlakes bool
+ w io.Writer
+}
+
+var alternatingColors = []string{defaultStyle, grayColor}
+
+func (s *consoleStenographer) AnnounceSuite(description string, randomSeed int64, randomizingAll bool, succinct bool) {
+ if succinct {
+ s.print(0, "[%d] %s ", randomSeed, s.colorize(boldStyle, description))
+ return
+ }
+ s.printBanner(fmt.Sprintf("Running Suite: %s", description), "=")
+ s.print(0, "Random Seed: %s", s.colorize(boldStyle, "%d", randomSeed))
+ if randomizingAll {
+ s.print(0, " - Will randomize all specs")
+ }
+ s.printNewLine()
+}
+
+func (s *consoleStenographer) AnnounceParallelRun(node int, nodes int, succinct bool) {
+ if succinct {
+ s.print(0, "- node #%d ", node)
+ return
+ }
+ s.println(0,
+ "Parallel test node %s/%s.",
+ s.colorize(boldStyle, "%d", node),
+ s.colorize(boldStyle, "%d", nodes),
+ )
+ s.printNewLine()
+}
+
+func (s *consoleStenographer) AnnounceAggregatedParallelRun(nodes int, succinct bool) {
+ if succinct {
+ s.print(0, "- %d nodes ", nodes)
+ return
+ }
+ s.println(0,
+ "Running in parallel across %s nodes",
+ s.colorize(boldStyle, "%d", nodes),
+ )
+ s.printNewLine()
+}
+
+func (s *consoleStenographer) AnnounceNumberOfSpecs(specsToRun int, total int, succinct bool) {
+ if succinct {
+ s.print(0, "- %d/%d specs ", specsToRun, total)
+ s.stream()
+ return
+ }
+ s.println(0,
+ "Will run %s of %s specs",
+ s.colorize(boldStyle, "%d", specsToRun),
+ s.colorize(boldStyle, "%d", total),
+ )
+
+ s.printNewLine()
+}
+
+func (s *consoleStenographer) AnnounceTotalNumberOfSpecs(total int, succinct bool) {
+ if succinct {
+ s.print(0, "- %d specs ", total)
+ s.stream()
+ return
+ }
+ s.println(0,
+ "Will run %s specs",
+ s.colorize(boldStyle, "%d", total),
+ )
+
+ s.printNewLine()
+}
+
+func (s *consoleStenographer) AnnounceSpecRunCompletion(summary *types.SuiteSummary, succinct bool) {
+ if succinct && summary.SuiteSucceeded {
+ s.print(0, " %s %s ", s.colorize(greenColor, "SUCCESS!"), summary.RunTime)
+ return
+ }
+ s.printNewLine()
+ color := greenColor
+ if !summary.SuiteSucceeded {
+ color = redColor
+ }
+ s.println(0, s.colorize(boldStyle+color, "Ran %d of %d Specs in %.3f seconds", summary.NumberOfSpecsThatWillBeRun, summary.NumberOfTotalSpecs, summary.RunTime.Seconds()))
+
+ status := ""
+ if summary.SuiteSucceeded {
+ status = s.colorize(boldStyle+greenColor, "SUCCESS!")
+ } else {
+ status = s.colorize(boldStyle+redColor, "FAIL!")
+ }
+
+ flakes := ""
+ if s.enableFlakes {
+ flakes = " | " + s.colorize(yellowColor+boldStyle, "%d Flaked", summary.NumberOfFlakedSpecs)
+ }
+
+ s.print(0,
+ "%s -- %s | %s | %s | %s\n",
+ status,
+ s.colorize(greenColor+boldStyle, "%d Passed", summary.NumberOfPassedSpecs),
+ s.colorize(redColor+boldStyle, "%d Failed", summary.NumberOfFailedSpecs)+flakes,
+ s.colorize(yellowColor+boldStyle, "%d Pending", summary.NumberOfPendingSpecs),
+ s.colorize(cyanColor+boldStyle, "%d Skipped", summary.NumberOfSkippedSpecs),
+ )
+}
+
+func (s *consoleStenographer) AnnounceSpecWillRun(spec *types.SpecSummary) {
+ s.startBlock()
+ for i, text := range spec.ComponentTexts[1 : len(spec.ComponentTexts)-1] {
+ s.print(0, s.colorize(alternatingColors[i%2], text)+" ")
+ }
+
+ indentation := 0
+ if len(spec.ComponentTexts) > 2 {
+ indentation = 1
+ s.printNewLine()
+ }
+ index := len(spec.ComponentTexts) - 1
+ s.print(indentation, s.colorize(boldStyle, spec.ComponentTexts[index]))
+ s.printNewLine()
+ s.print(indentation, s.colorize(lightGrayColor, spec.ComponentCodeLocations[index].String()))
+ s.printNewLine()
+ s.midBlock()
+}
+
+func (s *consoleStenographer) AnnounceBeforeSuiteFailure(summary *types.SetupSummary, succinct bool, fullTrace bool) {
+ s.announceSetupFailure("BeforeSuite", summary, succinct, fullTrace)
+}
+
+func (s *consoleStenographer) AnnounceAfterSuiteFailure(summary *types.SetupSummary, succinct bool, fullTrace bool) {
+ s.announceSetupFailure("AfterSuite", summary, succinct, fullTrace)
+}
+
+func (s *consoleStenographer) announceSetupFailure(name string, summary *types.SetupSummary, succinct bool, fullTrace bool) {
+ s.startBlock()
+ var message string
+ switch summary.State {
+ case types.SpecStateFailed:
+ message = "Failure"
+ case types.SpecStatePanicked:
+ message = "Panic"
+ case types.SpecStateTimedOut:
+ message = "Timeout"
+ }
+
+ s.println(0, s.colorize(redColor+boldStyle, "%s [%.3f seconds]", message, summary.RunTime.Seconds()))
+
+ indentation := s.printCodeLocationBlock([]string{name}, []types.CodeLocation{summary.CodeLocation}, summary.ComponentType, 0, summary.State, true)
+
+ s.printNewLine()
+ s.printFailure(indentation, summary.State, summary.Failure, fullTrace)
+
+ s.endBlock()
+}
+
+func (s *consoleStenographer) AnnounceCapturedOutput(output string) {
+ if output == "" {
+ return
+ }
+
+ s.startBlock()
+ s.println(0, output)
+ s.midBlock()
+}
+
+func (s *consoleStenographer) AnnounceSuccesfulSpec(spec *types.SpecSummary) {
+ s.print(0, s.colorize(greenColor, s.denoter))
+ s.stream()
+}
+
+func (s *consoleStenographer) AnnounceSuccesfulSlowSpec(spec *types.SpecSummary, succinct bool) {
+ s.printBlockWithMessage(
+ s.colorize(greenColor, "%s [SLOW TEST:%.3f seconds]", s.denoter, spec.RunTime.Seconds()),
+ "",
+ spec,
+ succinct,
+ )
+}
+
+func (s *consoleStenographer) AnnounceSuccesfulMeasurement(spec *types.SpecSummary, succinct bool) {
+ s.printBlockWithMessage(
+ s.colorize(greenColor, "%s [MEASUREMENT]", s.denoter),
+ s.measurementReport(spec, succinct),
+ spec,
+ succinct,
+ )
+}
+
+func (s *consoleStenographer) AnnouncePendingSpec(spec *types.SpecSummary, noisy bool) {
+ if noisy {
+ s.printBlockWithMessage(
+ s.colorize(yellowColor, "P [PENDING]"),
+ "",
+ spec,
+ false,
+ )
+ } else {
+ s.print(0, s.colorize(yellowColor, "P"))
+ s.stream()
+ }
+}
+
+func (s *consoleStenographer) AnnounceSkippedSpec(spec *types.SpecSummary, succinct bool, fullTrace bool) {
+ // Skips at runtime will have a non-empty spec.Failure. All others should be succinct.
+ if succinct || spec.Failure == (types.SpecFailure{}) {
+ s.print(0, s.colorize(cyanColor, "S"))
+ s.stream()
+ } else {
+ s.startBlock()
+ s.println(0, s.colorize(cyanColor+boldStyle, "S [SKIPPING]%s [%.3f seconds]", s.failureContext(spec.Failure.ComponentType), spec.RunTime.Seconds()))
+
+ indentation := s.printCodeLocationBlock(spec.ComponentTexts, spec.ComponentCodeLocations, spec.Failure.ComponentType, spec.Failure.ComponentIndex, spec.State, succinct)
+
+ s.printNewLine()
+ s.printSkip(indentation, spec.Failure)
+ s.endBlock()
+ }
+}
+
+func (s *consoleStenographer) AnnounceSpecTimedOut(spec *types.SpecSummary, succinct bool, fullTrace bool) {
+ s.printSpecFailure(fmt.Sprintf("%s... Timeout", s.denoter), spec, succinct, fullTrace)
+}
+
+func (s *consoleStenographer) AnnounceSpecPanicked(spec *types.SpecSummary, succinct bool, fullTrace bool) {
+ s.printSpecFailure(fmt.Sprintf("%s! Panic", s.denoter), spec, succinct, fullTrace)
+}
+
+func (s *consoleStenographer) AnnounceSpecFailed(spec *types.SpecSummary, succinct bool, fullTrace bool) {
+ s.printSpecFailure(fmt.Sprintf("%s Failure", s.denoter), spec, succinct, fullTrace)
+}
+
+func (s *consoleStenographer) SummarizeFailures(summaries []*types.SpecSummary) {
+ failingSpecs := []*types.SpecSummary{}
+
+ for _, summary := range summaries {
+ if summary.HasFailureState() {
+ failingSpecs = append(failingSpecs, summary)
+ }
+ }
+
+ if len(failingSpecs) == 0 {
+ return
+ }
+
+ s.printNewLine()
+ s.printNewLine()
+ plural := "s"
+ if len(failingSpecs) == 1 {
+ plural = ""
+ }
+ s.println(0, s.colorize(redColor+boldStyle, "Summarizing %d Failure%s:", len(failingSpecs), plural))
+ for _, summary := range failingSpecs {
+ s.printNewLine()
+ if summary.HasFailureState() {
+ if summary.TimedOut() {
+ s.print(0, s.colorize(redColor+boldStyle, "[Timeout...] "))
+ } else if summary.Panicked() {
+ s.print(0, s.colorize(redColor+boldStyle, "[Panic!] "))
+ } else if summary.Failed() {
+ s.print(0, s.colorize(redColor+boldStyle, "[Fail] "))
+ }
+ s.printSpecContext(summary.ComponentTexts, summary.ComponentCodeLocations, summary.Failure.ComponentType, summary.Failure.ComponentIndex, summary.State, true)
+ s.printNewLine()
+ s.println(0, s.colorize(lightGrayColor, summary.Failure.Location.String()))
+ }
+ }
+}
+
+func (s *consoleStenographer) startBlock() {
+ if s.cursorState == cursorStateStreaming {
+ s.printNewLine()
+ s.printDelimiter()
+ } else if s.cursorState == cursorStateMidBlock {
+ s.printNewLine()
+ }
+}
+
+func (s *consoleStenographer) midBlock() {
+ s.cursorState = cursorStateMidBlock
+}
+
+func (s *consoleStenographer) endBlock() {
+ s.printDelimiter()
+ s.cursorState = cursorStateEndBlock
+}
+
+func (s *consoleStenographer) stream() {
+ s.cursorState = cursorStateStreaming
+}
+
+func (s *consoleStenographer) printBlockWithMessage(header string, message string, spec *types.SpecSummary, succinct bool) {
+ s.startBlock()
+ s.println(0, header)
+
+ indentation := s.printCodeLocationBlock(spec.ComponentTexts, spec.ComponentCodeLocations, types.SpecComponentTypeInvalid, 0, spec.State, succinct)
+
+ if message != "" {
+ s.printNewLine()
+ s.println(indentation, message)
+ }
+
+ s.endBlock()
+}
+
+func (s *consoleStenographer) printSpecFailure(message string, spec *types.SpecSummary, succinct bool, fullTrace bool) {
+ s.startBlock()
+ s.println(0, s.colorize(redColor+boldStyle, "%s%s [%.3f seconds]", message, s.failureContext(spec.Failure.ComponentType), spec.RunTime.Seconds()))
+
+ indentation := s.printCodeLocationBlock(spec.ComponentTexts, spec.ComponentCodeLocations, spec.Failure.ComponentType, spec.Failure.ComponentIndex, spec.State, succinct)
+
+ s.printNewLine()
+ s.printFailure(indentation, spec.State, spec.Failure, fullTrace)
+ s.endBlock()
+}
+
+func (s *consoleStenographer) failureContext(failedComponentType types.SpecComponentType) string {
+ switch failedComponentType {
+ case types.SpecComponentTypeBeforeSuite:
+ return " in Suite Setup (BeforeSuite)"
+ case types.SpecComponentTypeAfterSuite:
+ return " in Suite Teardown (AfterSuite)"
+ case types.SpecComponentTypeBeforeEach:
+ return " in Spec Setup (BeforeEach)"
+ case types.SpecComponentTypeJustBeforeEach:
+ return " in Spec Setup (JustBeforeEach)"
+ case types.SpecComponentTypeAfterEach:
+ return " in Spec Teardown (AfterEach)"
+ }
+
+ return ""
+}
+
+func (s *consoleStenographer) printSkip(indentation int, spec types.SpecFailure) {
+ s.println(indentation, s.colorize(cyanColor, spec.Message))
+ s.printNewLine()
+ s.println(indentation, spec.Location.String())
+}
+
+func (s *consoleStenographer) printFailure(indentation int, state types.SpecState, failure types.SpecFailure, fullTrace bool) {
+ if state == types.SpecStatePanicked {
+ s.println(indentation, s.colorize(redColor+boldStyle, failure.Message))
+ s.println(indentation, s.colorize(redColor, failure.ForwardedPanic))
+ s.println(indentation, failure.Location.String())
+ s.printNewLine()
+ s.println(indentation, s.colorize(redColor, "Full Stack Trace"))
+ s.println(indentation, failure.Location.FullStackTrace)
+ } else {
+ s.println(indentation, s.colorize(redColor, failure.Message))
+ s.printNewLine()
+ s.println(indentation, failure.Location.String())
+ if fullTrace {
+ s.printNewLine()
+ s.println(indentation, s.colorize(redColor, "Full Stack Trace"))
+ s.println(indentation, failure.Location.FullStackTrace)
+ }
+ }
+}
+
+func (s *consoleStenographer) printSpecContext(componentTexts []string, componentCodeLocations []types.CodeLocation, failedComponentType types.SpecComponentType, failedComponentIndex int, state types.SpecState, succinct bool) int {
+ startIndex := 1
+ indentation := 0
+
+ if len(componentTexts) == 1 {
+ startIndex = 0
+ }
+
+ for i := startIndex; i < len(componentTexts); i++ {
+ if (state.IsFailure() || state == types.SpecStateSkipped) && i == failedComponentIndex {
+ color := redColor
+ if state == types.SpecStateSkipped {
+ color = cyanColor
+ }
+ blockType := ""
+ switch failedComponentType {
+ case types.SpecComponentTypeBeforeSuite:
+ blockType = "BeforeSuite"
+ case types.SpecComponentTypeAfterSuite:
+ blockType = "AfterSuite"
+ case types.SpecComponentTypeBeforeEach:
+ blockType = "BeforeEach"
+ case types.SpecComponentTypeJustBeforeEach:
+ blockType = "JustBeforeEach"
+ case types.SpecComponentTypeAfterEach:
+ blockType = "AfterEach"
+ case types.SpecComponentTypeIt:
+ blockType = "It"
+ case types.SpecComponentTypeMeasure:
+ blockType = "Measurement"
+ }
+ if succinct {
+ s.print(0, s.colorize(color+boldStyle, "[%s] %s ", blockType, componentTexts[i]))
+ } else {
+ s.println(indentation, s.colorize(color+boldStyle, "%s [%s]", componentTexts[i], blockType))
+ s.println(indentation, s.colorize(grayColor, "%s", componentCodeLocations[i]))
+ }
+ } else {
+ if succinct {
+ s.print(0, s.colorize(alternatingColors[i%2], "%s ", componentTexts[i]))
+ } else {
+ s.println(indentation, componentTexts[i])
+ s.println(indentation, s.colorize(grayColor, "%s", componentCodeLocations[i]))
+ }
+ }
+ indentation++
+ }
+
+ return indentation
+}
+
+func (s *consoleStenographer) printCodeLocationBlock(componentTexts []string, componentCodeLocations []types.CodeLocation, failedComponentType types.SpecComponentType, failedComponentIndex int, state types.SpecState, succinct bool) int {
+ indentation := s.printSpecContext(componentTexts, componentCodeLocations, failedComponentType, failedComponentIndex, state, succinct)
+
+ if succinct {
+ if len(componentTexts) > 0 {
+ s.printNewLine()
+ s.print(0, s.colorize(lightGrayColor, "%s", componentCodeLocations[len(componentCodeLocations)-1]))
+ }
+ s.printNewLine()
+ indentation = 1
+ } else {
+ indentation--
+ }
+
+ return indentation
+}
+
+func (s *consoleStenographer) orderedMeasurementKeys(measurements map[string]*types.SpecMeasurement) []string {
+ orderedKeys := make([]string, len(measurements))
+ for key, measurement := range measurements {
+ orderedKeys[measurement.Order] = key
+ }
+ return orderedKeys
+}
+
+func (s *consoleStenographer) measurementReport(spec *types.SpecSummary, succinct bool) string {
+ if len(spec.Measurements) == 0 {
+ return "Found no measurements"
+ }
+
+ message := []string{}
+ orderedKeys := s.orderedMeasurementKeys(spec.Measurements)
+
+ if succinct {
+ message = append(message, fmt.Sprintf("%s samples:", s.colorize(boldStyle, "%d", spec.NumberOfSamples)))
+ for _, key := range orderedKeys {
+ measurement := spec.Measurements[key]
+ message = append(message, fmt.Sprintf(" %s - %s: %s%s, %s: %s%s ± %s%s, %s: %s%s",
+ s.colorize(boldStyle, "%s", measurement.Name),
+ measurement.SmallestLabel,
+ s.colorize(greenColor, measurement.PrecisionFmt(), measurement.Smallest),
+ measurement.Units,
+ measurement.AverageLabel,
+ s.colorize(cyanColor, measurement.PrecisionFmt(), measurement.Average),
+ measurement.Units,
+ s.colorize(cyanColor, measurement.PrecisionFmt(), measurement.StdDeviation),
+ measurement.Units,
+ measurement.LargestLabel,
+ s.colorize(redColor, measurement.PrecisionFmt(), measurement.Largest),
+ measurement.Units,
+ ))
+ }
+ } else {
+ message = append(message, fmt.Sprintf("Ran %s samples:", s.colorize(boldStyle, "%d", spec.NumberOfSamples)))
+ for _, key := range orderedKeys {
+ measurement := spec.Measurements[key]
+ info := ""
+ if measurement.Info != nil {
+ message = append(message, fmt.Sprintf("%v", measurement.Info))
+ }
+
+ message = append(message, fmt.Sprintf("%s:\n%s %s: %s%s\n %s: %s%s\n %s: %s%s ± %s%s",
+ s.colorize(boldStyle, "%s", measurement.Name),
+ info,
+ measurement.SmallestLabel,
+ s.colorize(greenColor, measurement.PrecisionFmt(), measurement.Smallest),
+ measurement.Units,
+ measurement.LargestLabel,
+ s.colorize(redColor, measurement.PrecisionFmt(), measurement.Largest),
+ measurement.Units,
+ measurement.AverageLabel,
+ s.colorize(cyanColor, measurement.PrecisionFmt(), measurement.Average),
+ measurement.Units,
+ s.colorize(cyanColor, measurement.PrecisionFmt(), measurement.StdDeviation),
+ measurement.Units,
+ ))
+ }
+ }
+
+ return strings.Join(message, "\n")
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/README.md b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/README.md
new file mode 100644
index 000000000..37de454f4
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/README.md
@@ -0,0 +1,6 @@
+## Colorize Windows
+
+These packages are used for colorize on Windows and contributed by mattn.jp@gmail.com
+
+ * go-colorable: <https://github.com/mattn/go-colorable>
+ * go-isatty: <https://github.com/mattn/go-isatty>
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/LICENSE b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/LICENSE
new file mode 100644
index 000000000..91b5cef30
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Yasuhiro Matsumoto
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/README.md b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/README.md
new file mode 100644
index 000000000..e84226a73
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/README.md
@@ -0,0 +1,43 @@
+# go-colorable
+
+Colorable writer for windows.
+
+For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.)
+This package is possible to handle escape sequence for ansi color on windows.
+
+## Too Bad!
+
+![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png)
+
+
+## So Good!
+
+![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png)
+
+## Usage
+
+```go
+logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true})
+logrus.SetOutput(colorable.NewColorableStdout())
+
+logrus.Info("succeeded")
+logrus.Warn("not correct")
+logrus.Error("something error")
+logrus.Fatal("panic")
+```
+
+You can compile above code on non-windows OSs.
+
+## Installation
+
+```
+$ go get github.com/mattn/go-colorable
+```
+
+# License
+
+MIT
+
+# Author
+
+Yasuhiro Matsumoto (a.k.a mattn)
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/colorable_others.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/colorable_others.go
new file mode 100644
index 000000000..52d6653b3
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/colorable_others.go
@@ -0,0 +1,24 @@
+// +build !windows
+
+package colorable
+
+import (
+ "io"
+ "os"
+)
+
+func NewColorable(file *os.File) io.Writer {
+ if file == nil {
+ panic("nil passed instead of *os.File to NewColorable()")
+ }
+
+ return file
+}
+
+func NewColorableStdout() io.Writer {
+ return os.Stdout
+}
+
+func NewColorableStderr() io.Writer {
+ return os.Stderr
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/colorable_windows.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/colorable_windows.go
new file mode 100644
index 000000000..108800923
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/colorable_windows.go
@@ -0,0 +1,783 @@
+package colorable
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "math"
+ "os"
+ "strconv"
+ "strings"
+ "syscall"
+ "unsafe"
+
+ "github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty"
+)
+
+const (
+ foregroundBlue = 0x1
+ foregroundGreen = 0x2
+ foregroundRed = 0x4
+ foregroundIntensity = 0x8
+ foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity)
+ backgroundBlue = 0x10
+ backgroundGreen = 0x20
+ backgroundRed = 0x40
+ backgroundIntensity = 0x80
+ backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity)
+)
+
+type wchar uint16
+type short int16
+type dword uint32
+type word uint16
+
+type coord struct {
+ x short
+ y short
+}
+
+type smallRect struct {
+ left short
+ top short
+ right short
+ bottom short
+}
+
+type consoleScreenBufferInfo struct {
+ size coord
+ cursorPosition coord
+ attributes word
+ window smallRect
+ maximumWindowSize coord
+}
+
+var (
+ kernel32 = syscall.NewLazyDLL("kernel32.dll")
+ procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
+ procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
+ procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
+ procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
+ procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute")
+)
+
+type Writer struct {
+ out io.Writer
+ handle syscall.Handle
+ lastbuf bytes.Buffer
+ oldattr word
+}
+
+func NewColorable(file *os.File) io.Writer {
+ if file == nil {
+ panic("nil passed instead of *os.File to NewColorable()")
+ }
+
+ if isatty.IsTerminal(file.Fd()) {
+ var csbi consoleScreenBufferInfo
+ handle := syscall.Handle(file.Fd())
+ procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
+ return &Writer{out: file, handle: handle, oldattr: csbi.attributes}
+ } else {
+ return file
+ }
+}
+
+func NewColorableStdout() io.Writer {
+ return NewColorable(os.Stdout)
+}
+
+func NewColorableStderr() io.Writer {
+ return NewColorable(os.Stderr)
+}
+
+var color256 = map[int]int{
+ 0: 0x000000,
+ 1: 0x800000,
+ 2: 0x008000,
+ 3: 0x808000,
+ 4: 0x000080,
+ 5: 0x800080,
+ 6: 0x008080,
+ 7: 0xc0c0c0,
+ 8: 0x808080,
+ 9: 0xff0000,
+ 10: 0x00ff00,
+ 11: 0xffff00,
+ 12: 0x0000ff,
+ 13: 0xff00ff,
+ 14: 0x00ffff,
+ 15: 0xffffff,
+ 16: 0x000000,
+ 17: 0x00005f,
+ 18: 0x000087,
+ 19: 0x0000af,
+ 20: 0x0000d7,
+ 21: 0x0000ff,
+ 22: 0x005f00,
+ 23: 0x005f5f,
+ 24: 0x005f87,
+ 25: 0x005faf,
+ 26: 0x005fd7,
+ 27: 0x005fff,
+ 28: 0x008700,
+ 29: 0x00875f,
+ 30: 0x008787,
+ 31: 0x0087af,
+ 32: 0x0087d7,
+ 33: 0x0087ff,
+ 34: 0x00af00,
+ 35: 0x00af5f,
+ 36: 0x00af87,
+ 37: 0x00afaf,
+ 38: 0x00afd7,
+ 39: 0x00afff,
+ 40: 0x00d700,
+ 41: 0x00d75f,
+ 42: 0x00d787,
+ 43: 0x00d7af,
+ 44: 0x00d7d7,
+ 45: 0x00d7ff,
+ 46: 0x00ff00,
+ 47: 0x00ff5f,
+ 48: 0x00ff87,
+ 49: 0x00ffaf,
+ 50: 0x00ffd7,
+ 51: 0x00ffff,
+ 52: 0x5f0000,
+ 53: 0x5f005f,
+ 54: 0x5f0087,
+ 55: 0x5f00af,
+ 56: 0x5f00d7,
+ 57: 0x5f00ff,
+ 58: 0x5f5f00,
+ 59: 0x5f5f5f,
+ 60: 0x5f5f87,
+ 61: 0x5f5faf,
+ 62: 0x5f5fd7,
+ 63: 0x5f5fff,
+ 64: 0x5f8700,
+ 65: 0x5f875f,
+ 66: 0x5f8787,
+ 67: 0x5f87af,
+ 68: 0x5f87d7,
+ 69: 0x5f87ff,
+ 70: 0x5faf00,
+ 71: 0x5faf5f,
+ 72: 0x5faf87,
+ 73: 0x5fafaf,
+ 74: 0x5fafd7,
+ 75: 0x5fafff,
+ 76: 0x5fd700,
+ 77: 0x5fd75f,
+ 78: 0x5fd787,
+ 79: 0x5fd7af,
+ 80: 0x5fd7d7,
+ 81: 0x5fd7ff,
+ 82: 0x5fff00,
+ 83: 0x5fff5f,
+ 84: 0x5fff87,
+ 85: 0x5fffaf,
+ 86: 0x5fffd7,
+ 87: 0x5fffff,
+ 88: 0x870000,
+ 89: 0x87005f,
+ 90: 0x870087,
+ 91: 0x8700af,
+ 92: 0x8700d7,
+ 93: 0x8700ff,
+ 94: 0x875f00,
+ 95: 0x875f5f,
+ 96: 0x875f87,
+ 97: 0x875faf,
+ 98: 0x875fd7,
+ 99: 0x875fff,
+ 100: 0x878700,
+ 101: 0x87875f,
+ 102: 0x878787,
+ 103: 0x8787af,
+ 104: 0x8787d7,
+ 105: 0x8787ff,
+ 106: 0x87af00,
+ 107: 0x87af5f,
+ 108: 0x87af87,
+ 109: 0x87afaf,
+ 110: 0x87afd7,
+ 111: 0x87afff,
+ 112: 0x87d700,
+ 113: 0x87d75f,
+ 114: 0x87d787,
+ 115: 0x87d7af,
+ 116: 0x87d7d7,
+ 117: 0x87d7ff,
+ 118: 0x87ff00,
+ 119: 0x87ff5f,
+ 120: 0x87ff87,
+ 121: 0x87ffaf,
+ 122: 0x87ffd7,
+ 123: 0x87ffff,
+ 124: 0xaf0000,
+ 125: 0xaf005f,
+ 126: 0xaf0087,
+ 127: 0xaf00af,
+ 128: 0xaf00d7,
+ 129: 0xaf00ff,
+ 130: 0xaf5f00,
+ 131: 0xaf5f5f,
+ 132: 0xaf5f87,
+ 133: 0xaf5faf,
+ 134: 0xaf5fd7,
+ 135: 0xaf5fff,
+ 136: 0xaf8700,
+ 137: 0xaf875f,
+ 138: 0xaf8787,
+ 139: 0xaf87af,
+ 140: 0xaf87d7,
+ 141: 0xaf87ff,
+ 142: 0xafaf00,
+ 143: 0xafaf5f,
+ 144: 0xafaf87,
+ 145: 0xafafaf,
+ 146: 0xafafd7,
+ 147: 0xafafff,
+ 148: 0xafd700,
+ 149: 0xafd75f,
+ 150: 0xafd787,
+ 151: 0xafd7af,
+ 152: 0xafd7d7,
+ 153: 0xafd7ff,
+ 154: 0xafff00,
+ 155: 0xafff5f,
+ 156: 0xafff87,
+ 157: 0xafffaf,
+ 158: 0xafffd7,
+ 159: 0xafffff,
+ 160: 0xd70000,
+ 161: 0xd7005f,
+ 162: 0xd70087,
+ 163: 0xd700af,
+ 164: 0xd700d7,
+ 165: 0xd700ff,
+ 166: 0xd75f00,
+ 167: 0xd75f5f,
+ 168: 0xd75f87,
+ 169: 0xd75faf,
+ 170: 0xd75fd7,
+ 171: 0xd75fff,
+ 172: 0xd78700,
+ 173: 0xd7875f,
+ 174: 0xd78787,
+ 175: 0xd787af,
+ 176: 0xd787d7,
+ 177: 0xd787ff,
+ 178: 0xd7af00,
+ 179: 0xd7af5f,
+ 180: 0xd7af87,
+ 181: 0xd7afaf,
+ 182: 0xd7afd7,
+ 183: 0xd7afff,
+ 184: 0xd7d700,
+ 185: 0xd7d75f,
+ 186: 0xd7d787,
+ 187: 0xd7d7af,
+ 188: 0xd7d7d7,
+ 189: 0xd7d7ff,
+ 190: 0xd7ff00,
+ 191: 0xd7ff5f,
+ 192: 0xd7ff87,
+ 193: 0xd7ffaf,
+ 194: 0xd7ffd7,
+ 195: 0xd7ffff,
+ 196: 0xff0000,
+ 197: 0xff005f,
+ 198: 0xff0087,
+ 199: 0xff00af,
+ 200: 0xff00d7,
+ 201: 0xff00ff,
+ 202: 0xff5f00,
+ 203: 0xff5f5f,
+ 204: 0xff5f87,
+ 205: 0xff5faf,
+ 206: 0xff5fd7,
+ 207: 0xff5fff,
+ 208: 0xff8700,
+ 209: 0xff875f,
+ 210: 0xff8787,
+ 211: 0xff87af,
+ 212: 0xff87d7,
+ 213: 0xff87ff,
+ 214: 0xffaf00,
+ 215: 0xffaf5f,
+ 216: 0xffaf87,
+ 217: 0xffafaf,
+ 218: 0xffafd7,
+ 219: 0xffafff,
+ 220: 0xffd700,
+ 221: 0xffd75f,
+ 222: 0xffd787,
+ 223: 0xffd7af,
+ 224: 0xffd7d7,
+ 225: 0xffd7ff,
+ 226: 0xffff00,
+ 227: 0xffff5f,
+ 228: 0xffff87,
+ 229: 0xffffaf,
+ 230: 0xffffd7,
+ 231: 0xffffff,
+ 232: 0x080808,
+ 233: 0x121212,
+ 234: 0x1c1c1c,
+ 235: 0x262626,
+ 236: 0x303030,
+ 237: 0x3a3a3a,
+ 238: 0x444444,
+ 239: 0x4e4e4e,
+ 240: 0x585858,
+ 241: 0x626262,
+ 242: 0x6c6c6c,
+ 243: 0x767676,
+ 244: 0x808080,
+ 245: 0x8a8a8a,
+ 246: 0x949494,
+ 247: 0x9e9e9e,
+ 248: 0xa8a8a8,
+ 249: 0xb2b2b2,
+ 250: 0xbcbcbc,
+ 251: 0xc6c6c6,
+ 252: 0xd0d0d0,
+ 253: 0xdadada,
+ 254: 0xe4e4e4,
+ 255: 0xeeeeee,
+}
+
+func (w *Writer) Write(data []byte) (n int, err error) {
+ var csbi consoleScreenBufferInfo
+ procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+
+ er := bytes.NewBuffer(data)
+loop:
+ for {
+ r1, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+ if r1 == 0 {
+ break loop
+ }
+
+ c1, _, err := er.ReadRune()
+ if err != nil {
+ break loop
+ }
+ if c1 != 0x1b {
+ fmt.Fprint(w.out, string(c1))
+ continue
+ }
+ c2, _, err := er.ReadRune()
+ if err != nil {
+ w.lastbuf.WriteRune(c1)
+ break loop
+ }
+ if c2 != 0x5b {
+ w.lastbuf.WriteRune(c1)
+ w.lastbuf.WriteRune(c2)
+ continue
+ }
+
+ var buf bytes.Buffer
+ var m rune
+ for {
+ c, _, err := er.ReadRune()
+ if err != nil {
+ w.lastbuf.WriteRune(c1)
+ w.lastbuf.WriteRune(c2)
+ w.lastbuf.Write(buf.Bytes())
+ break loop
+ }
+ if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
+ m = c
+ break
+ }
+ buf.Write([]byte(string(c)))
+ }
+
+ var csbi consoleScreenBufferInfo
+ switch m {
+ case 'A':
+ n, err = strconv.Atoi(buf.String())
+ if err != nil {
+ continue
+ }
+ procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+ csbi.cursorPosition.y -= short(n)
+ procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
+ case 'B':
+ n, err = strconv.Atoi(buf.String())
+ if err != nil {
+ continue
+ }
+ procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+ csbi.cursorPosition.y += short(n)
+ procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
+ case 'C':
+ n, err = strconv.Atoi(buf.String())
+ if err != nil {
+ continue
+ }
+ procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+ csbi.cursorPosition.x -= short(n)
+ procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
+ case 'D':
+ n, err = strconv.Atoi(buf.String())
+ if err != nil {
+ continue
+ }
+ if n, err = strconv.Atoi(buf.String()); err == nil {
+ var csbi consoleScreenBufferInfo
+ procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+ csbi.cursorPosition.x += short(n)
+ procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
+ }
+ case 'E':
+ n, err = strconv.Atoi(buf.String())
+ if err != nil {
+ continue
+ }
+ procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+ csbi.cursorPosition.x = 0
+ csbi.cursorPosition.y += short(n)
+ procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
+ case 'F':
+ n, err = strconv.Atoi(buf.String())
+ if err != nil {
+ continue
+ }
+ procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+ csbi.cursorPosition.x = 0
+ csbi.cursorPosition.y -= short(n)
+ procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
+ case 'G':
+ n, err = strconv.Atoi(buf.String())
+ if err != nil {
+ continue
+ }
+ procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+ csbi.cursorPosition.x = short(n)
+ procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
+ case 'H':
+ token := strings.Split(buf.String(), ";")
+ if len(token) != 2 {
+ continue
+ }
+ n1, err := strconv.Atoi(token[0])
+ if err != nil {
+ continue
+ }
+ n2, err := strconv.Atoi(token[1])
+ if err != nil {
+ continue
+ }
+ csbi.cursorPosition.x = short(n2)
+ csbi.cursorPosition.x = short(n1)
+ procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
+ case 'J':
+ n, err := strconv.Atoi(buf.String())
+ if err != nil {
+ continue
+ }
+ var cursor coord
+ switch n {
+ case 0:
+ cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}
+ case 1:
+ cursor = coord{x: csbi.window.left, y: csbi.window.top}
+ case 2:
+ cursor = coord{x: csbi.window.left, y: csbi.window.top}
+ }
+ var count, written dword
+ count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x)
+ procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
+ procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
+ case 'K':
+ n, err := strconv.Atoi(buf.String())
+ if err != nil {
+ continue
+ }
+ var cursor coord
+ switch n {
+ case 0:
+ cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}
+ case 1:
+ cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y}
+ case 2:
+ cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y}
+ }
+ var count, written dword
+ count = dword(csbi.size.x - csbi.cursorPosition.x)
+ procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
+ procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
+ case 'm':
+ attr := csbi.attributes
+ cs := buf.String()
+ if cs == "" {
+ procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr))
+ continue
+ }
+ token := strings.Split(cs, ";")
+ for i := 0; i < len(token); i += 1 {
+ ns := token[i]
+ if n, err = strconv.Atoi(ns); err == nil {
+ switch {
+ case n == 0 || n == 100:
+ attr = w.oldattr
+ case 1 <= n && n <= 5:
+ attr |= foregroundIntensity
+ case n == 7:
+ attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)
+ case 22 == n || n == 25 || n == 25:
+ attr |= foregroundIntensity
+ case n == 27:
+ attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)
+ case 30 <= n && n <= 37:
+ attr = (attr & backgroundMask)
+ if (n-30)&1 != 0 {
+ attr |= foregroundRed
+ }
+ if (n-30)&2 != 0 {
+ attr |= foregroundGreen
+ }
+ if (n-30)&4 != 0 {
+ attr |= foregroundBlue
+ }
+ case n == 38: // set foreground color.
+ if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") {
+ if n256, err := strconv.Atoi(token[i+2]); err == nil {
+ if n256foreAttr == nil {
+ n256setup()
+ }
+ attr &= backgroundMask
+ attr |= n256foreAttr[n256]
+ i += 2
+ }
+ } else {
+ attr = attr & (w.oldattr & backgroundMask)
+ }
+ case n == 39: // reset foreground color.
+ attr &= backgroundMask
+ attr |= w.oldattr & foregroundMask
+ case 40 <= n && n <= 47:
+ attr = (attr & foregroundMask)
+ if (n-40)&1 != 0 {
+ attr |= backgroundRed
+ }
+ if (n-40)&2 != 0 {
+ attr |= backgroundGreen
+ }
+ if (n-40)&4 != 0 {
+ attr |= backgroundBlue
+ }
+ case n == 48: // set background color.
+ if i < len(token)-2 && token[i+1] == "5" {
+ if n256, err := strconv.Atoi(token[i+2]); err == nil {
+ if n256backAttr == nil {
+ n256setup()
+ }
+ attr &= foregroundMask
+ attr |= n256backAttr[n256]
+ i += 2
+ }
+ } else {
+ attr = attr & (w.oldattr & foregroundMask)
+ }
+ case n == 49: // reset foreground color.
+ attr &= foregroundMask
+ attr |= w.oldattr & backgroundMask
+ case 90 <= n && n <= 97:
+ attr = (attr & backgroundMask)
+ attr |= foregroundIntensity
+ if (n-90)&1 != 0 {
+ attr |= foregroundRed
+ }
+ if (n-90)&2 != 0 {
+ attr |= foregroundGreen
+ }
+ if (n-90)&4 != 0 {
+ attr |= foregroundBlue
+ }
+ case 100 <= n && n <= 107:
+ attr = (attr & foregroundMask)
+ attr |= backgroundIntensity
+ if (n-100)&1 != 0 {
+ attr |= backgroundRed
+ }
+ if (n-100)&2 != 0 {
+ attr |= backgroundGreen
+ }
+ if (n-100)&4 != 0 {
+ attr |= backgroundBlue
+ }
+ }
+ procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr))
+ }
+ }
+ }
+ }
+ return len(data) - w.lastbuf.Len(), nil
+}
+
+type consoleColor struct {
+ rgb int
+ red bool
+ green bool
+ blue bool
+ intensity bool
+}
+
+func (c consoleColor) foregroundAttr() (attr word) {
+ if c.red {
+ attr |= foregroundRed
+ }
+ if c.green {
+ attr |= foregroundGreen
+ }
+ if c.blue {
+ attr |= foregroundBlue
+ }
+ if c.intensity {
+ attr |= foregroundIntensity
+ }
+ return
+}
+
+func (c consoleColor) backgroundAttr() (attr word) {
+ if c.red {
+ attr |= backgroundRed
+ }
+ if c.green {
+ attr |= backgroundGreen
+ }
+ if c.blue {
+ attr |= backgroundBlue
+ }
+ if c.intensity {
+ attr |= backgroundIntensity
+ }
+ return
+}
+
+var color16 = []consoleColor{
+ consoleColor{0x000000, false, false, false, false},
+ consoleColor{0x000080, false, false, true, false},
+ consoleColor{0x008000, false, true, false, false},
+ consoleColor{0x008080, false, true, true, false},
+ consoleColor{0x800000, true, false, false, false},
+ consoleColor{0x800080, true, false, true, false},
+ consoleColor{0x808000, true, true, false, false},
+ consoleColor{0xc0c0c0, true, true, true, false},
+ consoleColor{0x808080, false, false, false, true},
+ consoleColor{0x0000ff, false, false, true, true},
+ consoleColor{0x00ff00, false, true, false, true},
+ consoleColor{0x00ffff, false, true, true, true},
+ consoleColor{0xff0000, true, false, false, true},
+ consoleColor{0xff00ff, true, false, true, true},
+ consoleColor{0xffff00, true, true, false, true},
+ consoleColor{0xffffff, true, true, true, true},
+}
+
+type hsv struct {
+ h, s, v float32
+}
+
+func (a hsv) dist(b hsv) float32 {
+ dh := a.h - b.h
+ switch {
+ case dh > 0.5:
+ dh = 1 - dh
+ case dh < -0.5:
+ dh = -1 - dh
+ }
+ ds := a.s - b.s
+ dv := a.v - b.v
+ return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv)))
+}
+
+func toHSV(rgb int) hsv {
+ r, g, b := float32((rgb&0xFF0000)>>16)/256.0,
+ float32((rgb&0x00FF00)>>8)/256.0,
+ float32(rgb&0x0000FF)/256.0
+ min, max := minmax3f(r, g, b)
+ h := max - min
+ if h > 0 {
+ if max == r {
+ h = (g - b) / h
+ if h < 0 {
+ h += 6
+ }
+ } else if max == g {
+ h = 2 + (b-r)/h
+ } else {
+ h = 4 + (r-g)/h
+ }
+ }
+ h /= 6.0
+ s := max - min
+ if max != 0 {
+ s /= max
+ }
+ v := max
+ return hsv{h: h, s: s, v: v}
+}
+
+type hsvTable []hsv
+
+func toHSVTable(rgbTable []consoleColor) hsvTable {
+ t := make(hsvTable, len(rgbTable))
+ for i, c := range rgbTable {
+ t[i] = toHSV(c.rgb)
+ }
+ return t
+}
+
+func (t hsvTable) find(rgb int) consoleColor {
+ hsv := toHSV(rgb)
+ n := 7
+ l := float32(5.0)
+ for i, p := range t {
+ d := hsv.dist(p)
+ if d < l {
+ l, n = d, i
+ }
+ }
+ return color16[n]
+}
+
+func minmax3f(a, b, c float32) (min, max float32) {
+ if a < b {
+ if b < c {
+ return a, c
+ } else if a < c {
+ return a, b
+ } else {
+ return c, b
+ }
+ } else {
+ if a < c {
+ return b, c
+ } else if b < c {
+ return b, a
+ } else {
+ return c, a
+ }
+ }
+}
+
+var n256foreAttr []word
+var n256backAttr []word
+
+func n256setup() {
+ n256foreAttr = make([]word, 256)
+ n256backAttr = make([]word, 256)
+ t := toHSVTable(color16)
+ for i, rgb := range color256 {
+ c := t.find(rgb)
+ n256foreAttr[i] = c.foregroundAttr()
+ n256backAttr[i] = c.backgroundAttr()
+ }
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/noncolorable.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/noncolorable.go
new file mode 100644
index 000000000..fb976dbd8
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/noncolorable.go
@@ -0,0 +1,57 @@
+package colorable
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+)
+
+type NonColorable struct {
+ out io.Writer
+ lastbuf bytes.Buffer
+}
+
+func NewNonColorable(w io.Writer) io.Writer {
+ return &NonColorable{out: w}
+}
+
+func (w *NonColorable) Write(data []byte) (n int, err error) {
+ er := bytes.NewBuffer(data)
+loop:
+ for {
+ c1, _, err := er.ReadRune()
+ if err != nil {
+ break loop
+ }
+ if c1 != 0x1b {
+ fmt.Fprint(w.out, string(c1))
+ continue
+ }
+ c2, _, err := er.ReadRune()
+ if err != nil {
+ w.lastbuf.WriteRune(c1)
+ break loop
+ }
+ if c2 != 0x5b {
+ w.lastbuf.WriteRune(c1)
+ w.lastbuf.WriteRune(c2)
+ continue
+ }
+
+ var buf bytes.Buffer
+ for {
+ c, _, err := er.ReadRune()
+ if err != nil {
+ w.lastbuf.WriteRune(c1)
+ w.lastbuf.WriteRune(c2)
+ w.lastbuf.Write(buf.Bytes())
+ break loop
+ }
+ if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
+ break
+ }
+ buf.Write([]byte(string(c)))
+ }
+ }
+ return len(data) - w.lastbuf.Len(), nil
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/LICENSE b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/LICENSE
new file mode 100644
index 000000000..65dc692b6
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/LICENSE
@@ -0,0 +1,9 @@
+Copyright (c) Yasuhiro MATSUMOTO <mattn.jp@gmail.com>
+
+MIT License (Expat)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/README.md b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/README.md
new file mode 100644
index 000000000..74845de4a
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/README.md
@@ -0,0 +1,37 @@
+# go-isatty
+
+isatty for golang
+
+## Usage
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/mattn/go-isatty"
+ "os"
+)
+
+func main() {
+ if isatty.IsTerminal(os.Stdout.Fd()) {
+ fmt.Println("Is Terminal")
+ } else {
+ fmt.Println("Is Not Terminal")
+ }
+}
+```
+
+## Installation
+
+```
+$ go get github.com/mattn/go-isatty
+```
+
+# License
+
+MIT
+
+# Author
+
+Yasuhiro Matsumoto (a.k.a mattn)
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/doc.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/doc.go
new file mode 100644
index 000000000..17d4f90eb
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/doc.go
@@ -0,0 +1,2 @@
+// Package isatty implements interface to isatty
+package isatty
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_appengine.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_appengine.go
new file mode 100644
index 000000000..83c588773
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_appengine.go
@@ -0,0 +1,9 @@
+// +build appengine
+
+package isatty
+
+// IsTerminal returns true if the file descriptor is terminal which
+// is always false on on appengine classic which is a sandboxed PaaS.
+func IsTerminal(fd uintptr) bool {
+ return false
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_bsd.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_bsd.go
new file mode 100644
index 000000000..98ffe86a4
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_bsd.go
@@ -0,0 +1,18 @@
+// +build darwin freebsd openbsd netbsd
+// +build !appengine
+
+package isatty
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+const ioctlReadTermios = syscall.TIOCGETA
+
+// IsTerminal return true if the file descriptor is terminal.
+func IsTerminal(fd uintptr) bool {
+ var termios syscall.Termios
+ _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
+ return err == 0
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_linux.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_linux.go
new file mode 100644
index 000000000..9d24bac1d
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_linux.go
@@ -0,0 +1,18 @@
+// +build linux
+// +build !appengine
+
+package isatty
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+const ioctlReadTermios = syscall.TCGETS
+
+// IsTerminal return true if the file descriptor is terminal.
+func IsTerminal(fd uintptr) bool {
+ var termios syscall.Termios
+ _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
+ return err == 0
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_solaris.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_solaris.go
new file mode 100644
index 000000000..1f0c6bf53
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_solaris.go
@@ -0,0 +1,16 @@
+// +build solaris
+// +build !appengine
+
+package isatty
+
+import (
+ "golang.org/x/sys/unix"
+)
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+// see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c
+func IsTerminal(fd uintptr) bool {
+ var termio unix.Termio
+ err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio)
+ return err == nil
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_windows.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_windows.go
new file mode 100644
index 000000000..83c398b16
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_windows.go
@@ -0,0 +1,19 @@
+// +build windows
+// +build !appengine
+
+package isatty
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+var kernel32 = syscall.NewLazyDLL("kernel32.dll")
+var procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
+
+// IsTerminal return true if the file descriptor is terminal.
+func IsTerminal(fd uintptr) bool {
+ var st uint32
+ r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)
+ return r != 0 && e == 0
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/teamcity_reporter.go b/vendor/github.com/onsi/ginkgo/reporters/teamcity_reporter.go
new file mode 100644
index 000000000..36ee2a600
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/teamcity_reporter.go
@@ -0,0 +1,93 @@
+/*
+
+TeamCity Reporter for Ginkgo
+
+Makes use of TeamCity's support for Service Messages
+http://confluence.jetbrains.com/display/TCD7/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ReportingTests
+*/
+
+package reporters
+
+import (
+ "fmt"
+ "io"
+ "strings"
+
+ "github.com/onsi/ginkgo/config"
+ "github.com/onsi/ginkgo/types"
+)
+
+const (
+ messageId = "##teamcity"
+)
+
+type TeamCityReporter struct {
+ writer io.Writer
+ testSuiteName string
+}
+
+func NewTeamCityReporter(writer io.Writer) *TeamCityReporter {
+ return &TeamCityReporter{
+ writer: writer,
+ }
+}
+
+func (reporter *TeamCityReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) {
+ reporter.testSuiteName = escape(summary.SuiteDescription)
+ fmt.Fprintf(reporter.writer, "%s[testSuiteStarted name='%s']", messageId, reporter.testSuiteName)
+}
+
+func (reporter *TeamCityReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) {
+ reporter.handleSetupSummary("BeforeSuite", setupSummary)
+}
+
+func (reporter *TeamCityReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) {
+ reporter.handleSetupSummary("AfterSuite", setupSummary)
+}
+
+func (reporter *TeamCityReporter) handleSetupSummary(name string, setupSummary *types.SetupSummary) {
+ if setupSummary.State != types.SpecStatePassed {
+ testName := escape(name)
+ fmt.Fprintf(reporter.writer, "%s[testStarted name='%s']", messageId, testName)
+ message := escape(setupSummary.Failure.ComponentCodeLocation.String())
+ details := escape(setupSummary.Failure.Message)
+ fmt.Fprintf(reporter.writer, "%s[testFailed name='%s' message='%s' details='%s']", messageId, testName, message, details)
+ durationInMilliseconds := setupSummary.RunTime.Seconds() * 1000
+ fmt.Fprintf(reporter.writer, "%s[testFinished name='%s' duration='%v']", messageId, testName, durationInMilliseconds)
+ }
+}
+
+func (reporter *TeamCityReporter) SpecWillRun(specSummary *types.SpecSummary) {
+ testName := escape(strings.Join(specSummary.ComponentTexts[1:], " "))
+ fmt.Fprintf(reporter.writer, "%s[testStarted name='%s']", messageId, testName)
+}
+
+func (reporter *TeamCityReporter) SpecDidComplete(specSummary *types.SpecSummary) {
+ testName := escape(strings.Join(specSummary.ComponentTexts[1:], " "))
+
+ if specSummary.State == types.SpecStateFailed || specSummary.State == types.SpecStateTimedOut || specSummary.State == types.SpecStatePanicked {
+ message := escape(specSummary.Failure.ComponentCodeLocation.String())
+ details := escape(specSummary.Failure.Message)
+ fmt.Fprintf(reporter.writer, "%s[testFailed name='%s' message='%s' details='%s']", messageId, testName, message, details)
+ }
+ if specSummary.State == types.SpecStateSkipped || specSummary.State == types.SpecStatePending {
+ fmt.Fprintf(reporter.writer, "%s[testIgnored name='%s']", messageId, testName)
+ }
+
+ durationInMilliseconds := specSummary.RunTime.Seconds() * 1000
+ fmt.Fprintf(reporter.writer, "%s[testFinished name='%s' duration='%v']", messageId, testName, durationInMilliseconds)
+}
+
+func (reporter *TeamCityReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) {
+ fmt.Fprintf(reporter.writer, "%s[testSuiteFinished name='%s']", messageId, reporter.testSuiteName)
+}
+
+func escape(output string) string {
+ output = strings.Replace(output, "|", "||", -1)
+ output = strings.Replace(output, "'", "|'", -1)
+ output = strings.Replace(output, "\n", "|n", -1)
+ output = strings.Replace(output, "\r", "|r", -1)
+ output = strings.Replace(output, "[", "|[", -1)
+ output = strings.Replace(output, "]", "|]", -1)
+ return output
+}
diff --git a/vendor/github.com/onsi/ginkgo/reporters/teamcity_reporter_test.go b/vendor/github.com/onsi/ginkgo/reporters/teamcity_reporter_test.go
new file mode 100644
index 000000000..b45d5db01
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/reporters/teamcity_reporter_test.go
@@ -0,0 +1,214 @@
+package reporters_test
+
+import (
+ "bytes"
+ "fmt"
+ "time"
+
+ . "github.com/onsi/ginkgo"
+ "github.com/onsi/ginkgo/config"
+ "github.com/onsi/ginkgo/internal/codelocation"
+ "github.com/onsi/ginkgo/reporters"
+ "github.com/onsi/ginkgo/types"
+ . "github.com/onsi/gomega"
+)
+
+var _ = Describe("TeamCity Reporter", func() {
+ var (
+ buffer bytes.Buffer
+ reporter Reporter
+ )
+
+ BeforeEach(func() {
+ buffer.Truncate(0)
+ reporter = reporters.NewTeamCityReporter(&buffer)
+ reporter.SpecSuiteWillBegin(config.GinkgoConfigType{}, &types.SuiteSummary{
+ SuiteDescription: "Foo's test suite",
+ NumberOfSpecsThatWillBeRun: 1,
+ })
+ })
+
+ Describe("a passing test", func() {
+ BeforeEach(func() {
+ beforeSuite := &types.SetupSummary{
+ State: types.SpecStatePassed,
+ }
+ reporter.BeforeSuiteDidRun(beforeSuite)
+
+ afterSuite := &types.SetupSummary{
+ State: types.SpecStatePassed,
+ }
+ reporter.AfterSuiteDidRun(afterSuite)
+
+ spec := &types.SpecSummary{
+ ComponentTexts: []string{"[Top Level]", "A", "B", "C"},
+ State: types.SpecStatePassed,
+ RunTime: 5 * time.Second,
+ }
+ reporter.SpecWillRun(spec)
+ reporter.SpecDidComplete(spec)
+
+ reporter.SpecSuiteDidEnd(&types.SuiteSummary{
+ NumberOfSpecsThatWillBeRun: 1,
+ NumberOfFailedSpecs: 0,
+ RunTime: 10 * time.Second,
+ })
+ })
+
+ It("should record the test as passing", func() {
+ actual := buffer.String()
+ expected :=
+ "##teamcity[testSuiteStarted name='Foo|'s test suite']" +
+ "##teamcity[testStarted name='A B C']" +
+ "##teamcity[testFinished name='A B C' duration='5000']" +
+ "##teamcity[testSuiteFinished name='Foo|'s test suite']"
+ Ω(actual).Should(Equal(expected))
+ })
+ })
+
+ Describe("when the BeforeSuite fails", func() {
+ var beforeSuite *types.SetupSummary
+
+ BeforeEach(func() {
+ beforeSuite = &types.SetupSummary{
+ State: types.SpecStateFailed,
+ RunTime: 3 * time.Second,
+ Failure: types.SpecFailure{
+ Message: "failed to setup\n",
+ ComponentCodeLocation: codelocation.New(0),
+ },
+ }
+ reporter.BeforeSuiteDidRun(beforeSuite)
+
+ reporter.SpecSuiteDidEnd(&types.SuiteSummary{
+ NumberOfSpecsThatWillBeRun: 1,
+ NumberOfFailedSpecs: 1,
+ RunTime: 10 * time.Second,
+ })
+ })
+
+ It("should record the test as having failed", func() {
+ actual := buffer.String()
+ expected := fmt.Sprintf(
+ "##teamcity[testSuiteStarted name='Foo|'s test suite']"+
+ "##teamcity[testStarted name='BeforeSuite']"+
+ "##teamcity[testFailed name='BeforeSuite' message='%s' details='failed to setup|n']"+
+ "##teamcity[testFinished name='BeforeSuite' duration='3000']"+
+ "##teamcity[testSuiteFinished name='Foo|'s test suite']", beforeSuite.Failure.ComponentCodeLocation.String(),
+ )
+ Ω(actual).Should(Equal(expected))
+ })
+ })
+
+ Describe("when the AfterSuite fails", func() {
+ var afterSuite *types.SetupSummary
+
+ BeforeEach(func() {
+ afterSuite = &types.SetupSummary{
+ State: types.SpecStateFailed,
+ RunTime: 3 * time.Second,
+ Failure: types.SpecFailure{
+ Message: "failed to setup\n",
+ ComponentCodeLocation: codelocation.New(0),
+ },
+ }
+ reporter.AfterSuiteDidRun(afterSuite)
+
+ reporter.SpecSuiteDidEnd(&types.SuiteSummary{
+ NumberOfSpecsThatWillBeRun: 1,
+ NumberOfFailedSpecs: 1,
+ RunTime: 10 * time.Second,
+ })
+ })
+
+ It("should record the test as having failed", func() {
+ actual := buffer.String()
+ expected := fmt.Sprintf(
+ "##teamcity[testSuiteStarted name='Foo|'s test suite']"+
+ "##teamcity[testStarted name='AfterSuite']"+
+ "##teamcity[testFailed name='AfterSuite' message='%s' details='failed to setup|n']"+
+ "##teamcity[testFinished name='AfterSuite' duration='3000']"+
+ "##teamcity[testSuiteFinished name='Foo|'s test suite']", afterSuite.Failure.ComponentCodeLocation.String(),
+ )
+ Ω(actual).Should(Equal(expected))
+ })
+ })
+ specStateCases := []struct {
+ state types.SpecState
+ message string
+ }{
+ {types.SpecStateFailed, "Failure"},
+ {types.SpecStateTimedOut, "Timeout"},
+ {types.SpecStatePanicked, "Panic"},
+ }
+
+ for _, specStateCase := range specStateCases {
+ specStateCase := specStateCase
+ Describe("a failing test", func() {
+ var spec *types.SpecSummary
+ BeforeEach(func() {
+ spec = &types.SpecSummary{
+ ComponentTexts: []string{"[Top Level]", "A", "B", "C"},
+ State: specStateCase.state,
+ RunTime: 5 * time.Second,
+ Failure: types.SpecFailure{
+ ComponentCodeLocation: codelocation.New(0),
+ Message: "I failed",
+ },
+ }
+ reporter.SpecWillRun(spec)
+ reporter.SpecDidComplete(spec)
+
+ reporter.SpecSuiteDidEnd(&types.SuiteSummary{
+ NumberOfSpecsThatWillBeRun: 1,
+ NumberOfFailedSpecs: 1,
+ RunTime: 10 * time.Second,
+ })
+ })
+
+ It("should record test as failing", func() {
+ actual := buffer.String()
+ expected :=
+ fmt.Sprintf("##teamcity[testSuiteStarted name='Foo|'s test suite']"+
+ "##teamcity[testStarted name='A B C']"+
+ "##teamcity[testFailed name='A B C' message='%s' details='I failed']"+
+ "##teamcity[testFinished name='A B C' duration='5000']"+
+ "##teamcity[testSuiteFinished name='Foo|'s test suite']", spec.Failure.ComponentCodeLocation.String())
+ Ω(actual).Should(Equal(expected))
+ })
+ })
+ }
+
+ for _, specStateCase := range []types.SpecState{types.SpecStatePending, types.SpecStateSkipped} {
+ specStateCase := specStateCase
+ Describe("a skipped test", func() {
+ var spec *types.SpecSummary
+ BeforeEach(func() {
+ spec = &types.SpecSummary{
+ ComponentTexts: []string{"[Top Level]", "A", "B", "C"},
+ State: specStateCase,
+ RunTime: 5 * time.Second,
+ }
+ reporter.SpecWillRun(spec)
+ reporter.SpecDidComplete(spec)
+
+ reporter.SpecSuiteDidEnd(&types.SuiteSummary{
+ NumberOfSpecsThatWillBeRun: 1,
+ NumberOfFailedSpecs: 0,
+ RunTime: 10 * time.Second,
+ })
+ })
+
+ It("should record test as ignored", func() {
+ actual := buffer.String()
+ expected :=
+ "##teamcity[testSuiteStarted name='Foo|'s test suite']" +
+ "##teamcity[testStarted name='A B C']" +
+ "##teamcity[testIgnored name='A B C']" +
+ "##teamcity[testFinished name='A B C' duration='5000']" +
+ "##teamcity[testSuiteFinished name='Foo|'s test suite']"
+ Ω(actual).Should(Equal(expected))
+ })
+ })
+ }
+})