From 0406dac7d78e4a8fff1f245325de3444a2a385a9 Mon Sep 17 00:00:00 2001 From: Leo Arias Date: Fri, 29 Jan 2016 15:29:42 +0000 Subject: [PATCH] Added an interface for the reporter --- check.go | 20 +++--- export_test.go | 4 ++ reporter.go | 50 +++++++++++-- reporter_test.go | 183 ++++++++++++++++++++++++++++------------------- 4 files changed, 169 insertions(+), 88 deletions(-) diff --git a/check.go b/check.go index a8c8d4d..cbef564 100644 --- a/check.go +++ b/check.go @@ -520,7 +520,7 @@ type suiteRunner struct { tempDir *tempDir keepDir bool logOutput io.Writer - output *outputWriter + reporter testReporter reportedProblemLast bool benchTime time.Duration benchMem bool @@ -565,7 +565,7 @@ func newSuiteRunner(suite interface{}, runConf *RunConf) *suiteRunner { runner := &suiteRunner{ suite: suite, logOutput: conf.Output, - output: newOutputWriter(conf.Output, verbosity), + reporter: newOutputWriter(conf.Output, verbosity), tracker: newResultTracker(), benchTime: conf.BenchmarkTime, benchMem: conf.BenchmarkMem, @@ -853,7 +853,7 @@ func (runner *suiteRunner) checkFixtureArgs() bool { } func (runner *suiteRunner) reportCallStarted(c *C) { - runner.output.WriteCallStarted("START", c) + runner.reporter.StartTest(c) } func (runner *suiteRunner) reportCallDone(c *C) { @@ -861,23 +861,23 @@ func (runner *suiteRunner) reportCallDone(c *C) { switch c.status() { case succeededSt: if c.mustFail { - runner.output.WriteCallSuccess("FAIL EXPECTED", c) + runner.reporter.AddExpectedFailure(c) } else { - runner.output.WriteCallSuccess("PASS", c) + runner.reporter.AddSuccess(c) } case skippedSt: - runner.output.WriteCallSuccess("SKIP", c) + runner.reporter.AddSkip(c) case failedSt: - runner.output.WriteCallProblem("FAIL", c) + runner.reporter.AddFailure(c) case panickedSt: - runner.output.WriteCallProblem("PANIC", c) + runner.reporter.AddError(c) case fixturePanickedSt: // That's a testKd call reporting that its fixture // has panicked. The fixture call which caused the // panic itself was tracked above. We'll report to // aid debugging. - runner.output.WriteCallProblem("PANIC", c) + runner.reporter.AddError(c) case missedSt: - runner.output.WriteCallSuccess("MISS", c) + runner.reporter.AddMissed(c) } } diff --git a/export_test.go b/export_test.go index cf51a99..96127b0 100644 --- a/export_test.go +++ b/export_test.go @@ -2,6 +2,10 @@ package check import "io" +type TestReporter interface { + testReporter +} + func PrintLine(filename string, line int) (string, error) { return printLine(filename, line) } diff --git a/reporter.go b/reporter.go index f963659..3a42ba3 100644 --- a/reporter.go +++ b/reporter.go @@ -6,6 +6,18 @@ import ( "sync" ) +type testReporter interface { + StartTest(*C) + StopTest(*C) + AddFailure(*C) + AddError(*C) + AddUnexpectedSuccess(*C) + AddSuccess(*C) + AddExpectedFailure(*C) + AddSkip(*C) + AddMissed(*C) +} + // ----------------------------------------------------------------------- // Output writer manages atomic output writing according to settings. @@ -20,16 +32,27 @@ func newOutputWriter(writer io.Writer, verbosity uint8) *outputWriter { return &outputWriter{writer: writer, verbosity: verbosity} } -func (ow *outputWriter) WriteCallStarted(label string, c *C) { +func (ow *outputWriter) StartTest(c *C) { if ow.verbosity > 1 { - header := renderCallHeader(label, c, "", "\n") + header := renderCallHeader("START", c, "", "\n") ow.m.Lock() ow.writer.Write([]byte(header)) ow.m.Unlock() } } -func (ow *outputWriter) WriteCallProblem(label string, c *C) { +func (ow *outputWriter) StopTest(c *C) { +} + +func (ow *outputWriter) AddFailure(c *C) { + ow.writeProblem("FAIL", c) +} + +func (ow *outputWriter) AddError(c *C) { + ow.writeProblem("PANIC", c) +} + +func (ow *outputWriter) writeProblem(label string, c *C) { var prefix string if ow.verbosity < 2 { prefix = "\n-----------------------------------" + @@ -45,7 +68,26 @@ func (ow *outputWriter) WriteCallProblem(label string, c *C) { ow.m.Unlock() } -func (ow *outputWriter) WriteCallSuccess(label string, c *C) { +func (ow *outputWriter) AddUnexpectedSuccess(c *C) { +} + +func (ow *outputWriter) AddSuccess(c *C) { + ow.writeSuccess("PASS", c) +} + +func (ow *outputWriter) AddExpectedFailure(c *C) { + ow.writeSuccess("FAIL EXPECTED", c) +} + +func (ow *outputWriter) AddSkip(c *C) { + ow.writeSuccess("SKIP", c) +} + +func (ow *outputWriter) AddMissed(c *C) { + ow.writeSuccess("MISS", c) +} + +func (ow *outputWriter) writeSuccess(label string, c *C) { if ow.verbosity > 1 || (ow.verbosity == 1 && c.kind == testKd) { // TODO Use a buffer here. var suffix string diff --git a/reporter_test.go b/reporter_test.go index 0e1056c..7839935 100644 --- a/reporter_test.go +++ b/reporter_test.go @@ -20,119 +20,154 @@ func (s *reporterS) SetUpSuite(c *C) { s.testFile = filepath.Base(fileName) } -func (s *reporterS) TestWriteCallStartedWithStreamFlag(c *C) { - testLabel := "test started label" +func (s *reporterS) TestStartTestWithHighVerbosity(c *C) { var verbosity uint8 = 2 output := String{} o := NewOutputWriter(&output, verbosity) - o.WriteCallStarted(testLabel, c) - expected := fmt.Sprintf("%s: %s:\\d+: %s\n", testLabel, s.testFile, c.TestName()) + o.StartTest(c) + expected := fmt.Sprintf("START: %s:\\d+: %s\n", s.testFile, c.TestName()) c.Assert(output.value, Matches, expected) } -func (s *reporterS) TestWriteCallStartedWithoutStreamFlag(c *C) { +func (s *reporterS) TestStartTestLowVerbosity(c *C) { var verbosity uint8 = 1 output := String{} - dummyLabel := "dummy" o := NewOutputWriter(&output, verbosity) - o.WriteCallStarted(dummyLabel, c) + o.StartTest(c) c.Assert(output.value, Equals, "") } -func (s *reporterS) TestWriteCallProblemWithStreamFlag(c *C) { - testLabel := "test problem label" - var verbosity uint8 = 2 - output := String{} +var problemTests = []string{"FAIL", "PANIC"} - o := NewOutputWriter(&output, verbosity) +func addProblem(label string, r TestReporter, c *C) { + if label == "FAIL" { + r.AddFailure(c) + } else if label == "PANIC" { + r.AddError(c) + } else { + panic("Unknown problem: " + label) + } +} - o.WriteCallProblem(testLabel, c) - expected := fmt.Sprintf("%s: %s:\\d+: %s\n\n", testLabel, s.testFile, c.TestName()) - c.Assert(output.value, Matches, expected) +func (s *reporterS) TestAddProblemWitHighVerbosity(c *C) { + for _, testLabel := range problemTests { + var verbosity uint8 = 2 + output := String{} + + o := NewOutputWriter(&output, verbosity) + + addProblem(testLabel, o, c) + expected := fmt.Sprintf("%s: %s:\\d+: %s\n\n", testLabel, s.testFile, c.TestName()) + c.Check(output.value, Matches, expected) + } } -func (s *reporterS) TestWriteCallProblemWithoutStreamFlag(c *C) { - testLabel := "test problem label" - var verbosity uint8 = 1 - output := String{} +func (s *reporterS) TestAddProblemWithLowVerbosity(c *C) { + for _, testLabel := range problemTests { + var verbosity uint8 = 1 + output := String{} + + o := NewOutputWriter(&output, verbosity) + + addProblem(testLabel, o, c) + expected := fmt.Sprintf(""+ + "\n"+ + "----------------------------------------------------------------------\n"+ + "%s: %s:\\d+: %s\n\n", testLabel, s.testFile, c.TestName()) + c.Check(output.value, Matches, expected) + } +} - o := NewOutputWriter(&output, verbosity) +func (s *reporterS) TestAddProblemWithLowVerbosityWithLog(c *C) { + for _, testLabel := range problemTests { + testLog := "test log" + var verbosity uint8 = 1 + output := String{} - o.WriteCallProblem(testLabel, c) - expected := fmt.Sprintf(""+ - "\n"+ - "----------------------------------------------------------------------\n"+ - "%s: %s:\\d+: %s\n\n", testLabel, s.testFile, c.TestName()) - c.Assert(output.value, Matches, expected) -} + o := NewOutputWriter(&output, verbosity) -func (s *reporterS) TestWriteCallProblemWithoutStreamFlagWithLog(c *C) { - testLabel := "test problem label" - testLog := "test log" - var verbosity uint8 = 1 - output := String{} + c.Log(testLog) + addProblem(testLabel, o, c) - o := NewOutputWriter(&output, verbosity) + expected := fmt.Sprintf(""+ + "\n"+ + "----------------------------------------------------------------------\n"+ + "%s: %s:\\d+: %s\n\n%s\n", testLabel, s.testFile, c.TestName(), testLog) + c.Check(output.value, Matches, expected) + } +} - c.Log(testLog) - o.WriteCallProblem(testLabel, c) - expected := fmt.Sprintf(""+ - "\n"+ - "----------------------------------------------------------------------\n"+ - "%s: %s:\\d+: %s\n\n%s\n", testLabel, s.testFile, c.TestName(), testLog) - c.Assert(output.value, Matches, expected) +var successTests = []string{"PASS", "SKIP", "FAIL EXPECTED", "MISS"} + +func addSuccess(label string, r TestReporter, c *C) { + if label == "PASS" { + r.AddSuccess(c) + } else if label == "SKIP" { + r.AddSkip(c) + } else if label == "FAIL EXPECTED" { + r.AddExpectedFailure(c) + } else if label == "MISS" { + r.AddMissed(c) + } else { + panic("Unknown success: " + label) + } } -func (s *reporterS) TestWriteCallSuccessWithStreamFlag(c *C) { - testLabel := "test success label" - var verbosity uint8 = 2 - output := String{} +func (s *reporterS) TestAddSuccessWithHighVerbosity(c *C) { + for _, testLabel := range successTests { + var verbosity uint8 = 2 + output := String{} - o := NewOutputWriter(&output, verbosity) + o := NewOutputWriter(&output, verbosity) - o.WriteCallSuccess(testLabel, c) - expected := fmt.Sprintf("%s: %s:\\d+: %s\t\\d\\.\\d+s\n\n", testLabel, s.testFile, c.TestName()) - c.Assert(output.value, Matches, expected) + addSuccess(testLabel, o, c) + expected := fmt.Sprintf("%s: %s:\\d+: %s\t\\d\\.\\d+s\n\n", testLabel, s.testFile, c.TestName()) + c.Check(output.value, Matches, expected) + } } -func (s *reporterS) TestWriteCallSuccessWithStreamFlagAndReason(c *C) { - testLabel := "test success label" - testReason := "test skip reason" - var verbosity uint8 = 2 - output := String{} +func (s *reporterS) TestAddSuccessWithHighVerbosityAndReason(c *C) { + for _, testLabel := range successTests { + testReason := "test skip reason" + var verbosity uint8 = 2 + output := String{} - o := NewOutputWriter(&output, verbosity) - c.FakeSkip(testReason) + o := NewOutputWriter(&output, verbosity) + c.FakeSkip(testReason) - o.WriteCallSuccess(testLabel, c) - expected := fmt.Sprintf("%s: %s:\\d+: %s \\(%s\\)\t\\d\\.\\d+s\n\n", - testLabel, s.testFile, c.TestName(), testReason) - c.Assert(output.value, Matches, expected) + addSuccess(testLabel, o, c) + expected := fmt.Sprintf("%s: %s:\\d+: %s \\(%s\\)\t\\d\\.\\d+s\n\n", + testLabel, s.testFile, c.TestName(), testReason) + c.Check(output.value, Matches, expected) + } } -func (s *reporterS) TestWriteCallSuccessWithoutStreamFlagWithVerboseFlag(c *C) { - testLabel := "test success label" - var verbosity uint8 = 1 - output := String{} +func (s *reporterS) TestAddSuccessWithLowVerbosity(c *C) { + for _, testLabel := range successTests { + var verbosity uint8 = 1 + output := String{} - o := NewOutputWriter(&output, verbosity) + o := NewOutputWriter(&output, verbosity) - o.WriteCallSuccess(testLabel, c) - expected := fmt.Sprintf("%s: %s:\\d+: %s\t\\d\\.\\d+s\n", testLabel, s.testFile, c.TestName()) - c.Assert(output.value, Matches, expected) + addSuccess(testLabel, o, c) + + expected := fmt.Sprintf("%s: %s:\\d+: %s\t\\d\\.\\d+s\n", testLabel, s.testFile, c.TestName()) + c.Check(output.value, Matches, expected) + } } -func (s *reporterS) TestWriteCallSuccessWithoutStreamFlagWithoutVerboseFlag(c *C) { - testLabel := "test success label" - var verbosity uint8 = 0 - output := String{} +func (s *reporterS) TestAddSuccessWithoutVerbosity(c *C) { + for _, testLabel := range successTests { + var verbosity uint8 = 0 + output := String{} - o := NewOutputWriter(&output, verbosity) + o := NewOutputWriter(&output, verbosity) - o.WriteCallSuccess(testLabel, c) - c.Assert(output.value, Equals, "") + addSuccess(testLabel, o, c) + c.Check(output.value, Equals, "") + } }