]> Dogcows Code - chaz/sbt-tap/blobdiff - src/main/scala/SbtTapReporting.scala
update tap protocol version to 13
[chaz/sbt-tap] / src / main / scala / SbtTapReporting.scala
index 20d8b7c9d1cedb479bd825fd5e9a4cb0652ae65a..20b1130bbeab5ff6e9bda4f6b418bcb4a2183217 100644 (file)
@@ -1,11 +1,11 @@
+import java.io.{PrintWriter, StringWriter, File, FileWriter}
 import sbt._
 import org.scalatools.testing.{Event => TEvent, Result => TResult}
 
 import java.util.concurrent.atomic.AtomicInteger
-import java.io.{File, FileWriter}
 
 object SbtTapReporting extends Plugin {
-  lazy val tapListener = new SbtTapListener
+  def apply() = new SbtTapListener
 }
 
 /**
@@ -20,37 +20,58 @@ class SbtTapListener extends TestsListener {
   var testId = new AtomicInteger(0)
   var fileWriter: FileWriter = _
 
-  override def doInit {
-    println("doInit called in sbt tap plugin")
-    new File("test-results").mkdirs()
-
-    fileWriter = new FileWriter("test-results/test.tap")
+  override def doInit = {
+    val filename = scala.util.Properties.envOrElse("SBT_TAP_OUTPUT", "test-results/test.tap")
+    val file = new File(filename)
+    new File(file.getParent).mkdirs
+    fileWriter = new FileWriter(file)
+    writeTap("TAP", "version", 13)
   }
 
-  def startGroup(name: String) {}
+  def startGroup(name: String) =
+    writeTapDiag("start", name)
+
+  def endGroup(name: String, result: TestResult.Value) =
+    writeTapDiag("end", name, "with result", result.toString.toLowerCase)
+
+  def endGroup(name: String, t: Throwable) = {
+    writeTapDiag("end", name)
+    writeTapDiag(stackTraceForError(t))
+  }
 
-  def testEvent(event: TestEvent) {
+  def testEvent(event: TestEvent) {
     event.detail.foreach { e: TEvent =>
+      val description = e.testName.replaceAll("#", "%23")
       e.result match {
-        case TResult.Success => writeTapFields("ok", testId.incrementAndGet(), "-", e.testName())
-        case TResult.Error | TResult.Failure =>
-          writeTapFields("not ok", testId.incrementAndGet(), "-", e.testName())
-          // TODO: for exceptions, write stack trace to tap file.
+        case TResult.Success =>
+          writeTap("ok", testId.incrementAndGet, "-", description)
         case TResult.Skipped =>
-          // it doesn't look like this framework distinguishes between pending and ignored.
-          writeTapFields("ok", testId.incrementAndGet(), "#", "skip", e.testName())
+          writeTap("ok", testId.incrementAndGet, "-", description, "# SKIP")
+        case TResult.Error | TResult.Failure =>
+          writeTap("not ok", testId.incrementAndGet, "-", description)
+          // TODO: It would be nice if we could report the exact line in the test where this happened.
+          writeTapDiag(stackTraceForError(e.error))
       }
     }
   }
 
-  override def doComplete(finalResult: TestResult.Value) {
-    writeTapFields("1.." + testId.get)
-    fileWriter.close()
+  override def doComplete(finalResult: TestResult.Value) {
+    writeTap("1.." + testId.get)
+    fileWriter.close
   }
 
-  private def writeTapFields(s: Any*) { fileWriter.write(s.mkString("",  " ", "\n")) }
+  private def writeTap(s: Any*) = {
+    fileWriter.write(s.mkString("", " ", "\n"))
+    fileWriter.flush
+  }
 
-  def endGroup(name: String, t: Throwable) { }
+  private def writeTapDiag(s: Any*) =
+    writeTap("#", s.mkString("", " ", "\n").trim.replaceAll("\\n", "\n# "))
 
-  def endGroup(name: String, result: TestResult.Value) { }
+  private def stackTraceForError(t: Throwable): String = {
+    val sw = new StringWriter
+    val printWriter = new PrintWriter(sw)
+    t.printStackTrace(printWriter)
+    sw.toString
+  }
 }
This page took 0.026628 seconds and 4 git commands to generate.