diff options
author | Som Snytt <som.snytt@gmail.com> | 2015-09-13 17:22:11 -0700 |
---|---|---|
committer | Som Snytt <som.snytt@gmail.com> | 2016-05-19 11:27:02 -0700 |
commit | 3cddeaa525fd6fe9860a27019fdf484297a8d3dd (patch) | |
tree | 76d1bc7142e7f28e6290d25c51c82d2df072ab41 /test/junit | |
parent | 15189d14953335f7a3a8310861d045d21ab22d48 (diff) | |
download | scala-3cddeaa525fd6fe9860a27019fdf484297a8d3dd.tar.gz scala-3cddeaa525fd6fe9860a27019fdf484297a8d3dd.tar.bz2 scala-3cddeaa525fd6fe9860a27019fdf484297a8d3dd.zip |
SI-7916: ScriptEngine support
Refactor the ScriptEngine support to an adaptor atop the
IMain API.
Allow references to resolve to context attributes. (The
attributes must be defined at compilation time, though
they may resolve to updated values at evaluation time.)
This means that attributes are not bound statically in
REPL history. In particular, we forgo the trick of binding
attributes named "name: Type" as typed values.
Instead, an `x` bound in dynamic context is injected into
the script as a dynamic selection `$ctx.x` where `ctx`
performs the look-up in the script context.
When a compiled script is re-evaluated, a new instance of
the script class is created and defined symbols are
rebound.
The context stdout writer is handled with `Console.withOut`,
with bytes decoded using the default charset.
Compilation errors are thrown as ScriptException with the
first reported error.
This commit doesn't attempt dynamic selection from objects
in context. Currently, script must cast.
Diffstat (limited to 'test/junit')
-rw-r--r-- | test/junit/scala/tools/nsc/interpreter/ScriptedTest.scala | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/test/junit/scala/tools/nsc/interpreter/ScriptedTest.scala b/test/junit/scala/tools/nsc/interpreter/ScriptedTest.scala new file mode 100644 index 0000000000..a8dc8eb3e0 --- /dev/null +++ b/test/junit/scala/tools/nsc/interpreter/ScriptedTest.scala @@ -0,0 +1,83 @@ +package scala.tools.nsc +package interpreter + +import org.junit._, Assert._, runner.RunWith, runners.JUnit4 +import scala.tools.testing.AssertUtil.assertThrows + +@RunWith(classOf[JUnit4]) +class ScriptedTest { + import javax.script._ + import scala.tools.nsc.interpreter.Scripted + + def scripted: ScriptEngine with Compilable = Scripted() + // same as by service discovery + //new ScriptEngineManager().getEngineByName("scala").asInstanceOf[ScriptEngine with Compilable] + + @Test def eval() = { + val engine = scripted + engine.put("foo","bar") + assert("bar" == engine.eval("foo")) + val bindings = engine.createBindings() + bindings.put("foo","baz") + assert("baz" == engine.eval("foo", bindings)) + val c = engine.compile("def f = foo.asInstanceOf[String] ; f * 2") + assert("barbar" == c.eval()) + assert("bazbaz" == c.eval(bindings)) + } + @Test def `SI-7933 multiple eval compiled script`() = { + val engine = scripted + val init = """val i = new java.util.concurrent.atomic.AtomicInteger""" + val code = """i.getAndIncrement()""" + engine eval init + val c = engine compile code + assert(0 == c.eval()) + assert(1 == c.eval()) + } + @Test def `SI-8422 captured i/o`() = { + import java.io.StringWriter + val engine = scripted + val ctx = new SimpleScriptContext + val w = new StringWriter + val code = """print("hello, world")""" + + ctx.setWriter(w) + engine.eval(code, ctx) + assertEquals("hello, world", w.toString) + } + @Test def `SI-8422 captured multi i/o`() = { + import java.io.{ StringWriter, StringReader } + import scala.compat.Platform.EOL + val engine = scripted + val ctx = new SimpleScriptContext + val out = new StringWriter + val err = new StringWriter + val text = + """Now is the time + |for all good + |dogs to come for supper.""".stripMargin + val in = new StringReader(text) + + val code = + """var s: String = _ + |var i: Int = 0 + |do { + | s = scala.io.StdIn.readLine() + | val out = if ((i & 1) == 0) Console.out else Console.err + | i += 1 + | Option(s) foreach out.println + |} while (s != null)""".stripMargin + + ctx.setWriter(out) + ctx.setErrorWriter(err) + ctx.setReader(in) + engine.eval(code, ctx) + val lines = text.lines.toList + assertEquals(lines.head + EOL + lines.last + EOL, out.toString) + assertEquals(lines(1) + EOL, err.toString) + } + @Test def `on compile error`(): Unit = { + val engine = scripted + val err = "not found: value foo in def f = foo at line number 11 at column number 16" + assertThrows[ScriptException](engine.compile("def f = foo"), _ == err) + } +} |