All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.scalajs.sbttestadapter.ScalaJSTask.scala Maven / Gradle / Ivy

The newest version!
/*                     __                                               *\
**     ________ ___   / /  ___      __ ____  Scala.js sbt plugin        **
**    / __/ __// _ | / /  / _ | __ / // __/  (c) 2013, LAMP/EPFL        **
**  __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \    http://scala-js.org/       **
** /____/\___/_/ |_/____/_/ | |__/ /____/                               **
**                          |/____/                                     **
\*                                                                      */


package org.scalajs.testadapter

import org.scalajs.core.tools.json._

import org.scalajs.jsenv._

import scala.collection.mutable

import sbt.testing._

import TaskDefSerializers._
import EventSerializers._
import ComUtils.LoopHandler
import ScalaJSTask.LogElement

final class ScalaJSTask private (
    runner: ScalaJSRunner,
    val taskDef: TaskDef,
    val tags: Array[String],
    serializedTask: String
) extends Task {

  def execute(handler: EventHandler, loggers: Array[Logger]): Array[Task] = {
    val slave = runner.getSlave()

    // Prepare data to send to Slave VM
    val colorSupport = loggers.map(_.ansiCodesSupported).toList
    val data = {
      val bld = new JSONObjBuilder
      bld.fld("serializedTask", serializedTask)
      bld.fld("loggerColorSupport", colorSupport)
      bld.toJSON
    }

    // Send command to VM
    slave.send("execute:" + jsonToString(data))

    // Prepare result handler
    val logBuffer = mutable.Buffer.empty[LogElement[_]]

    val doneHandler: LoopHandler[List[TaskInfo]] = {
      case ("ok", msg) => Some(fromJSON[List[TaskInfo]](readJSON(msg)))
    }

    val handlerChain = (
        eventHandler(handler) orElse
        loggerHandler(logBuffer) orElse
        runner.msgHandler(slave) orElse
        doneHandler)

    // Wait for result
    val taskInfos = ComUtils.receiveLoop(slave)(handlerChain)

    // Flush log buffer
    runner.loggerLock.synchronized {
      logBuffer.foreach(_.call(loggers))
    }

    taskInfos.map(ScalaJSTask.fromInfo(runner, _)).toArray
  }

  private def eventHandler(handler: EventHandler): LoopHandler[Nothing] = {
    case ("event", data) =>
      val event = fromJSON[Event](readJSON(data))
      handler.handle(event)
      None
  }

  private def loggerHandler(
      buf: mutable.Buffer[LogElement[_]]): LoopHandler[Nothing] = {

    def processData(data: String) = {
      val pos = data.indexOf(':')
      assert(pos != -1, "Log command needs logger index")
      val index = data.substring(0, pos).toInt
      val innerData = data.substring(pos + 1)

      (index, innerData)
    }

    def log(level: Logger => (String => Unit), data: String) = {
      val (index, msg) = processData(data)
      buf += new LogElement(index, level, msg)
      None
    }

    val pf: LoopHandler[Nothing] = {
      case ("error", data) => log(_.error, data)
      case ("warn",  data) => log(_.warn,  data)
      case ("info",  data) => log(_.info,  data)
      case ("debug", data) => log(_.debug, data)
      case ("trace", data) =>
        val (index, innerData) = processData(data)
        val throwable = fromJSON[RemoteException](readJSON(innerData))
        buf += new LogElement(index, _.trace, throwable)
        None
    }

    pf
  }

}

object ScalaJSTask {
  private final class LogElement[T](index: Int,
      log: Logger => (T => Unit), data: T) {
    def call(arr: Array[Logger]): Unit = log(arr(index))(data)
  }

  private[testadapter] def fromInfo(runner: ScalaJSRunner,
      info: TaskInfo): ScalaJSTask =
    new ScalaJSTask(runner, info.taskDef, info.tags, info.serializedTask)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy