Search code examples
scalajava-8scalatestnashorn

How to use ScriptEngine in ScalaTest


The following test should pass, but it doesn't

class EngineTest extends FunSuite {

  test("engine should not be null") {
    val manager: ScriptEngineManager = new ScriptEngineManager
    val engine: ScriptEngine = manager.getEngineByName("nashorn")
    assert(engine != null)
  }
}

The manager.getEngineFactories() seems to be empty. Why? How to init the context?


Solution

  • What versions are you using? This is sbt .13.

    > console
    [info] Starting scala interpreter...
    [info] 
    Welcome to Scala version 2.11.0 (OpenJDK 64-Bit Server VM, Java 1.7.0_25).
    Type in expressions to have them evaluated.
    Type :help for more information.
    
    scala> import javax.script._
    import javax.script._
    
    scala> new ScriptEngineManager().getEngineByName("scala")
    res0: javax.script.ScriptEngine = scala.tools.nsc.interpreter.IMain@7078c799
    
    scala> new ScriptEngineManager().getEngineByName("rhino")
    res1: javax.script.ScriptEngine = com.sun.script.javascript.RhinoScriptEngine@5c854934
    
    scala> new ScriptEngineManager().getEngineFactories
    res2: java.util.List[javax.script.ScriptEngineFactory] = [com.sun.script.javascript.RhinoScriptEngineFactory@454ee4c0, scala.tools.nsc.interpreter.IMain$Factory@354e3bce]
    

    Wait, you asked about test context --

    Well, before I lost interest in decoding more sbt, adding to libraryDependencies:

    "org.scala-lang" % "scala-compiler" % scalaVersion.value % "test",
    

    enables locating the Scala script engine:

      @Test def engines: Unit = {
        import javax.script._
        val all = new ScriptEngineManager().getEngineFactories
        Console println s"Found ${all.size}: $all"
        assert(all.size > 0)
      }
    

    No doubt there's a simple way to add runtime:full-classpath to test:full-classpath directly. Because it's the simple build tool, right?

    For Nashorn on Java 8, note the location:

    > set fullClasspath in Test += Attributed.blank(file(s"${util.Properties.javaHome}/lib/ext/nashorn.jar"))
    [info] Defining test:fullClasspath
    [info] The new value will be used by test:console, test:executeTests and 5 others.
    [info]  Run `last` for details.
    [info] Reapplying settings...
    [info] Set current project to goofy (in build file:/home/apm/goofy/)
    > test
    Found 1: [jdk.nashorn.api.scripting.NashornScriptEngineFactory@7fa2239d]
    [info] Passed: Total 10, Failed 0, Errors 0, Passed 10
    

    Update: https://github.com/sbt/sbt/issues/1214

    Also I guess it's still considered black art:

    // Somehow required to get a js engine in tests (https://github.com/sbt/sbt/issues/1214)
    
    fork in Test := true