@@ -2,14 +2,10 @@ package scala.cli.integration
22
33import com .eed3si9n .expecty .Expecty .expect
44
5- import scala .cli .integration .TestUtil .removeAnsiColors
6- import scala .util .Properties
5+ import scala .cli .integration .TestUtil .{normalizeArgsForWindows , removeAnsiColors }
76
87trait ReplAmmoniteTestDefinitions { this : ReplTestDefinitions =>
9- protected val retrieveScalaVersionCode : String = if (actualScalaVersion.startsWith(" 2." ))
10- " scala.util.Properties.versionNumberString"
11- else " dotty.tools.dotc.config.Properties.simpleVersionString"
12-
8+ protected val ammonitePrefix : String = " Running in Ammonite REPL:"
139 def expectedScalaVersionForAmmonite : String =
1410 actualScalaVersion match {
1511 case s
@@ -32,212 +28,185 @@ trait ReplAmmoniteTestDefinitions { this: ReplTestDefinitions =>
3228 }
3329
3430 def actualMaxAmmoniteScalaVersion : String =
35- if ( actualScalaVersion.startsWith(Constants .scala3LtsPrefix))
31+ if actualScalaVersion.startsWith(Constants .scala3LtsPrefix) then
3632 Constants .maxAmmoniteScala3LtsVersion
37- else if ( actualScalaVersion.startsWith(Constants .scala3NextPrefix))
33+ else if actualScalaVersion.startsWith(Constants .scala3NextPrefix) then
3834 Constants .maxAmmoniteScala3Version
39- else if ( actualScalaVersion.startsWith(" 2.13" )) Constants .maxAmmoniteScala213Version
35+ else if actualScalaVersion.startsWith(" 2.13" ) then Constants .maxAmmoniteScala213Version
4036 else Constants .maxAmmoniteScala212Version
4137
38+ def shouldUseMaxAmmoniteScalaVersion : Boolean =
39+ actualScalaVersion.coursierVersion > actualMaxAmmoniteScalaVersion.coursierVersion
40+
4241 def ammoniteExtraOptions : Seq [String ] =
43- Seq (" --scala" , actualMaxAmmoniteScalaVersion) ++ TestUtil .extraOptions
42+ if ! shouldUseMaxAmmoniteScalaVersion then extraOptions
43+ else Seq (" --scala" , actualMaxAmmoniteScalaVersion) ++ TestUtil .extraOptions
44+
45+ def runInAmmoniteRepl (
46+ codeToRunInRepl : String = " " ,
47+ testInputs : TestInputs = TestInputs .empty,
48+ cliOptions : Seq [String ] = Seq .empty,
49+ extraAmmoniteOptions : Seq [String ] = Seq .empty,
50+ shouldPipeStdErr : Boolean = false ,
51+ check : Boolean = true ,
52+ env : Map [String , String ] = Map .empty
53+ )(
54+ runAfterRepl : os.CommandResult => Unit ,
55+ runBeforeReplAndGetExtraCliOpts : () => Seq [os.Shellable ] = () => Seq .empty
56+ ): Unit = {
57+ val ammArgs =
58+ if codeToRunInRepl.nonEmpty then
59+ (Seq (" -c" , codeToRunInRepl) ++ extraAmmoniteOptions)
60+ .normalizeArgsForWindows
61+ .flatMap(arg => Seq (" --ammonite-arg" , arg))
62+ else Seq .empty
63+ testInputs.fromRoot { root =>
64+ val potentiallyExtraCliOpts = runBeforeReplAndGetExtraCliOpts()
65+ runAfterRepl(
66+ os.proc(
67+ TestUtil .cli,
68+ " --power" ,
69+ " repl" ,
70+ " ." ,
71+ " --ammonite" ,
72+ ammArgs,
73+ ammoniteExtraOptions,
74+ cliOptions,
75+ potentiallyExtraCliOpts
76+ ).call(
77+ cwd = root,
78+ env = env,
79+ check = check,
80+ stderr = if shouldPipeStdErr then os.Pipe else os.Inherit
81+ )
82+ )
83+ }
84+ }
4485
45- def ammoniteTest (useMaxAmmoniteScalaVersion : Boolean ): Unit = {
86+ def ammoniteTest (): Unit = {
4687 TestInputs .empty.fromRoot { root =>
47- val testExtraOptions = if (useMaxAmmoniteScalaVersion) ammoniteExtraOptions else extraOptions
48- val ammArgs = Seq (
49- " -c" ,
50- s """ println("Hello" + " from Scala " + $retrieveScalaVersionCode) """
51- )
52- .map {
53- if (Properties .isWin)
54- a => if (a.contains(" " )) " \" " + a.replace(" \" " , " \\\" " ) + " \" " else a
55- else
56- identity
88+ runInAmmoniteRepl(
89+ codeToRunInRepl = s """ println("Hello" + " from Scala " + $retrieveScalaVersionCode) """ ,
90+ shouldPipeStdErr = true
91+ ) { res =>
92+ val output = res.out.trim()
93+ val expectedSv =
94+ if shouldUseMaxAmmoniteScalaVersion then actualMaxAmmoniteScalaVersion
95+ else expectedScalaVersionForAmmonite
96+ expect(output == s " Hello from Scala $expectedSv" )
97+ if shouldUseMaxAmmoniteScalaVersion then {
98+ // the maximum Scala version supported by ammonite is being used, so we shouldn't downgrade
99+ val errOutput = res.err.trim()
100+ expect(! errOutput.contains(" not yet supported with this version of Ammonite" ))
57101 }
58- .flatMap(arg => Seq (" --ammonite-arg" , arg))
59- val res =
60- os.proc(TestUtil .cli, " --power" , " repl" , testExtraOptions, " --ammonite" , ammArgs)
61- .call(cwd = root, stderr = os.Pipe )
62- val output = res.out.trim()
63- val expectedSv =
64- if (useMaxAmmoniteScalaVersion) actualMaxAmmoniteScalaVersion
65- else expectedScalaVersionForAmmonite
66- expect(output == s " Hello from Scala $expectedSv" )
67- if (useMaxAmmoniteScalaVersion) {
68- // the maximum Scala version supported by ammonite is being used, so we shouldn't downgrade
69- val errOutput = res.err.trim()
70- expect(! errOutput.contains(" not yet supported with this version of Ammonite" ))
71102 }
72103 }
73104 }
74105
75- def ammoniteTestScope (useMaxAmmoniteScalaVersion : Boolean ): Unit = {
106+ def ammoniteTestScope (): Unit = {
76107 val message = " something something ammonite"
77- TestInputs (
78- os.rel / " example" / " TestScopeExample.test.scala" ->
79- s """ package example
80- |
81- |object TestScopeExample {
82- | def message: String = " $message"
83- |}
84- | """ .stripMargin
85- ).fromRoot { root =>
86- val testExtraOptions = if (useMaxAmmoniteScalaVersion) ammoniteExtraOptions else extraOptions
87- val ammArgs = Seq (" -c" , " println(example.TestScopeExample.message)" )
88- .map {
89- if (Properties .isWin)
90- a => if (a.contains(" " )) " \" " + a.replace(" \" " , " \\\" " ) + " \" " else a
91- else
92- identity
93- }
94- .flatMap(arg => Seq (" --ammonite-arg" , arg))
95- val res =
96- os.proc(
97- TestUtil .cli,
98- " --power" ,
99- " repl" ,
100- " ." ,
101- testExtraOptions,
102- " --test" ,
103- " --ammonite" ,
104- ammArgs
105- )
106- .call(cwd = root, stderr = os.Pipe )
108+ runInAmmoniteRepl(
109+ codeToRunInRepl = " println(example.TestScopeExample.message)" ,
110+ testInputs =
111+ TestInputs (
112+ os.rel / " example" / " TestScopeExample.test.scala" ->
113+ s """ package example
114+ |
115+ |object TestScopeExample {
116+ | def message: String = " $message"
117+ |}
118+ | """ .stripMargin
119+ ),
120+ cliOptions = Seq (" --test" ),
121+ shouldPipeStdErr = true
122+ ) { res =>
107123 val output = res.out.trim()
108124 expect(output == message)
109- if (useMaxAmmoniteScalaVersion) {
125+ if shouldUseMaxAmmoniteScalaVersion then {
110126 // the maximum Scala version supported by ammonite is being used, so we shouldn't downgrade
111127 val errOutput = res.err.trim()
112128 expect(! errOutput.contains(" not yet supported with this version of Ammonite" ))
113129 }
114130 }
115131 }
116132
117- def ammoniteScalapyTest (useMaxAmmoniteScalaVersion : Boolean ): Unit = {
118- val testExtraOptions = if (useMaxAmmoniteScalaVersion) ammoniteExtraOptions else extraOptions
119- val inputs = TestInputs (
120- os.rel / " foo" / " something.py" ->
121- """ messageStart = 'Hello from'
122- |messageEnd = 'ScalaPy'
123- |""" .stripMargin
124- )
125- inputs.fromRoot { root =>
126- val ammArgs = Seq (
127- " -c" ,
128- s """ println("Hello" + " from Scala " + $retrieveScalaVersionCode)
129- |val sth = py.module("foo.something")
130- |py.Dynamic.global.applyDynamicNamed("print")("" -> sth.messageStart, "" -> sth.messageEnd, "flush" -> py.Any.from(true))
131- | """ .stripMargin
132- )
133- .map {
134- if (Properties .isWin)
135- a => if (a.contains(" " )) " \" " + a.replace(" \" " , " \\\" " ) + " \" " else a
136- else
137- identity
138- }
139- .flatMap(arg => Seq (" --ammonite-arg" , arg))
140-
141- val errorRes = os.proc(
142- TestUtil .cli,
143- " --power" ,
144- " repl" ,
145- testExtraOptions,
146- " --ammonite" ,
147- " --python" ,
148- ammArgs
149- ).call(
150- cwd = root,
151- env = Map (" PYTHONSAFEPATH" -> " foo" ),
152- mergeErrIntoOut = true ,
153- check = false
133+ def ammoniteScalapyTest (): Unit = {
134+ val codeToRunInRepl =
135+ s """ println("Hello" + " from Scala " + $retrieveScalaVersionCode)
136+ |val sth = py.module("foo.something")
137+ |py.Dynamic.global.applyDynamicNamed("print")("" -> sth.messageStart, "" -> sth.messageEnd, "flush" -> py.Any.from(true))
138+ | """ .stripMargin
139+ val inputs =
140+ TestInputs (
141+ os.rel / " foo" / " something.py" ->
142+ """ messageStart = 'Hello from'
143+ |messageEnd = 'ScalaPy'
144+ |""" .stripMargin
154145 )
146+ runInAmmoniteRepl(
147+ codeToRunInRepl = codeToRunInRepl,
148+ testInputs = inputs,
149+ cliOptions = Seq (" --python" ),
150+ shouldPipeStdErr = true ,
151+ check = false ,
152+ env = Map (" PYTHONSAFEPATH" -> " foo" )
153+ ) { errorRes =>
155154 expect(errorRes.exitCode != 0 )
156- val errorOutput = errorRes.out.text ()
155+ val errorOutput = errorRes.err.trim() + errorRes. out.trim ()
157156 expect(errorOutput.contains(" No module named 'foo'" ))
158-
159- val res = os.proc(
160- TestUtil .cli,
161- " --power" ,
162- " repl" ,
163- testExtraOptions,
164- " --ammonite" ,
165- " --python" ,
166- ammArgs
167- ).call(cwd = root, stderr = os.Pipe )
157+ }
158+ runInAmmoniteRepl(
159+ codeToRunInRepl = codeToRunInRepl,
160+ testInputs = inputs,
161+ cliOptions = Seq (" --python" ),
162+ shouldPipeStdErr = true
163+ ) { res =>
168164 val expectedSv =
169- if (useMaxAmmoniteScalaVersion) actualMaxAmmoniteScalaVersion
165+ if shouldUseMaxAmmoniteScalaVersion then actualMaxAmmoniteScalaVersion
170166 else expectedScalaVersionForAmmonite
171167 val lines = res.out.trim().linesIterator.toVector
172168 expect(lines == Seq (s " Hello from Scala $expectedSv" , " Hello from ScalaPy" ))
173- if (useMaxAmmoniteScalaVersion)
169+ if shouldUseMaxAmmoniteScalaVersion then
174170 // the maximum Scala version supported by ammonite is being used, so we shouldn't downgrade
175171 expect(! res.err.trim().contains(" not yet supported with this version of Ammonite" ))
176172 }
177173 }
178174
179175 def ammoniteMaxVersionString : String =
180- if ( actualScalaVersion == actualMaxAmmoniteScalaVersion) " "
176+ if actualScalaVersion <= actualMaxAmmoniteScalaVersion then s " with Scala $actualScalaVersion "
181177 else s " with Scala $actualMaxAmmoniteScalaVersion (the latest supported version) "
182178
183- test(s " ammonite $ammoniteMaxVersionString" ) {
184- ammoniteTest(useMaxAmmoniteScalaVersion = true )
185- }
186-
187- test(s " ammonite scalapy $ammoniteMaxVersionString" ) {
188- ammoniteScalapyTest(useMaxAmmoniteScalaVersion = true )
189- }
190-
191- test(" ammonite with test scope sources" ) {
192- ammoniteTestScope(useMaxAmmoniteScalaVersion = true )
193- }
179+ test(s " $ammonitePrefix simple $ammoniteMaxVersionString" )(ammoniteTest())
180+ test(s " $ammonitePrefix scalapy $ammoniteMaxVersionString" )(ammoniteScalapyTest())
181+ test(s " $ammonitePrefix with test scope sources $ammoniteMaxVersionString" )(ammoniteTestScope())
194182
195- test(" default ammonite version in help" ) {
196- TestInputs .empty.fromRoot { root =>
197- val res = os.proc(TestUtil .cli, " --power" , " repl" , extraOptions, " --help" ).call(cwd = root)
198- val lines = removeAnsiColors(res.out.trim()).linesIterator.toVector
183+ test(s " $ammonitePrefix ammonite version in help $ammoniteMaxVersionString" ) {
184+ runInAmmoniteRepl(cliOptions = Seq (" --help" )) { res =>
185+ val lines = removeAnsiColors(res.out.trim()).linesIterator.toVector
199186 val ammVersionHelp = lines.find(_.contains(" --ammonite-ver" )).getOrElse(" " )
200187 expect(ammVersionHelp.contains(s " ( ${Constants .ammoniteVersion} by default) " ))
201188 }
202189 }
203190
204191 def ammoniteWithExtraJarTest (): Unit = {
205- TestInputs .empty.fromRoot { root =>
206- val ammArgs = Seq (
207- " -c" ,
208- """ import shapeless._; println("Here's an HList: " + (2 :: true :: "a" :: HNil))"""
209- )
210- .map {
211- if (Properties .isWin)
212- a => if (a.contains(" " )) " \" " + a.replace(" \" " , " \\\" " ) + " \" " else a
213- else
214- identity
215- }
216- .flatMap(arg => Seq (" --ammonite-arg" , arg))
217- val shapelessJar =
218- os.proc(TestUtil .cs, " fetch" , " --intransitive" , " com.chuusai:shapeless_2.13:2.3.7" )
219- .call()
220- .out
221- .text()
222- .trim
223- val cmd = Seq [os.Shellable ](
224- TestUtil .cli,
225- " --power" ,
226- " repl" ,
227- ammoniteExtraOptions,
228- " --jar" ,
229- shapelessJar,
230- " --ammonite" ,
231- ammArgs
232- )
233- val res = os.proc(cmd).call(cwd = root)
234- val output = res.out.trim()
235- expect(output == " Here's an HList: 2 :: true :: a :: HNil" )
236- }
192+ runInAmmoniteRepl(codeToRunInRepl =
193+ """ import shapeless._; println("Here's an HList: " + (2 :: true :: "a" :: HNil))"""
194+ )(
195+ runBeforeReplAndGetExtraCliOpts = () =>
196+ val shapelessJar =
197+ os.proc(TestUtil .cs, " fetch" , " --intransitive" , " com.chuusai:shapeless_2.13:2.3.7" )
198+ .call()
199+ .out
200+ .text()
201+ .trim
202+ Seq (" --jar" , shapelessJar)
203+ ,
204+ runAfterRepl = res => expect(res.out.trim() == " Here's an HList: 2 :: true :: a :: HNil" )
205+ )
237206 }
238207
239- if ( actualScalaVersion.startsWith(" 2.13" ))
240- test(s " ammonite with extra JAR $ammoniteMaxVersionString" ) {
208+ if actualScalaVersion.startsWith(" 2.13" ) then
209+ test(s " $ammonitePrefix with extra JAR $ammoniteMaxVersionString" ) {
241210 ammoniteWithExtraJarTest()
242211 }
243212}
0 commit comments