From f15c3259ed6c55613c00e49f76473900c4541766 Mon Sep 17 00:00:00 2001 From: Manish Khettry Date: Sun, 22 Apr 2012 15:37:44 -0700 Subject: [PATCH 1/1] initial commit for sbt-tap plugin --- .gitignore | 1 + README | 1 + build.sbt | 7 ++++ src/main/scala/SbtTapReporting.scala | 61 ++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+) create mode 100644 .gitignore create mode 100644 README create mode 100644 build.sbt create mode 100644 src/main/scala/SbtTapReporting.scala diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e420ee4 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +target/* diff --git a/README b/README new file mode 100644 index 0000000..ebed61e --- /dev/null +++ b/README @@ -0,0 +1 @@ +Sbt plugin to generate results in tap format. diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..31326f4 --- /dev/null +++ b/build.sbt @@ -0,0 +1,7 @@ +sbtPlugin := true + +name := "sbt-tap-plugin2" + +version := "0.1" + + diff --git a/src/main/scala/SbtTapReporting.scala b/src/main/scala/SbtTapReporting.scala new file mode 100644 index 0000000..50035af --- /dev/null +++ b/src/main/scala/SbtTapReporting.scala @@ -0,0 +1,61 @@ +package sbttap + +import sbt._ +import org.scalatools.testing.{Event => TEvent, Result => TResult} + +import Keys._ +import java.util.concurrent.atomic.AtomicInteger +import io.Source +import java.io.{File, FileWriter, PrintWriter, StringWriter} + +object SbtTapReporting extends Plugin { + override def settings = Seq( + testListeners ++= Seq(new SbtTapListener) + ) +} + +/** + * Listens to sbt test listener events and writes them to a tap compatible file. Results for all groups + * go to a single file although it might be desirable to generate one tap file per group. + *

+ * sbt runs tests in parallel and the protocol does not seem to provide a way to match a group to a test event. It + * does look line one thread calls startGroup/testEvent/endGroup sequentially and using thread local to keep + * the current active group might be one way to go. + */ +class SbtTapListener extends TestsListener { + var testId = new AtomicInteger(0) + var fileWriter: FileWriter = _ + + override def doInit { + new File("test-results").mkdirs() + + fileWriter = new FileWriter("test-results/test.tap") + } + + def startGroup(name: String) {} + + def testEvent(event: TestEvent) { + event.detail.foreach { e: TEvent => + 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.Skipped => + // it doesn't look like this framework distinguishes between pending and ignored. + writeTapFields("ok", testId.incrementAndGet(), "#", "skip", e.testName()) + } + } + } + + override def doComplete(finalResult: TestResult.Value) { + writeTapFields("1.." + testId.get) + fileWriter.close() + } + + private def writeTapFields(s: Any*) { fileWriter.write(s.mkString("", " ", "\n")) } + + def endGroup(name: String, t: Throwable) { } + + def endGroup(name: String, result: TestResult.Value) { } +} -- 2.45.2