Skip to content

Commit c4bba82

Browse files
committed
Migrate Ammonite REPL tests to Scala 3 REPL
1 parent 514ea74 commit c4bba82

File tree

2 files changed

+167
-8
lines changed

2 files changed

+167
-8
lines changed

modules/integration/src/test/scala/scala/cli/integration/ReplAmmoniteTestDefinitions.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import com.eed3si9n.expecty.Expecty.expect
55
import scala.cli.integration.TestUtil.{normalizeArgsForWindows, removeAnsiColors}
66

77
trait ReplAmmoniteTestDefinitions { this: ReplTestDefinitions =>
8-
protected val ammonitePrefix: String = "Ammonite REPL:"
8+
protected val ammonitePrefix: String = "Running in Ammonite REPL:"
99
def expectedScalaVersionForAmmonite: String =
1010
actualScalaVersion match {
1111
case s

modules/integration/src/test/scala/scala/cli/integration/ReplTestDefinitions.scala

Lines changed: 166 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,39 @@ abstract class ReplTestDefinitions extends ScalaCliSuite with TestScalaVersionAr
1515
actualScalaVersion.coursierVersion >= "3.7.0-RC1".coursierVersion
1616

1717
protected val dryRunPrefix: String = "Dry run:"
18-
protected val runInReplPrefix: String = "Running in REPL:"
18+
protected val runInReplPrefix: String = "Running in Scala REPL:"
1919

2020
def runInRepl(
2121
codeToRunInRepl: String,
22-
testInputs: TestInputs = TestInputs.empty
23-
)(f: os.CommandResult => Unit): Unit = {
22+
testInputs: TestInputs = TestInputs.empty,
23+
cliOptions: Seq[String] = Seq.empty,
24+
shouldPipeStdErr: Boolean = false,
25+
check: Boolean = true,
26+
env: Map[String, String] = Map.empty
27+
)(
28+
runAfterRepl: os.CommandResult => Unit,
29+
runBeforeReplAndGetExtraCliOpts: () => Seq[os.Shellable] = () => Seq.empty
30+
): Unit = {
2431
testInputs.fromRoot { root =>
25-
f(
32+
val potentiallyExtraCliOpts = runBeforeReplAndGetExtraCliOpts()
33+
runAfterRepl(
2634
os.proc(
2735
TestUtil.cli,
2836
"repl",
37+
".",
2938
"--repl-quit-after-init",
3039
"--repl-init-script",
3140
codeToRunInRepl,
32-
extraOptions
41+
extraOptions,
42+
cliOptions,
43+
potentiallyExtraCliOpts
3344
)
34-
.call(cwd = root)
45+
.call(
46+
cwd = root,
47+
stderr = if shouldPipeStdErr then os.Pipe else os.Inherit,
48+
env = env,
49+
check = check
50+
)
3551
)
3652
}
3753
}
@@ -114,11 +130,154 @@ abstract class ReplTestDefinitions extends ScalaCliSuite with TestScalaVersionAr
114130
expect(output.contains("typer"))
115131
}
116132

117-
if canRunInRepl then
133+
if canRunInRepl then {
118134
test(s"$runInReplPrefix simple") {
119135
val expectedMessage = "1337"
120136
runInRepl(s"""println($expectedMessage)""")(r =>
121137
expect(r.out.trim() == expectedMessage)
122138
)
123139
}
140+
141+
test(s"$runInReplPrefix verify Scala version from the REPL") {
142+
val opts = if actualScalaVersion.startsWith("3") && !isScala38OrNewer then
143+
Seq("--with-compiler")
144+
else Seq.empty
145+
runInRepl(
146+
codeToRunInRepl = s"""println($retrieveScalaVersionCode)""",
147+
cliOptions = opts
148+
)(r => expect(r.out.trim() == actualScalaVersion))
149+
}
150+
151+
test(s"$runInReplPrefix test scope") {
152+
val message = "something something something REPL"
153+
runInRepl(
154+
codeToRunInRepl = "println(example.TestScopeExample.message)",
155+
testInputs = TestInputs(
156+
os.rel / "example" / "TestScopeExample.test.scala" ->
157+
s"""package example
158+
|
159+
|object TestScopeExample {
160+
| def message: String = "$message"
161+
|}
162+
|""".stripMargin
163+
),
164+
cliOptions = Seq("--test")
165+
)(r => expect(r.out.trim() == message))
166+
}
167+
168+
test(s"$runInReplPrefix ScalaPy") {
169+
val opts =
170+
if actualScalaVersion.startsWith("3") && !isScala38OrNewer then Seq("--with-compiler")
171+
else Seq.empty
172+
runInRepl(
173+
codeToRunInRepl =
174+
s"""import me.shadaj.scalapy.py
175+
|println("Hello" + " from Scala " + $retrieveScalaVersionCode)
176+
|val sth = py.module("foo.something")
177+
|py.Dynamic.global.applyDynamicNamed("print")("" -> sth.messageStart, "" -> sth.messageEnd, "flush" -> py.Any.from(true))
178+
|""".stripMargin,
179+
testInputs = TestInputs(
180+
os.rel / "foo" / "something.py" ->
181+
"""messageStart = 'Hello from'
182+
|messageEnd = 'ScalaPy'
183+
|""".stripMargin
184+
),
185+
cliOptions = Seq("--python", "--power") ++ opts,
186+
shouldPipeStdErr = true
187+
) { res =>
188+
val output = res.out.trim().linesIterator.toVector.take(2).mkString("\n")
189+
expect(output == s"""Hello from Scala $actualScalaVersion
190+
|Hello from ScalaPy""".stripMargin)
191+
}
192+
}
193+
194+
test(s"$runInReplPrefix ScalaPy with PYTHONSAFEPATH") {
195+
val opts =
196+
if actualScalaVersion.startsWith("3") && !isScala38OrNewer then Seq("--with-compiler")
197+
else Seq.empty
198+
runInRepl(
199+
codeToRunInRepl =
200+
s"""import me.shadaj.scalapy.py
201+
|println("Hello" + " from Scala " + $retrieveScalaVersionCode)
202+
|val sth = py.module("foo.something")
203+
|py.Dynamic.global.applyDynamicNamed("print")("" -> sth.messageStart, "" -> sth.messageEnd, "flush" -> py.Any.from(true))
204+
|""".stripMargin,
205+
testInputs = TestInputs(
206+
os.rel / "foo" / "something.py" ->
207+
"""messageStart = 'Hello from'
208+
|messageEnd = 'ScalaPy'
209+
|""".stripMargin
210+
),
211+
cliOptions = Seq("--python", "--power") ++ opts,
212+
shouldPipeStdErr = true,
213+
// check = false, // technically should be an error, but the REPL itself doesn't return it as such.
214+
env = Map("PYTHONSAFEPATH" -> "foo")
215+
) { errorRes =>
216+
// expect(errorRes.exitCode != 0) // technically should be an error, but the REPL itself doesn't return it as such.
217+
val errorOutput = TestUtil.removeAnsiColors(errorRes.err.trim() + errorRes.out.trim())
218+
expect(errorOutput.contains("No module named 'foo'"))
219+
}
220+
}
221+
222+
test(s"$runInReplPrefix with extra JAR") {
223+
runInRepl(codeToRunInRepl =
224+
"""import shapeless._; println("Here's an HList: " + (2 :: true :: "a" :: HNil))"""
225+
)(
226+
runBeforeReplAndGetExtraCliOpts = () =>
227+
val shapelessJar =
228+
os.proc(TestUtil.cs, "fetch", "--intransitive", "com.chuusai:shapeless_2.13:2.3.7")
229+
.call()
230+
.out
231+
.text()
232+
.trim
233+
Seq("--jar", shapelessJar)
234+
,
235+
runAfterRepl = res => expect(res.out.trim() == "Here's an HList: 2 :: true :: a :: HNil")
236+
)
237+
}
238+
239+
test(s"$runInReplPrefix https://github.com/scala/scala3/issues/21229") {
240+
runInRepl(
241+
codeToRunInRepl = "println(stuff.baz)",
242+
testInputs = TestInputs(
243+
os.rel / "Pprint.scala" ->
244+
"""//> using dep com.lihaoyi::pprint::0.9.0
245+
|package stuff
246+
|import scala.quoted.*
247+
|def foo = pprint(1)
248+
|inline def bar = pprint(1)
249+
|inline def baz = ${ bazImpl }
250+
|def bazImpl(using Quotes) = '{ pprint(1) }
251+
|""".stripMargin
252+
)
253+
)(res => expect(res.out.trim().nonEmpty))
254+
}
255+
256+
test(s"$runInReplPrefix as jar") {
257+
val inputs = TestInputs(
258+
os.rel / "CheckCp.scala" ->
259+
"""//> using dep com.lihaoyi::os-lib:0.9.1
260+
|package checkcp
261+
|class CheckCp
262+
|object CheckCp {
263+
| def hasDir: Boolean = {
264+
| val uri: java.net.URI = classOf[checkcp.CheckCp].getProtectionDomain.getCodeSource.getLocation.toURI
265+
| os.isDir(os.Path(java.nio.file.Paths.get(uri)))
266+
| }
267+
|}
268+
|""".stripMargin
269+
)
270+
val code = """println("hasDir=" + checkcp.CheckCp.hasDir)"""
271+
runInRepl(codeToRunInRepl = code, testInputs = inputs) {
272+
res => expect(res.out.trim().contains("hasDir=true"))
273+
}
274+
runInRepl(
275+
codeToRunInRepl = code,
276+
testInputs = inputs,
277+
cliOptions = Seq("--as-jar", "--power")
278+
) {
279+
res => expect(res.out.trim().contains("hasDir=false"))
280+
}
281+
}
282+
}
124283
}

0 commit comments

Comments
 (0)