summaryrefslogtreecommitdiff
path: root/examples/scala-js/test-bridge/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'examples/scala-js/test-bridge/src/main')
-rw-r--r--examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/Test.scala17
-rw-r--r--examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/TestFramework.scala36
-rw-r--r--examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/TestOutput.scala34
-rw-r--r--examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/TestOutputLog.scala16
-rw-r--r--examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/internal/ConsoleTestOutput.scala118
5 files changed, 221 insertions, 0 deletions
diff --git a/examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/Test.scala b/examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/Test.scala
new file mode 100644
index 0000000..05d3077
--- /dev/null
+++ b/examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/Test.scala
@@ -0,0 +1,17 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.testbridge
+
+import scala.scalajs.js
+import js.annotation.JSExportDescendentObjects
+
+/** Marker trait for Scala.js tests */
+@JSExportDescendentObjects
+trait Test
diff --git a/examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/TestFramework.scala b/examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/TestFramework.scala
new file mode 100644
index 0000000..f855cf6
--- /dev/null
+++ b/examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/TestFramework.scala
@@ -0,0 +1,36 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.testbridge
+
+import scala.scalajs.js
+import js.annotation.{ JSExportDescendentObjects, JSExport }
+
+/** This trait should be sub classed (as object) by a concrete test framework
+ *
+ * It will receive a call to runTest for each object on the classpath
+ * extending Test
+ */
+@JSExportDescendentObjects
+trait TestFramework {
+ @JSExport
+ final def safeRunTest(testOutput: TestOutput, args: js.Array[String])(
+ test: js.Function0[Test]): Unit = {
+ try {
+ runTest(testOutput, args)(test)
+ } catch {
+ case e: Throwable =>
+ testOutput.error(s"Test framework ${getClass.getName} failed:")
+ testOutput.error(e.getMessage, e.getStackTrace)
+ }
+ }
+
+ def runTest(testOutput: TestOutput, args: js.Array[String])(
+ test: js.Function0[Test]): Unit
+}
diff --git a/examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/TestOutput.scala b/examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/TestOutput.scala
new file mode 100644
index 0000000..5f3b8b6
--- /dev/null
+++ b/examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/TestOutput.scala
@@ -0,0 +1,34 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.testbridge
+
+trait TestOutput {
+
+ type Color
+
+ val errorColor: Color
+ val successColor: Color
+ val infoColor: Color
+
+ def color(message: String, color: Color): String
+
+ def error(message: String, stack: Array[StackTraceElement]): Unit
+ def error(message: String): Unit
+ def failure(message: String, stack: Array[StackTraceElement]): Unit
+ def failure(message: String): Unit
+ def succeeded(message: String): Unit
+ def skipped(message: String): Unit
+ def pending(message: String): Unit
+ def ignored(message: String): Unit
+ def canceled(message: String): Unit
+
+ def log: TestOutputLog
+
+}
diff --git a/examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/TestOutputLog.scala b/examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/TestOutputLog.scala
new file mode 100644
index 0000000..3369592
--- /dev/null
+++ b/examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/TestOutputLog.scala
@@ -0,0 +1,16 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.testbridge
+
+trait TestOutputLog {
+ def info(message: String): Unit
+ def warn(message: String): Unit
+ def error(message: String): Unit
+}
diff --git a/examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/internal/ConsoleTestOutput.scala b/examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/internal/ConsoleTestOutput.scala
new file mode 100644
index 0000000..c89a32e
--- /dev/null
+++ b/examples/scala-js/test-bridge/src/main/scala/scala/scalajs/testbridge/internal/ConsoleTestOutput.scala
@@ -0,0 +1,118 @@
+package scala.scalajs.testbridge.internal
+
+import scala.scalajs.js
+import scala.scalajs.js.annotation.JSExport
+
+import scala.scalajs.testbridge._
+
+import scala.scalajs.runtime.StackTrace.ColumnStackTraceElement
+
+/** Implementation of TestOutput.
+ *
+ * Attention: This class monkey-patches console.log. Make sure it is loaded
+ * before any output. It also should always be paired with a
+ * [[scala.scalajs.sbtplugin.testing.TestOutputConsole]] on the JVM side.
+ */
+@JSExport
+protected object ConsoleTestOutput extends TestOutput {
+
+ /** monkey-patches console.log when class is loaded */
+ private val savedConsoleLog: js.Function1[String, Unit] = {
+ import js.Dynamic.{ global => g }
+
+ val console = g.console
+ val savedLog = console.log
+
+ val patch = (new MonkeyPatchConsole).asInstanceOf[js.Dynamic]
+
+ // Need to write updateDynamic explicitly here. Since 2.10.x
+ // chokes on this ("erroneous or inaccessible type")
+ console.updateDynamic("log")(patch.log.bind(patch))
+
+ savedLog.bind(console).asInstanceOf[js.Function1[String, Unit]]
+ }
+
+ type Color = String
+
+ val errorColor = "\u001b[31m"
+ val successColor = "\u001b[32m"
+ val infoColor = "\u001b[34m"
+
+ private val reset = "\u001b[0m"
+
+ def color(message: String, color: String): String =
+ message.split('\n').mkString(color, reset + '\n' + color, reset)
+
+ def error(message: String,
+ stack: Array[StackTraceElement]): Unit = {
+ sendTrace(stack)
+ send("error", message)
+ }
+
+ def error(message: String): Unit =
+ error(message, Array.empty)
+
+ def failure(message: String,
+ stack: Array[StackTraceElement]): Unit = {
+ sendTrace(stack)
+ send("failure", message)
+ }
+
+ def failure(message: String): Unit =
+ failure(message, Array.empty)
+
+ def succeeded(message: String): Unit =
+ send("succeeded", message)
+
+ def skipped(message: String): Unit =
+ send("skipped", message)
+
+ def pending(message: String): Unit =
+ send("pending", message)
+
+ def ignored(message: String): Unit =
+ send("ignored", message)
+
+ def canceled(message: String): Unit =
+ send("canceled", message)
+
+ val log =
+ new TestOutputLog {
+ def info(message: String): Unit = send("info", message)
+ def warn(message: String): Unit = send("warn", message)
+ def error(message: String): Unit = send("error-log", message)
+ }
+
+ private def send(fct: String, msg: String) = {
+ val escaped = msg
+ .replace("\\", "\\\\")
+ .replace("\n", "\\n")
+ .replace("\r", "\\r")
+ savedConsoleLog(fct + "|" + escaped)
+ }
+
+ private def sendTrace(stack: Array[StackTraceElement]) = for {
+ el <- stack
+ } send("trace", serializeStackElem(el))
+
+ private def serializeStackElem(e: StackTraceElement) = {
+
+ val flds = List(
+ e.getClassName,
+ e.getMethodName,
+ e.getFileName,
+ e.getLineNumber.toString,
+ e.getColumnNumber.toString)
+
+ flds.mkString("|")
+ }
+
+ /** used to monkey-patch console (only log will be used)
+ * we can't write a simple lambda, because we need varargs
+ */
+ private class MonkeyPatchConsole {
+ @JSExport
+ def log(msg: js.Any*): Unit = send("console-log", msg.mkString(" "))
+ }
+
+}