scala.jsutest

How do I test scala.js programs for side-effects that happen asynchronously using µtest?


I have a µtest suite that needs to check that some asynchronous operation eventually has a side effect. Since javascript (and thus scala.js) is single threadded, it is not possible to block and wait for the side effect to happen. Also, the µtest eventually method does not work on javascript runtime. How do I perform such a test?


Solution

  • If you return a Future from a µtest, then the test will pass if the future succeeds and fail if the future fails. Thus, you can schedule the conditional check for some point in the future without blocking.

    I wrote a simple eventually method that accomplishes this:

    package utest
    
    import rx.ops.DomScheduler
    
    import scala.concurrent.{Promise, Future}
    import scala.concurrent.duration.FiniteDuration
    import scala.util.{Failure, Success, Try}
    
    object JsOps {
      import scala.concurrent.ExecutionContext.Implicits.global
      val scheduler = new DomScheduler
    
      def eventually(eval: => Try[Boolean])(implicit timeout: FiniteDuration): Future[Boolean] = {
        val p = Promise[Boolean]()
        scheduler.scheduleOnce(timeout) {
          eval match {
            case Success(b) => p.success(b)
            case Failure(t) => p.failure(t)
          }
        }
        p.future
      }
    }
    

    Here is an example of usage:

      import scala.concurrent.duration._
      implicit val timeout = 30.milliseconds
    
      eventually {
        if (/*condition holds true*/) {
          Success(true)
        } else Failure(new RuntimeException(/*error message*/))
      }