From 06c1c7855510ce31e43356407b95979e1e3813f1 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Thu, 5 Sep 2013 22:15:46 -0700 Subject: SI-7805 REPL -i startup Tested with a ReplTest that loads an include script. ReplTests can choose to be `Welcoming` and keep a normalized welcome message in their check transcript. One recent SessionTest is updated to use the normalizing API. --- .../scala/tools/partest/ReplTest.scala | 24 +++++++++++-- src/repl/scala/tools/nsc/interpreter/ILoop.scala | 2 +- test/files/run/repl-trim-stack-trace.scala | 11 +++--- test/files/run/t7805-repl-i.check | 11 ++++++ test/files/run/t7805-repl-i.scala | 42 ++++++++++++++++++++++ test/files/run/t7805-repl-i.script | 1 + 6 files changed, 82 insertions(+), 9 deletions(-) create mode 100644 test/files/run/t7805-repl-i.check create mode 100644 test/files/run/t7805-repl-i.scala create mode 100644 test/files/run/t7805-repl-i.script diff --git a/src/partest-extras/scala/tools/partest/ReplTest.scala b/src/partest-extras/scala/tools/partest/ReplTest.scala index 38662c34b5..a728e8bdef 100644 --- a/src/partest-extras/scala/tools/partest/ReplTest.scala +++ b/src/partest-extras/scala/tools/partest/ReplTest.scala @@ -9,8 +9,8 @@ import scala.tools.nsc.Settings import scala.tools.nsc.interpreter.ILoop import java.lang.reflect.{ Method => JMethod, Field => JField } -/** A trait for testing repl code. It drops the first line - * of output because the real repl prints a version number. +/** A class for testing repl code. + * It filters the line of output that mentions a version number. */ abstract class ReplTest extends DirectTest { // override to transform Settings object immediately before the finish @@ -22,14 +22,32 @@ abstract class ReplTest extends DirectTest { s.Xnojline.value = true transformSettings(s) } + def welcoming: Boolean = false + lazy val welcome = "(Welcome to Scala) version .*".r + def normalize(s: String) = s match { + case welcome(w) => w + case s => s + } + def unwelcoming(s: String) = s match { + case welcome(w) => false + case _ => true + } def eval() = { val s = settings log("eval(): settings = " + s) - ILoop.runForTranscript(code, s).lines drop 1 + //ILoop.runForTranscript(code, s).lines drop 1 // not always first line + val lines = ILoop.runForTranscript(code, s).lines + if (welcoming) lines map normalize + else lines filter unwelcoming } def show() = eval() foreach println } +/** Retain and normalize the welcome message. */ +trait Welcoming { this: ReplTest => + override def welcoming = true +} + /** Run a REPL test from a session transcript. * The `session` should be a triple-quoted String starting * with the `Type in expressions` message and ending diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala index a623ee5055..ed56016bce 100644 --- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala @@ -854,9 +854,9 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) globalFuture = future { intp.initializeSynchronous() loopPostInit() - loadFiles(settings) !intp.reporter.hasErrors } + loadFiles(settings) printWelcome() try loop() diff --git a/test/files/run/repl-trim-stack-trace.scala b/test/files/run/repl-trim-stack-trace.scala index 0f4a43bc85..70ee8e1840 100644 --- a/test/files/run/repl-trim-stack-trace.scala +++ b/test/files/run/repl-trim-stack-trace.scala @@ -1,10 +1,11 @@ -import scala.tools.partest.SessionTest +import scala.tools.partest.{ SessionTest, Welcoming } // SI-7740 -object Test extends SessionTest { +object Test extends SessionTest with Welcoming { def session = -"""Type in expressions to have them evaluated. +"""Welcome to Scala +Type in expressions to have them evaluated. Type :help for more information. scala> def f = throw new Exception("Uh-oh") @@ -35,10 +36,10 @@ scala> """ // normalize the "elided" lines because the frame count depends on test context lazy val elided = """(\s+\.{3} )\d+( elided)""".r - def normalize(line: String) = line match { + override def normalize(line: String) = line match { + case welcome(w) => w case elided(ellipsis, suffix) => s"$ellipsis???$suffix" case s => s } - override def eval() = super.eval() map normalize override def expected = super.expected map normalize } diff --git a/test/files/run/t7805-repl-i.check b/test/files/run/t7805-repl-i.check new file mode 100644 index 0000000000..eecfff079a --- /dev/null +++ b/test/files/run/t7805-repl-i.check @@ -0,0 +1,11 @@ +Loading t7805-repl-i.script... +import util._ + +Welcome to Scala +Type in expressions to have them evaluated. +Type :help for more information. + +scala> Console println Try(8) +Success(8) + +scala> diff --git a/test/files/run/t7805-repl-i.scala b/test/files/run/t7805-repl-i.scala new file mode 100644 index 0000000000..a4061689f0 --- /dev/null +++ b/test/files/run/t7805-repl-i.scala @@ -0,0 +1,42 @@ + +import scala.tools.partest.{ ReplTest, Welcoming } +import scala.tools.nsc.{ GenericRunnerSettings, Settings } +import scala.tools.nsc.settings.MutableSettings + +object Test extends ReplTest with HangingRepl with Welcoming { + def script = testPath changeExtension "script" + override def transformSettings(s: Settings) = s match { + case m: MutableSettings => + val t = new GenericRunnerSettings(s.errorFn) + m copyInto t + t processArgumentString s"-i $script" + t + case _ => s + } + def code = "Console println Try(8)" +} + +object Resulting { + import scala.concurrent._ + import scala.concurrent.duration._ + implicit class AwaitResult[A](val f: Future[A]) extends AnyVal { + def resultWithin(d: Duration): A = Await.result(f, d) + } +} + +/** Test that hangs the REPL. + * Usually that is the "before" case. + */ +trait HangingRepl extends ReplTest { + import scala.language.postfixOps + import scala.util._ + import scala.concurrent._ + import scala.concurrent.duration._ + import ExecutionContext.Implicits._ + import Resulting._ + def timeout = 15 seconds + def hanging[A](a: =>A): A = future(a) resultWithin timeout + override def show() = Try(hanging(super.show())) recover { + case e => e.printStackTrace() + } +} diff --git a/test/files/run/t7805-repl-i.script b/test/files/run/t7805-repl-i.script new file mode 100644 index 0000000000..eb2b8705f3 --- /dev/null +++ b/test/files/run/t7805-repl-i.script @@ -0,0 +1 @@ +import util._ -- cgit v1.2.3