Permalink
Browse files

- Moved outputWriter to reporter.go

- outputWriter is now interface
- Old outputWriter implementation is now plainWriter
- Added some basic functionality to xunitWriter
  • Loading branch information...
1 parent 6413154 commit 45ed7de654751f962e5c6d493a18933dcea604ec Ivan Kirichenko committed Dec 29, 2014
Showing with 181 additions and 84 deletions.
  1. +3 −84 check.go
  2. +178 −0 reporter.go
View
@@ -509,7 +509,7 @@ type suiteRunner struct {
tracker *resultTracker
tempDir *tempDir
keepDir bool
- output *outputWriter
+ output outputWriter
reportedProblemLast bool
benchTime time.Duration
benchMem bool
@@ -545,7 +545,7 @@ func newSuiteRunner(suite interface{}, runConf *RunConf) *suiteRunner {
runner := &suiteRunner{
suite: suite,
- output: newOutputWriter(conf.Output, conf.Stream, conf.Verbose),
+ output: newPlainWriter(conf.Output, conf.Stream, conf.Verbose),
tracker: newResultTracker(),
benchTime: conf.BenchmarkTime,
benchMem: conf.BenchmarkMem,
@@ -632,7 +632,7 @@ func (runner *suiteRunner) run() *Result {
// goroutine with the provided dispatcher for running it.
func (runner *suiteRunner) forkCall(method *methodType, kind funcKind, testName string, logb *logger, dispatcher func(c *C)) *C {
var logw io.Writer
- if runner.output.Stream {
+ if runner.output.StreamEnabled() {
logw = runner.output
}
if logb == nil {
@@ -862,84 +862,3 @@ func (runner *suiteRunner) reportCallDone(c *C) {
runner.output.WriteCallSuccess("MISS", c)
}
}
-
-// -----------------------------------------------------------------------
-// Output writer manages atomic output writing according to settings.
-
-type outputWriter struct {
- m sync.Mutex
- writer io.Writer
- wroteCallProblemLast bool
- Stream bool
- Verbose bool
-}
-
-func newOutputWriter(writer io.Writer, stream, verbose bool) *outputWriter {
- return &outputWriter{writer: writer, Stream: stream, Verbose: verbose}
-}
-
-func (ow *outputWriter) Write(content []byte) (n int, err error) {
- ow.m.Lock()
- n, err = ow.writer.Write(content)
- ow.m.Unlock()
- return
-}
-
-func (ow *outputWriter) WriteCallStarted(label string, c *C) {
- if ow.Stream {
- header := renderCallHeader(label, c, "", "\n")
- ow.m.Lock()
- ow.writer.Write([]byte(header))
- ow.m.Unlock()
- }
-}
-
-func (ow *outputWriter) WriteCallProblem(label string, c *C) {
- var prefix string
- if !ow.Stream {
- prefix = "\n-----------------------------------" +
- "-----------------------------------\n"
- }
- header := renderCallHeader(label, c, prefix, "\n\n")
- ow.m.Lock()
- ow.wroteCallProblemLast = true
- ow.writer.Write([]byte(header))
- if !ow.Stream {
- c.logb.WriteTo(ow.writer)
- }
- ow.m.Unlock()
-}
-
-func (ow *outputWriter) WriteCallSuccess(label string, c *C) {
- if ow.Stream || (ow.Verbose && c.kind == testKd) {
- // TODO Use a buffer here.
- var suffix string
- if c.reason != "" {
- suffix = " (" + c.reason + ")"
- }
- if c.status == succeededSt {
- suffix += "\t" + c.timerString()
- }
- suffix += "\n"
- if ow.Stream {
- suffix += "\n"
- }
- header := renderCallHeader(label, c, "", suffix)
- ow.m.Lock()
- // Resist temptation of using line as prefix above due to race.
- if !ow.Stream && ow.wroteCallProblemLast {
- header = "\n-----------------------------------" +
- "-----------------------------------\n" +
- header
- }
- ow.wroteCallProblemLast = false
- ow.writer.Write([]byte(header))
- ow.m.Unlock()
- }
-}
-
-func renderCallHeader(label string, c *C, prefix, suffix string) string {
- pc := c.method.PC()
- return fmt.Sprintf("%s%s: %s: %s%s", prefix, label, niceFuncPath(pc),
- niceFuncName(pc), suffix)
-}
View
@@ -0,0 +1,178 @@
+package check
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "sync"
+ "time"
+)
+
+// TODO: start test suite
+type outputWriter interface {
+ Write(content []byte) (n int, err error)
+ WriteCallStarted(label string, c *C)
+ WriteCallProblem(label string, c *C)
+ WriteCallSuccess(label string, c *C)
+ StreamEnabled() bool
+}
+
+/*************** Plain writer *****************/
+
+type plainWriter struct {
+ outputWriter
+ m sync.Mutex
+ writer io.Writer
+ wroteCallProblemLast bool
+ stream bool
+ verbose bool
+}
+
+func newPlainWriter(writer io.Writer, stream, verbose bool) *plainWriter {
+ return &plainWriter{writer: writer, stream: stream, verbose: verbose}
+}
+
+func (w *plainWriter) StreamEnabled() bool { return w.stream }
+
+func (w *plainWriter) Write(content []byte) (n int, err error) {
+ w.m.Lock()
+ n, err = w.writer.Write(content)
+ w.m.Unlock()
+ return
+}
+
+func (w *plainWriter) WriteCallStarted(label string, c *C) {
+ if w.stream {
+ header := renderCallHeader(label, c, "", "\n")
+ w.m.Lock()
+ w.writer.Write([]byte(header))
+ w.m.Unlock()
+ }
+}
+
+func (w *plainWriter) WriteCallProblem(label string, c *C) {
+ var prefix string
+ if !w.stream {
+ prefix = "\n-----------------------------------" +
+ "-----------------------------------\n"
+ }
+ header := renderCallHeader(label, c, prefix, "\n\n")
+ w.m.Lock()
+ w.wroteCallProblemLast = true
+ w.writer.Write([]byte(header))
+ if !w.stream {
+ c.logb.WriteTo(w.writer)
+ }
+ w.m.Unlock()
+}
+
+func (w *plainWriter) WriteCallSuccess(label string, c *C) {
+ if w.stream || (w.verbose && c.kind == testKd) {
+ // TODO Use a buffer here.
+ var suffix string
+ if c.reason != "" {
+ suffix = " (" + c.reason + ")"
+ }
+ if c.status == succeededSt {
+ suffix += "\t" + c.timerString()
+ }
+ suffix += "\n"
+ if w.stream {
+ suffix += "\n"
+ }
+ header := renderCallHeader(label, c, "", suffix)
+ w.m.Lock()
+ // Resist temptation of using line as prefix above due to race.
+ if !w.stream && w.wroteCallProblemLast {
+ header = "\n-----------------------------------" +
+ "-----------------------------------\n" +
+ header
+ }
+ w.wroteCallProblemLast = false
+ w.writer.Write([]byte(header))
+ w.m.Unlock()
+ }
+}
+
+func renderCallHeader(label string, c *C, prefix, suffix string) string {
+ pc := c.method.PC()
+ return fmt.Sprintf("%s%s: %s: %s%s", prefix, label, niceFuncPath(pc),
+ niceFuncName(pc), suffix)
+}
+
+/*************** xUnit writer *****************/
+// TODO: Write mrthod can collect data for std-out
+type xunitReport struct {
+ suites []xunitSuite `xml:"testsuites>testsuite,omitempty"`
+}
+
+type xunitSuite struct {
+ Package string `xml:"package,attr,omitempty"`
+ Name string `xml:"name,attr,omitempty"`
+ Classname string `xml:"classname,attr,omitempty"`
+ Time float64 `xml:"time,attr"`
+ Timestamp time.Time `xml:"timestamp,attr"`
+
+ Tests uint64 `xml:"tests,attr"`
+ Failures uint64 `xml:"failures,attr"`
+ Errors uint64 `xml:"errors,attr"`
+ Skipped uint64 `xml:"skipped,attr"`
+
+ Properties []xunitSuiteProperty `xml:"properties>property"` //TODO: test
+ Testcases []xunitTestcase `xml:"testcase"`
+
+ SystemOut string `xml:"system-out,omitempty"`
+ SystemErr string `xml:"system-err,omitempty"`
+}
+
+type xunitSuiteProperty struct {
+ Name string `xml:"name,attr"`
+ Value string `xml:"value,attr"`
+}
+
+type xunitTestcase struct {
+ Name string `xml:"name,attr,omitempty"`
+ Classname string `xml:"classname,attr,omitempty"`
+ Time float64 `xml:"time,attr"`
+ Failure *xunitTestcaseResult `xml:"failure,omitempty"`
+ Error *xunitTestcaseResult `xml:"error,omitempty"`
+}
+
+type xunitTestcaseResult struct {
+ Message string `xml:"message,attr,omitempty"`
+ Type string `xml:"type,attr,omitempty"`
+ Value string `xml:",chardata"`
+}
+
+type xunitWriter struct {
+ outputWriter
+ m sync.Mutex
+ writer io.Writer
+ stream bool
+ verbose bool
+
+ systemOut io.Writer
+}
+
+func newXunitWriter(writer io.Writer, stream, verbose bool) *plainWriter {
+ return &xunitWriter{
+ writer: writer,
+ systemOut: bytes.Buffer{},
+ stream: stream,
+ verbose: verbose,
+ }
+}
+
+func (w *xunitWriter) GetReport() string {
+}
+
+func (w *xunitWriter) Write(content []byte) (n int, err error) {
+ w.m.Lock()
+ n, err = w.systemOut.Write(content)
+ w.m.Unlock()
+ return
+}
+func (w *xunitWriter) WriteCallStarted(label string, c *C) {}
+func (w *xunitWriter) WriteCallProblem(label string, c *C) {}
+func (w *xunitWriter) WriteCallSuccess(label string, c *C) {}
+func (w *xunitWriter) StreamEnabled() bool {}

0 comments on commit 45ed7de

Please sign in to comment.