vendor: Mega update all dependencies

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4080
This commit is contained in:
Jakob Borg
2017-04-05 14:34:41 +00:00
parent 49c1527724
commit a1bcc15458
1354 changed files with 55066 additions and 797850 deletions

View File

@@ -29,9 +29,10 @@ func NewDefaultReporter(config config.DefaultReporterConfigType, stenographer st
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, summary.NumberOfTotalSpecs, summary.NumberOfSpecsBeforeParallelization, reporter.config.Succinct)
reporter.stenographer.AnnounceParallelRun(config.ParallelNode, config.ParallelTotal, reporter.config.Succinct)
} else {
reporter.stenographer.AnnounceNumberOfSpecs(summary.NumberOfSpecsThatWillBeRun, summary.NumberOfTotalSpecs, reporter.config.Succinct)
}
reporter.stenographer.AnnounceNumberOfSpecs(summary.NumberOfSpecsThatWillBeRun, summary.NumberOfTotalSpecs, reporter.config.Succinct)
}
func (reporter *DefaultReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) {

View File

@@ -1,415 +0,0 @@
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,
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(3))
Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSuite", "A Sweet Suite", ginkgoConfig.RandomSeed, true, false)))
Ω(stenographer.Calls()[1]).Should(Equal(call("AnnounceParallelRun", 1, 2, 10, 20, false)))
Ω(stenographer.Calls()[2]).Should(Equal(call("AnnounceNumberOfSpecs", 8, 10, 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", func() {
Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSkippedSpec", spec, false, 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 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)))
})
})
})

View File

@@ -11,10 +11,11 @@ package reporters
import (
"encoding/xml"
"fmt"
"github.com/onsi/ginkgo/config"
"github.com/onsi/ginkgo/types"
"os"
"strings"
"github.com/onsi/ginkgo/config"
"github.com/onsi/ginkgo/types"
)
type JUnitTestSuite struct {
@@ -31,6 +32,7 @@ type JUnitTestCase struct {
FailureMessage *JUnitFailureMessage `xml:"failure,omitempty"`
Skipped *JUnitSkipped `xml:"skipped,omitempty"`
Time float64 `xml:"time,attr"`
SystemOut string `xml:"system-out,omitempty"`
}
type JUnitFailureMessage struct {
@@ -57,7 +59,6 @@ func NewJUnitReporter(filename string) *JUnitReporter {
func (reporter *JUnitReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) {
reporter.suite = JUnitTestSuite{
Tests: summary.NumberOfSpecsThatWillBeRun,
TestCases: []JUnitTestCase{},
}
reporter.testSuiteName = summary.SuiteDescription
@@ -74,6 +75,10 @@ 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{
@@ -83,8 +88,9 @@ func (reporter *JUnitReporter) handleSetupSummary(name string, setupSummary *typ
testCase.FailureMessage = &JUnitFailureMessage{
Type: reporter.failureTypeForState(setupSummary.State),
Message: fmt.Sprintf("%s\n%s", setupSummary.Failure.ComponentCodeLocation.String(), setupSummary.Failure.Message),
Message: failureMessage(setupSummary.Failure),
}
testCase.SystemOut = setupSummary.CapturedOutput
testCase.Time = setupSummary.RunTime.Seconds()
reporter.suite.TestCases = append(reporter.suite.TestCases, testCase)
}
@@ -98,8 +104,9 @@ func (reporter *JUnitReporter) SpecDidComplete(specSummary *types.SpecSummary) {
if specSummary.State == types.SpecStateFailed || specSummary.State == types.SpecStateTimedOut || specSummary.State == types.SpecStatePanicked {
testCase.FailureMessage = &JUnitFailureMessage{
Type: reporter.failureTypeForState(specSummary.State),
Message: fmt.Sprintf("%s\n%s", specSummary.Failure.ComponentCodeLocation.String(), specSummary.Failure.Message),
Message: failureMessage(specSummary.Failure),
}
testCase.SystemOut = specSummary.CapturedOutput
}
if specSummary.State == types.SpecStateSkipped || specSummary.State == types.SpecStatePending {
testCase.Skipped = &JUnitSkipped{}
@@ -109,6 +116,7 @@ func (reporter *JUnitReporter) SpecDidComplete(specSummary *types.SpecSummary) {
}
func (reporter *JUnitReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) {
reporter.suite.Tests = summary.NumberOfSpecsThatWillBeRun
reporter.suite.Time = summary.RunTime.Seconds()
reporter.suite.Failures = summary.NumberOfFailedSpecs
file, err := os.Create(reporter.filename)

View File

@@ -1,241 +0,0 @@
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
)
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: 10 * time.Second,
})
})
It("should record the test as passing", func() {
output := readOutputFile()
Ω(output.Tests).Should(Equal(1))
Ω(output.Failures).Should(Equal(0))
Ω(output.Time).Should(Equal(10.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),
},
}
reporter.BeforeSuiteDidRun(beforeSuite)
reporter.SpecSuiteDidEnd(&types.SuiteSummary{
NumberOfSpecsThatWillBeRun: 1,
NumberOfFailedSpecs: 1,
RunTime: 10 * time.Second,
})
})
It("should record the test as having failed", func() {
output := readOutputFile()
Ω(output.Tests).Should(Equal(1))
Ω(output.Failures).Should(Equal(1))
Ω(output.Time).Should(Equal(10.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].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),
},
}
reporter.AfterSuiteDidRun(afterSuite)
reporter.SpecSuiteDidEnd(&types.SuiteSummary{
NumberOfSpecsThatWillBeRun: 1,
NumberOfFailedSpecs: 1,
RunTime: 10 * time.Second,
})
})
It("should record the test as having failed", func() {
output := readOutputFile()
Ω(output.Tests).Should(Equal(1))
Ω(output.Failures).Should(Equal(1))
Ω(output.Time).Should(Equal(10.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].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),
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() {
output := readOutputFile()
Ω(output.Tests).Should(Equal(1))
Ω(output.Failures).Should(Equal(1))
Ω(output.Time).Should(Equal(10.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].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: 10 * time.Second,
})
})
It("should record test as failing", func() {
output := readOutputFile()
Ω(output.Tests).Should(Equal(1))
Ω(output.Failures).Should(Equal(0))
Ω(output.Time).Should(Equal(10.0))
Ω(output.TestCases[0].Name).Should(Equal("A B C"))
Ω(output.TestCases[0].Skipped).ShouldNot(BeNil())
})
})
}
})

View File

@@ -1,13 +0,0 @@
package reporters_test
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"testing"
)
func TestReporters(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Reporters Suite")
}

View File

@@ -22,24 +22,24 @@ func (s *consoleStenographer) colorize(colorCode string, format string, args ...
}
func (s *consoleStenographer) printBanner(text string, bannerCharacter string) {
fmt.Println(text)
fmt.Println(strings.Repeat(bannerCharacter, len(text)))
fmt.Fprintln(s.w, text)
fmt.Fprintln(s.w, strings.Repeat(bannerCharacter, len(text)))
}
func (s *consoleStenographer) printNewLine() {
fmt.Println("")
fmt.Fprintln(s.w, "")
}
func (s *consoleStenographer) printDelimiter() {
fmt.Println(s.colorize(grayColor, "%s", strings.Repeat("-", 30)))
fmt.Fprintln(s.w, s.colorize(grayColor, "%s", strings.Repeat("-", 30)))
}
func (s *consoleStenographer) print(indentation int, format string, args ...interface{}) {
fmt.Print(s.indent(indentation, format, args...))
fmt.Fprint(s.w, s.indent(indentation, format, args...))
}
func (s *consoleStenographer) println(indentation int, format string, args ...interface{}) {
fmt.Println(s.indent(indentation, format, args...))
fmt.Fprintln(s.w, s.indent(indentation, format, args...))
}
func (s *consoleStenographer) indent(indentation int, format string, args ...interface{}) string {

View File

@@ -74,14 +74,18 @@ func (stenographer *FakeStenographer) AnnounceAggregatedParallelRun(nodes int, s
stenographer.registerCall("AnnounceAggregatedParallelRun", nodes, succinct)
}
func (stenographer *FakeStenographer) AnnounceParallelRun(node int, nodes int, specsToRun int, totalSpecs int, succinct bool) {
stenographer.registerCall("AnnounceParallelRun", node, nodes, specsToRun, totalSpecs, 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)
}

View File

@@ -8,9 +8,11 @@ package stenographer
import (
"fmt"
"io"
"runtime"
"strings"
"github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable"
"github.com/onsi/ginkgo/types"
)
@@ -35,7 +37,8 @@ const (
type Stenographer interface {
AnnounceSuite(description string, randomSeed int64, randomizingAll bool, succinct bool)
AnnounceAggregatedParallelRun(nodes int, succinct bool)
AnnounceParallelRun(node int, nodes int, specsToRun int, totalSpecs 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)
@@ -59,22 +62,26 @@ type Stenographer interface {
SummarizeFailures(summaries []*types.SpecSummary)
}
func New(color bool) Stenographer {
func New(color bool, enableFlakes bool) Stenographer {
denoter := "•"
if runtime.GOOS == "windows" {
denoter = "+"
}
return &consoleStenographer{
color: color,
denoter: denoter,
cursorState: cursorStateTop,
color: color,
denoter: denoter,
cursorState: cursorStateTop,
enableFlakes: enableFlakes,
w: colorable.NewColorableStdout(),
}
}
type consoleStenographer struct {
color bool
denoter string
cursorState cursorStateType
color bool
denoter string
cursorState cursorStateType
enableFlakes bool
w io.Writer
}
var alternatingColors = []string{defaultStyle, grayColor}
@@ -92,17 +99,15 @@ func (s *consoleStenographer) AnnounceSuite(description string, randomSeed int64
s.printNewLine()
}
func (s *consoleStenographer) AnnounceParallelRun(node int, nodes int, specsToRun int, totalSpecs int, succinct bool) {
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. Assigned %s of %s specs.",
"Parallel test node %s/%s.",
s.colorize(boldStyle, "%d", node),
s.colorize(boldStyle, "%d", nodes),
s.colorize(boldStyle, "%d", specsToRun),
s.colorize(boldStyle, "%d", totalSpecs),
)
s.printNewLine()
}
@@ -134,6 +139,20 @@ func (s *consoleStenographer) AnnounceNumberOfSpecs(specsToRun int, total int, s
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)
@@ -153,11 +172,16 @@ func (s *consoleStenographer) AnnounceSpecRunCompletion(summary *types.SuiteSumm
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 ",
status,
s.colorize(greenColor+boldStyle, "%d Passed", summary.NumberOfPassedSpecs),
s.colorize(redColor+boldStyle, "%d Failed", summary.NumberOfFailedSpecs),
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),
)
@@ -506,15 +530,15 @@ func (s *consoleStenographer) measurementReport(spec *types.SpecSummary, succinc
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, "%.3f", measurement.Smallest),
s.colorize(greenColor, measurement.PrecisionFmt(), measurement.Smallest),
measurement.Units,
measurement.AverageLabel,
s.colorize(cyanColor, "%.3f", measurement.Average),
s.colorize(cyanColor, measurement.PrecisionFmt(), measurement.Average),
measurement.Units,
s.colorize(cyanColor, "%.3f", measurement.StdDeviation),
s.colorize(cyanColor, measurement.PrecisionFmt(), measurement.StdDeviation),
measurement.Units,
measurement.LargestLabel,
s.colorize(redColor, "%.3f", measurement.Largest),
s.colorize(redColor, measurement.PrecisionFmt(), measurement.Largest),
measurement.Units,
))
}
@@ -531,15 +555,15 @@ func (s *consoleStenographer) measurementReport(spec *types.SpecSummary, succinc
s.colorize(boldStyle, "%s", measurement.Name),
info,
measurement.SmallestLabel,
s.colorize(greenColor, "%.3f", measurement.Smallest),
s.colorize(greenColor, measurement.PrecisionFmt(), measurement.Smallest),
measurement.Units,
measurement.LargestLabel,
s.colorize(redColor, "%.3f", measurement.Largest),
s.colorize(redColor, measurement.PrecisionFmt(), measurement.Largest),
measurement.Units,
measurement.AverageLabel,
s.colorize(cyanColor, "%.3f", measurement.Average),
s.colorize(cyanColor, measurement.PrecisionFmt(), measurement.Average),
measurement.Units,
s.colorize(cyanColor, "%.3f", measurement.StdDeviation),
s.colorize(cyanColor, measurement.PrecisionFmt(), measurement.StdDeviation),
measurement.Units,
))
}

View File

@@ -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
}

View File

@@ -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()
}
}

View File

@@ -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
}

View File

@@ -0,0 +1,2 @@
// Package isatty implements interface to isatty
package isatty

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -1,213 +0,0 @@
package reporters_test
import (
"bytes"
"fmt"
. "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"
"time"
)
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))
})
})
}
})