@@ -8,6 +8,7 @@ package scala.tools.partest
88import scala .tools .nsc .Settings
99import scala .tools .nsc .interpreter .ILoop
1010import java .lang .reflect .{ Method => JMethod , Field => JField }
11+ import scala .util .matching .Regex .Match
1112
1213/** A class for testing repl code.
1314 * It filters the line of output that mentions a version number.
@@ -22,6 +23,9 @@ abstract class ReplTest extends DirectTest {
2223 s.Xnojline .value = true
2324 transformSettings(s)
2425 }
26+ /** True for SessionTest to preserve session text. */
27+ def inSession : Boolean = false
28+ /** True to preserve welcome text. */
2529 def welcoming : Boolean = false
2630 lazy val welcome = " (Welcome to Scala) version .*" .r
2731 def normalize (s : String ) = s match {
@@ -36,7 +40,7 @@ abstract class ReplTest extends DirectTest {
3640 val s = settings
3741 log(" eval(): settings = " + s)
3842 // ILoop.runForTranscript(code, s).lines drop 1 // not always first line
39- val lines = ILoop .runForTranscript(code, s).lines
43+ val lines = ILoop .runForTranscript(code, s, inSession = inSession ).lines
4044 if (welcoming) lines map normalize
4145 else lines filter unwelcoming
4246 }
@@ -57,13 +61,30 @@ abstract class SessionTest extends ReplTest {
5761 /** Session transcript, as a triple-quoted, multiline, marginalized string. */
5862 def session : String
5963
60- /** Expected output, as an iterator. */
61- def expected = session.stripMargin.lines
64+ /** Expected output, as an iterator, optionally marginally stripped. */
65+ def expected = if (stripMargins) session.stripMargin.lines else session.lines
66+
67+ /** Override with false if we should not strip margins because of leading continuation lines. */
68+ def stripMargins : Boolean = true
69+
70+ /** Analogous to stripMargins, don't mangle continuation lines on echo. */
71+ override def inSession : Boolean = true
6272
6373 /** Code is the command list culled from the session (or the expected session output).
64- * Would be nicer if code were lazy lines.
74+ * Would be nicer if code were lazy lines so you could generate arbitrarily long text.
75+ * Retain user input: prompt lines and continuations, without the prefix; or pasted text plus ctl-D.
6576 */
66- override final def code = expected filter (_ startsWith prompt) map (_ drop prompt.length) mkString " \n "
77+ import SessionTest ._
78+ override final def code = input findAllMatchIn (expected mkString (" " , " \n " , " \n " )) map {
79+ case input(null , null , prompted) =>
80+ def continued (m : Match ): Option [String ] = m match {
81+ case margin(text) => Some (text)
82+ case _ => None
83+ }
84+ margin.replaceSomeIn(prompted, continued)
85+ case input(cmd, pasted, null ) =>
86+ cmd + pasted + " \u0004 "
87+ } mkString
6788
6889 final def prompt = " scala> "
6990
@@ -75,3 +96,9 @@ abstract class SessionTest extends ReplTest {
7596 if (evaled != wanted) Console print nest.FileManager .compareContents(wanted, evaled, " expected" , " actual" )
7697 }
7798}
99+ object SessionTest {
100+ // \R for line break is Java 8, \v for vertical space might suffice
101+ val input = """ (?m)^scala> (:pa.*\u000A )// Entering paste mode.*\u000A\u000A ((?:.*\u000A )*)\u000A // Exiting paste mode.*\u000A |^scala> (.*\u000A (?:\s*\| .*\u000A )*)""" .r
102+
103+ val margin = """ (?m)^\s*\| (.*)$""" .r
104+ }
0 commit comments