From 58a5ea499c6a6824ea72b72efb45e273e75b792f Mon Sep 17 00:00:00 2001 From: Piotr Chabelski Date: Tue, 9 Apr 2024 09:02:34 +0200 Subject: [PATCH 1/3] Fix & refactor script wrapper tests --- .../scala/cli/integration/TestInputs.scala | 1 + .../cli/integration/BspTestDefinitions.scala | 14 +- .../scala/cli/integration/BspTests212.scala | 2 +- .../scala/cli/integration/BspTests213.scala | 4 +- .../integration/BspTests2Definitions.scala | 31 +++ .../integration/BspTests3Definitions.scala | 52 ++++ .../scala/cli/integration/BspTests3Lts.scala | 2 +- .../cli/integration/BspTests3NextRc.scala | 2 +- .../cli/integration/BspTestsDefault.scala | 2 +- .../ScriptWrapperTestDefinitions.scala | 87 +++++++ .../cli/integration/ScriptWrapperTests.scala | 230 ------------------ 11 files changed, 184 insertions(+), 243 deletions(-) create mode 100644 modules/integration/src/test/scala/scala/cli/integration/BspTests2Definitions.scala create mode 100644 modules/integration/src/test/scala/scala/cli/integration/BspTests3Definitions.scala create mode 100644 modules/integration/src/test/scala/scala/cli/integration/ScriptWrapperTestDefinitions.scala delete mode 100644 modules/integration/src/test/scala/scala/cli/integration/ScriptWrapperTests.scala diff --git a/modules/integration/src/main/scala/scala/cli/integration/TestInputs.scala b/modules/integration/src/main/scala/scala/cli/integration/TestInputs.scala index a63237e7f4..d79d80fc3e 100644 --- a/modules/integration/src/main/scala/scala/cli/integration/TestInputs.scala +++ b/modules/integration/src/main/scala/scala/cli/integration/TestInputs.scala @@ -34,6 +34,7 @@ final case class TestInputs(maybeCharset: Option[Charset], files: (os.RelPath, S writeIn(tmpDir) f(tmpDir) } + def fileNames: Seq[String] = files.flatMap(_._1.lastOpt) } object TestInputs { diff --git a/modules/integration/src/test/scala/scala/cli/integration/BspTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/BspTestDefinitions.scala index 2817cb9951..1c111037a6 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/BspTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/BspTestDefinitions.scala @@ -22,9 +22,10 @@ import scala.jdk.CollectionConverters.* import scala.util.control.NonFatal import scala.util.{Failure, Properties, Success, Try} -abstract class BspTestDefinitions extends ScalaCliSuite with TestScalaVersionArgs { +abstract class BspTestDefinitions extends ScalaCliSuite with TestScalaVersionArgs + with ScriptWrapperTestDefinitions { _: TestScalaVersion => - private lazy val extraOptions = scalaVersionArgs ++ TestUtil.extraOptions + protected lazy val extraOptions: Seq[String] = scalaVersionArgs ++ TestUtil.extraOptions import BspTestDefinitions.* @@ -61,12 +62,12 @@ abstract class BspTestDefinitions extends ScalaCliSuite with TestScalaVersionArg pool.shutdown() } - private def extractMainTargets(targets: Seq[BuildTargetIdentifier]): BuildTargetIdentifier = + protected def extractMainTargets(targets: Seq[BuildTargetIdentifier]): BuildTargetIdentifier = targets.collectFirst { case t if !t.getUri.contains("-test") => t }.get - private def extractTestTargets(targets: Seq[BuildTargetIdentifier]): BuildTargetIdentifier = + protected def extractTestTargets(targets: Seq[BuildTargetIdentifier]): BuildTargetIdentifier = targets.collectFirst { case t if t.getUri.contains("-test") => t }.get @@ -78,7 +79,8 @@ abstract class BspTestDefinitions extends ScalaCliSuite with TestScalaVersionArg pauseDuration: FiniteDuration = 5.seconds, bspOptions: List[String] = List.empty, reuseRoot: Option[os.Path] = None, - stdErrOpt: Option[os.RelPath] = None + stdErrOpt: Option[os.RelPath] = None, + extraOptionsOverride: Seq[String] = extraOptions )( f: ( os.Path, @@ -93,7 +95,7 @@ abstract class BspTestDefinitions extends ScalaCliSuite with TestScalaVersionArg val stdErrPathOpt: Option[os.ProcessOutput] = stdErrOpt.map(path => inputsRoot / path) val stderr: os.ProcessOutput = stdErrPathOpt.getOrElse(os.Inherit) - val proc = os.proc(TestUtil.cli, "bsp", bspOptions ++ extraOptions, args) + val proc = os.proc(TestUtil.cli, "bsp", bspOptions ++ extraOptionsOverride, args) .spawn(cwd = root, stderr = stderr) var remoteServer: b.BuildServer & b.ScalaBuildServer & b.JavaBuildServer & b.JvmBuildServer = null diff --git a/modules/integration/src/test/scala/scala/cli/integration/BspTests212.scala b/modules/integration/src/test/scala/scala/cli/integration/BspTests212.scala index e0d26ea118..def55ff4b6 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/BspTests212.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/BspTests212.scala @@ -1,3 +1,3 @@ package scala.cli.integration -class BspTests212 extends BspTestDefinitions with Test212 +class BspTests212 extends BspTestDefinitions with BspTests2Definitions with Test212 diff --git a/modules/integration/src/test/scala/scala/cli/integration/BspTests213.scala b/modules/integration/src/test/scala/scala/cli/integration/BspTests213.scala index 3de44c3e8e..bf8dfcf358 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/BspTests213.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/BspTests213.scala @@ -8,8 +8,7 @@ import scala.async.Async.{async, await} import scala.concurrent.ExecutionContext.Implicits.global import scala.jdk.CollectionConverters.* -class BspTests213 extends BspTestDefinitions with Test213 { - +class BspTests213 extends BspTestDefinitions with BspTests2Definitions with Test213 { List(".sc", ".scala").foreach { filetype => test(s"bsp should report actionable diagnostic from bloop for $filetype files (Scala 2.13)") { val fileName = s"Hello$filetype" @@ -73,5 +72,4 @@ class BspTests213 extends BspTestDefinitions with Test213 { } } } - } diff --git a/modules/integration/src/test/scala/scala/cli/integration/BspTests2Definitions.scala b/modules/integration/src/test/scala/scala/cli/integration/BspTests2Definitions.scala new file mode 100644 index 0000000000..2282faa98e --- /dev/null +++ b/modules/integration/src/test/scala/scala/cli/integration/BspTests2Definitions.scala @@ -0,0 +1,31 @@ +package scala.cli.integration + +import scala.concurrent.ExecutionContext.Implicits.global + +trait BspTests2Definitions { _: BspTestDefinitions => + for { + useDirectives <- Seq(true, false) + (directive, options) <- Seq( + (s"//> using scala $actualScalaVersion", Seq("--scala", actualScalaVersion)) + ) + extraOptionsOverride = + if (useDirectives) TestUtil.extraOptions else TestUtil.extraOptions ++ options + testNameSuffix = if (useDirectives) directive else options.mkString(" ") + } test(s"BSP App object wrapper forced with $testNameSuffix") { + val (script1, script2) = "script1.sc" -> "script2.sc" + val directiveString = if (useDirectives) directive else "" + val inputs = TestInputs( + os.rel / script1 -> + s"""//> using platform js + |$directiveString + | + |def main(args: String*): Unit = println("Hello") + |main() + |""".stripMargin, + os.rel / script2 -> + """println("Hello") + |""".stripMargin + ) + testScriptWrappers(inputs, extraOptionsOverride = extraOptionsOverride)(expectAppWrapper) + } +} diff --git a/modules/integration/src/test/scala/scala/cli/integration/BspTests3Definitions.scala b/modules/integration/src/test/scala/scala/cli/integration/BspTests3Definitions.scala new file mode 100644 index 0000000000..95be177187 --- /dev/null +++ b/modules/integration/src/test/scala/scala/cli/integration/BspTests3Definitions.scala @@ -0,0 +1,52 @@ +package scala.cli.integration + +import scala.concurrent.ExecutionContext.Implicits.global + +trait BspTests3Definitions { _: BspTestDefinitions => + test("BSP class wrapper for Scala 3") { + val (script1, script2) = "script1.sc" -> "script2.sc" + val inputs = TestInputs( + os.rel / script1 -> + s"""def main(args: String*): Unit = println("Hello") + |main() + |""".stripMargin, + os.rel / script2 -> + s"""//> using dep "org.scalatest::scalatest:3.2.15" + | + |import org.scalatest.*, flatspec.*, matchers.* + | + |class PiTest extends AnyFlatSpec with should.Matchers { + | "pi calculus" should "return a precise enough pi value" in { + | math.Pi shouldBe 3.14158d +- 0.001d + | } + |} + |org.scalatest.tools.Runner.main(Array("-oDF", "-s", classOf[PiTest].getName))""".stripMargin + ) + testScriptWrappers(inputs)(expectClassWrapper) + } + + for { + useDirectives <- Seq(true, false) + (directive, options) <- Seq( + ("//> using object.wrapper", Seq("--object-wrapper")), + ("//> using platform js", Seq("--js")) + ) + wrapperOptions = if (useDirectives) Nil else options + testNameSuffix = if (useDirectives) directive else options.mkString(" ") + } test(s"BSP object wrapper forced with $testNameSuffix") { + val (script1, script2) = "script1.sc" -> "script2.sc" + val directiveString = if (useDirectives) directive else "" + val inputs = TestInputs( + os.rel / script1 -> + s"""$directiveString + | + |def main(args: String*): Unit = println("Hello") + |main() + |""".stripMargin, + os.rel / script2 -> + """println("Hello") + |""".stripMargin + ) + testScriptWrappers(inputs, bspOptions = wrapperOptions)(expectObjectWrapper) + } +} diff --git a/modules/integration/src/test/scala/scala/cli/integration/BspTests3Lts.scala b/modules/integration/src/test/scala/scala/cli/integration/BspTests3Lts.scala index 4b09e92e5f..1b5cff8f05 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/BspTests3Lts.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/BspTests3Lts.scala @@ -1,3 +1,3 @@ package scala.cli.integration -class BspTests3Lts extends BspTestDefinitions with Test3Lts +class BspTests3Lts extends BspTestDefinitions with BspTests3Definitions with Test3Lts diff --git a/modules/integration/src/test/scala/scala/cli/integration/BspTests3NextRc.scala b/modules/integration/src/test/scala/scala/cli/integration/BspTests3NextRc.scala index ddd0205017..a42659289c 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/BspTests3NextRc.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/BspTests3NextRc.scala @@ -1,3 +1,3 @@ package scala.cli.integration -class BspTests3NextRc extends BspTestDefinitions with Test3NextRc +class BspTests3NextRc extends BspTestDefinitions with BspTests3Definitions with Test3NextRc diff --git a/modules/integration/src/test/scala/scala/cli/integration/BspTestsDefault.scala b/modules/integration/src/test/scala/scala/cli/integration/BspTestsDefault.scala index 8d9d1a721c..fa942772b8 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/BspTestsDefault.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/BspTestsDefault.scala @@ -1,3 +1,3 @@ package scala.cli.integration -class BspTestsDefault extends BspTestDefinitions with TestDefault +class BspTestsDefault extends BspTestDefinitions with BspTests3Definitions with TestDefault diff --git a/modules/integration/src/test/scala/scala/cli/integration/ScriptWrapperTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/ScriptWrapperTestDefinitions.scala new file mode 100644 index 0000000000..efb9a1f0ed --- /dev/null +++ b/modules/integration/src/test/scala/scala/cli/integration/ScriptWrapperTestDefinitions.scala @@ -0,0 +1,87 @@ +package scala.cli.integration + +import ch.epfl.scala.bsp4j as b +import com.eed3si9n.expecty.Expecty.expect + +import scala.async.Async.{async, await} +import scala.concurrent.ExecutionContext +import scala.jdk.CollectionConverters.* + +trait ScriptWrapperTestDefinitions extends ScalaCliSuite { _: BspTestDefinitions => + private def appWrapperSnippet(wrapperName: String) = s"object $wrapperName extends App {" + private def classWrapperSnippet(wrapperName: String) = s"final class $wrapperName$$_" + private def objectWrapperSnippet(wrapperName: String) = s"object $wrapperName {" + def expectScriptWrapper( + path: os.Path, + containsCheck: String => Boolean, + doesNotContainCheck: String => Boolean + ): Unit = { + val generatedFileContent = os.read(path) + assert( + containsCheck(generatedFileContent), + clue(s"Generated file content: $generatedFileContent") + ) + assert( + doesNotContainCheck(generatedFileContent), + clue(s"Generated file content: $generatedFileContent") + ) + } + def expectAppWrapper(wrapperName: String, path: os.Path): Unit = + expectScriptWrapper( + path, + _.contains(appWrapperSnippet(wrapperName)), + content => + !content.contains(classWrapperSnippet(wrapperName)) && + !content.contains(objectWrapperSnippet(wrapperName)) + ) + + def expectObjectWrapper(wrapperName: String, path: os.Path): Unit = + expectScriptWrapper( + path, + _.contains(objectWrapperSnippet(wrapperName)), + content => + !content.contains(classWrapperSnippet(wrapperName)) && + !content.contains(appWrapperSnippet(wrapperName)) + ) + + def expectClassWrapper(wrapperName: String, path: os.Path): Unit = + expectScriptWrapper( + path, + _.contains(classWrapperSnippet(wrapperName)), + content => + !content.contains(appWrapperSnippet(wrapperName)) && + !content.contains(objectWrapperSnippet(wrapperName)) + ) + + def testScriptWrappers( + inputs: TestInputs, + bspOptions: Seq[String] = Nil, + extraOptionsOverride: Seq[String] = extraOptions + )(expectWrapperFunction: (String, os.Path) => Unit)(implicit ec: ExecutionContext): Unit = { + withBsp( + inputs, + inputs.fileNames ++ Seq("--power") ++ bspOptions, + extraOptionsOverride = extraOptionsOverride + ) { + (root, _, remoteServer) => + async { + val buildTargetsResp = await(remoteServer.workspaceBuildTargets().asScala) + val targets = buildTargetsResp.getTargets.asScala.map(_.getId).asJava + val compileParams = new b.CompileParams(targets) + val buildResp = await(remoteServer.buildTargetCompile(compileParams).asScala) + expect(buildResp.getStatusCode == b.StatusCode.OK) + val projectDir = os.list(root / Constants.workspaceDirName).filter( + _.baseName.startsWith(root.baseName + "_") + ) + expect(projectDir.size == 1) + inputs.fileNames.map(_.stripSuffix(".sc")).foreach { + scriptName => + expectWrapperFunction( + scriptName, + projectDir.head / "src_generated" / "main" / s"$scriptName.scala" + ) + } + } + } + } +} diff --git a/modules/integration/src/test/scala/scala/cli/integration/ScriptWrapperTests.scala b/modules/integration/src/test/scala/scala/cli/integration/ScriptWrapperTests.scala deleted file mode 100644 index 33f76868d8..0000000000 --- a/modules/integration/src/test/scala/scala/cli/integration/ScriptWrapperTests.scala +++ /dev/null @@ -1,230 +0,0 @@ -package scala.cli.integration - -import com.eed3si9n.expecty.Expecty.expect - -import scala.concurrent.ExecutionContext -import scala.concurrent.duration.Duration - -class ScriptWrapperTests extends ScalaCliSuite { - def expectAppWrapper(wrapperName: String, path: os.Path) = { - val generatedFileContent = os.read(path) - assert( - generatedFileContent.contains(s"object $wrapperName extends App {"), - clue(s"Generated file content: $generatedFileContent") - ) - assert( - !generatedFileContent.contains(s"final class $wrapperName$$_") && - !generatedFileContent.contains(s"object $wrapperName {"), - clue(s"Generated file content: $generatedFileContent") - ) - } - - def expectObjectWrapper(wrapperName: String, path: os.Path) = { - val generatedFileContent = os.read(path) - assert( - generatedFileContent.contains(s"object $wrapperName {"), - clue(s"Generated file content: $generatedFileContent") - ) - assert( - !generatedFileContent.contains(s"final class $wrapperName$$_") && - !generatedFileContent.contains(s"object $wrapperName wraps App {"), - clue(s"Generated file content: $generatedFileContent") - ) - } - - def expectClassWrapper(wrapperName: String, path: os.Path) = { - val generatedFileContent = os.read(path) - assert( - generatedFileContent.contains(s"final class $wrapperName$$_"), - clue(s"Generated file content: $generatedFileContent") - ) - assert( - !generatedFileContent.contains(s"object $wrapperName extends App {") && - !generatedFileContent.contains(s"object $wrapperName {"), - clue(s"Generated file content: $generatedFileContent") - ) - } - - test("BSP class wrapper for Scala 3") { - val inputs = TestInputs( - os.rel / "script.sc" -> - s"""//> using dep "com.lihaoyi::os-lib:0.9.1" - | - |def main(args: String*): Unit = println("Hello") - |""".stripMargin, - os.rel / "munit.sc" -> - s"""//> using dep "org.scalatest::scalatest:3.2.15" - | - |import org.scalatest.*, flatspec.*, matchers.* - | - |class PiTest extends AnyFlatSpec with should.Matchers { - | "pi calculus" should "return a precise enough pi value" in { - | math.Pi shouldBe 3.14158d +- 0.001d - | } - |} - |org.scalatest.tools.Runner.main(Array("-oDF", "-s", classOf[PiTest].getName))""".stripMargin - ) - inputs.fromRoot { root => - TestUtil.withThreadPool("script-wrapper-bsp-test", 2) { pool => - val timeout = Duration("60 seconds") - implicit val ec = ExecutionContext.fromExecutorService(pool) - val bspProc = os.proc(TestUtil.cli, "--power", "bsp", "script.sc", "munit.sc") - .spawn(cwd = root, mergeErrIntoOut = true, stdout = os.Pipe) - - def lineReaderIter = - Iterator.continually(TestUtil.readLine(bspProc.stdout, ec, timeout)) - - lineReaderIter.find(_.contains("\"build/taskFinish\"")) - - bspProc.destroy() - if (bspProc.isAlive()) - bspProc.destroyForcibly() - - val projectDir = os.list(root / Constants.workspaceDirName).filter( - _.baseName.startsWith(root.baseName + "_") - ) - expect(projectDir.size == 1) - expectClassWrapper( - "script", - projectDir.head / "src_generated" / "main" / "script.scala" - ) - expectClassWrapper( - "munit", - projectDir.head / "src_generated" / "main" / "munit.scala" - ) - } - } - } - - for { - useDirectives <- Seq(true, false) - (directive, options) <- Seq( - ("//> using object.wrapper", Seq("--object-wrapper")), - ("//> using platform js", Seq("--js")) - ) - } { - val inputs = TestInputs( - os.rel / "script1.sc" -> - s"""//> using dep "com.lihaoyi::os-lib:0.9.1" - |${if (useDirectives) directive else ""} - | - |def main(args: String*): Unit = println("Hello") - |main() - |""".stripMargin, - os.rel / "script2.sc" -> - """//> using dep "com.lihaoyi::os-lib:0.9.1" - | - |println("Hello") - |""".stripMargin - ) - - test( - s"BSP object wrapper forced with ${if (useDirectives) directive else options.mkString(" ")}" - ) { - inputs.fromRoot { root => - TestUtil.withThreadPool("script-wrapper-bsp-test", 2) { pool => - val timeout = Duration("60 seconds") - implicit val ec = ExecutionContext.fromExecutorService(pool) - - val bspProc = os.proc( - TestUtil.cli, - "--power", - "bsp", - "script1.sc", - "script2.sc", - if (useDirectives) Nil else options - ) - .spawn(cwd = root, mergeErrIntoOut = true, stdout = os.Pipe) - - def lineReaderIter = - Iterator.continually(TestUtil.readLine(bspProc.stdout, ec, timeout)) - - lineReaderIter.find(_.contains("\"build/taskFinish\"")) - - bspProc.destroy() - if (bspProc.isAlive()) - bspProc.destroyForcibly() - - val projectDir = os.list(root / Constants.workspaceDirName).filter( - _.baseName.startsWith(root.baseName + "_") - ) - expect(projectDir.size == 1) - expectObjectWrapper( - "script1", - projectDir.head / "src_generated" / "main" / "script1.scala" - ) - expectObjectWrapper( - "script2", - projectDir.head / "src_generated" / "main" / "script2.scala" - ) - } - } - } - } - - for { - useDirectives <- Seq(true, false) - (directive, options) <- Seq( - (s"//> using scala ${Constants.scala213}", Seq("--scala", Constants.scala213)) - ) - } { - val inputs = TestInputs( - os.rel / "script1.sc" -> - s"""//> using platform js - |//> using dep "com.lihaoyi::os-lib:0.9.1" - |${if (useDirectives) directive else ""} - | - |def main(args: String*): Unit = println("Hello") - |main() - |""".stripMargin, - os.rel / "script2.sc" -> - """//> using dep "com.lihaoyi::os-lib:0.9.1" - | - |println("Hello") - |""".stripMargin - ) - - test( - s"BSP App object wrapper forced with ${if (useDirectives) directive else options.mkString(" ")}" - ) { - inputs.fromRoot { root => - TestUtil.withThreadPool("script-wrapper-bsp-test", 2) { pool => - val timeout = Duration("60 seconds") - implicit val ec = ExecutionContext.fromExecutorService(pool) - - val bspProc = os.proc( - TestUtil.cli, - "--power", - "bsp", - "script1.sc", - "script2.sc", - if (useDirectives) Nil else options - ) - .spawn(cwd = root, mergeErrIntoOut = true, stdout = os.Pipe) - - def lineReaderIter = - Iterator.continually(TestUtil.readLine(bspProc.stdout, ec, timeout)) - - lineReaderIter.find(_.contains("\"build/taskFinish\"")) - - bspProc.destroy() - if (bspProc.isAlive()) - bspProc.destroyForcibly() - - val projectDir = os.list(root / Constants.workspaceDirName).filter( - _.baseName.startsWith(root.baseName + "_") - ) - expect(projectDir.size == 1) - expectAppWrapper( - "script1", - projectDir.head / "src_generated" / "main" / "script1.scala" - ) - expectAppWrapper( - "script2", - projectDir.head / "src_generated" / "main" / "script2.scala" - ) - } - } - } - } -} From b284360e537984ffa0417799813ae91e8fb01bf2 Mon Sep 17 00:00:00 2001 From: Piotr Chabelski Date: Tue, 9 Apr 2024 13:58:04 +0200 Subject: [PATCH 2/3] NIT Minor refactors in BSP integration tests --- .../cli/integration/BspTestDefinitions.scala | 48 +++++++++---------- .../scala/cli/integration/BspTests213.scala | 18 +++---- 2 files changed, 31 insertions(+), 35 deletions(-) diff --git a/modules/integration/src/test/scala/scala/cli/integration/BspTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/BspTestDefinitions.scala index 1c111037a6..0c1142259e 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/BspTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/BspTestDefinitions.scala @@ -1608,21 +1608,21 @@ abstract class BspTestDefinitions extends ScalaCliSuite with TestScalaVersionArg ) val scalaDiagnostic = new Gson().fromJson[b.ScalaDiagnostic]( - updateActionableDiagnostic.getData().asInstanceOf[JsonElement], + updateActionableDiagnostic.getData.asInstanceOf[JsonElement], classOf[b.ScalaDiagnostic] ) - val actions = scalaDiagnostic.getActions().asScala.toList + val actions = scalaDiagnostic.getActions.asScala.toList assert(actions.size == 1) - val changes = actions.head.getEdit().getChanges().asScala.toList + val changes = actions.head.getEdit.getChanges.asScala.toList assert(changes.size == 1) val textEdit = changes.head - expect(textEdit.getNewText().contains("com.lihaoyi::os-lib:")) - expect(textEdit.getRange().getStart.getLine == 0) - expect(textEdit.getRange().getStart.getCharacter == 15) - expect(textEdit.getRange().getEnd.getLine == 0) - expect(textEdit.getRange().getEnd.getCharacter == 40) + expect(textEdit.getNewText.contains("com.lihaoyi::os-lib:")) + expect(textEdit.getRange.getStart.getLine == 0) + expect(textEdit.getRange.getStart.getCharacter == 15) + expect(textEdit.getRange.getEnd.getLine == 0) + expect(textEdit.getRange.getEnd.getCharacter == 40) } } } @@ -1655,8 +1655,8 @@ abstract class BspTestDefinitions extends ScalaCliSuite with TestScalaVersionArg await(remoteServer.buildTargetCompile(new b.CompileParams(targets)).asScala) val visibleDiagnostics = - localClient.diagnostics().map(_.getDiagnostics().asScala).find( - !_.isEmpty + localClient.diagnostics().map(_.getDiagnostics.asScala).find( + _.nonEmpty ).getOrElse( Nil ) @@ -1678,21 +1678,21 @@ abstract class BspTestDefinitions extends ScalaCliSuite with TestScalaVersionArg ) val scalaDiagnostic = new Gson().fromJson[b.ScalaDiagnostic]( - updateActionableDiagnostic.getData().asInstanceOf[JsonElement], + updateActionableDiagnostic.getData.asInstanceOf[JsonElement], classOf[b.ScalaDiagnostic] ) - val actions = scalaDiagnostic.getActions().asScala.toList + val actions = scalaDiagnostic.getActions.asScala.toList assert(actions.size == 1) - val changes = actions.head.getEdit().getChanges().asScala.toList + val changes = actions.head.getEdit.getChanges.asScala.toList assert(changes.size == 1) val textEdit = changes.head - expect(textEdit.getNewText().contains("\n case TestB() => ???")) - expect(textEdit.getRange().getStart.getLine == 7) - expect(textEdit.getRange().getStart.getCharacter == 19) - expect(textEdit.getRange().getEnd.getLine == 7) - expect(textEdit.getRange().getEnd.getCharacter == 19) + expect(textEdit.getNewText.contains("\n case TestB() => ???")) + expect(textEdit.getRange.getStart.getLine == 7) + expect(textEdit.getRange.getStart.getCharacter == 19) + expect(textEdit.getRange.getEnd.getLine == 7) + expect(textEdit.getRange.getEnd.getCharacter == 19) } } } @@ -1940,11 +1940,11 @@ abstract class BspTestDefinitions extends ScalaCliSuite with TestScalaVersionArg } val diagnostics = diagnosticsParams.flatMap(_.getDiagnostics.asScala) - .sortBy(_.getRange().getEnd().getCharacter()) + .sortBy(_.getRange.getEnd.getCharacter()) { checkDiagnostic( - diagnostic = diagnostics.apply(0), + diagnostic = diagnostics.head, expectedMessage = "Using 'latest' for toolkit is deprecated, use 'default' to get more stable behaviour", expectedSeverity = b.DiagnosticSeverity.WARNING, @@ -1955,7 +1955,7 @@ abstract class BspTestDefinitions extends ScalaCliSuite with TestScalaVersionArg ) checkScalaAction( - diagnostic = diagnostics.apply(0), + diagnostic = diagnostics.head, expectedActionsSize = 1, expectedTitle = "Change to: toolkit default", expectedChanges = 1, @@ -2092,7 +2092,7 @@ abstract class BspTestDefinitions extends ScalaCliSuite with TestScalaVersionArg expectedEndLine: Int, expectedEndCharacter: Int, expectedNewText: String - ) = { + ): Unit = { expect(diagnostic.getDataKind == "scala") val gson = new com.google.gson.Gson() @@ -2131,7 +2131,6 @@ abstract class BspTestDefinitions extends ScalaCliSuite with TestScalaVersionArg } object BspTestDefinitions { - private final case class Details( name: String, version: String, @@ -2140,7 +2139,4 @@ object BspTestDefinitions { languages: List[String] ) private val detailsCodec: JsonValueCodec[Details] = JsonCodecMaker.make - - private final case class TextEdit(range: b.Range, newText: String) - } diff --git a/modules/integration/src/test/scala/scala/cli/integration/BspTests213.scala b/modules/integration/src/test/scala/scala/cli/integration/BspTests213.scala index bf8dfcf358..d137d321bf 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/BspTests213.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/BspTests213.scala @@ -32,7 +32,7 @@ class BspTests213 extends BspTestDefinitions with BspTests2Definitions with Test await(remoteServer.buildTargetCompile(new b.CompileParams(targets)).asScala) val visibleDiagnostics = - localClient.diagnostics().map(_.getDiagnostics().asScala).find(!_.isEmpty).getOrElse( + localClient.diagnostics().map(_.getDiagnostics.asScala).find(_.nonEmpty).getOrElse( Nil ) @@ -53,21 +53,21 @@ class BspTests213 extends BspTestDefinitions with BspTests2Definitions with Test ) val scalaDiagnostic = new Gson().fromJson[b.ScalaDiagnostic]( - updateActionableDiagnostic.getData().asInstanceOf[JsonElement], + updateActionableDiagnostic.getData.asInstanceOf[JsonElement], classOf[b.ScalaDiagnostic] ) - val actions = scalaDiagnostic.getActions().asScala.toList + val actions = scalaDiagnostic.getActions.asScala.toList assert(actions.size == 1) - val changes = actions.head.getEdit().getChanges().asScala.toList + val changes = actions.head.getEdit.getChanges.asScala.toList assert(changes.size == 1) val textEdit = changes.head - expect(textEdit.getNewText().contains("(x: Int)")) - expect(textEdit.getRange().getStart.getLine == 3) - expect(textEdit.getRange().getStart.getCharacter == 4) - expect(textEdit.getRange().getEnd.getLine == 3) - expect(textEdit.getRange().getEnd.getCharacter == 10) + expect(textEdit.getNewText.contains("(x: Int)")) + expect(textEdit.getRange.getStart.getLine == 3) + expect(textEdit.getRange.getStart.getCharacter == 4) + expect(textEdit.getRange.getEnd.getLine == 3) + expect(textEdit.getRange.getEnd.getCharacter == 10) } } } From 0657b8902121a2ac8f629fc0495359496bdaf93c Mon Sep 17 00:00:00 2001 From: Piotr Chabelski Date: Wed, 3 Apr 2024 12:30:50 +0200 Subject: [PATCH 3/3] Bump `bloop-core` to 1.5.16-sc-2 & ensure the false positive fatal invariant warnings are no longer raised --- .../cli/integration/RunTestDefinitions.scala | 23 +++++++++++++++++++ project/deps.sc | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala index e62bc008e6..80d102a27a 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala @@ -2193,6 +2193,29 @@ abstract class RunTestDefinitions } } + test("running a .scala file several times doesn't produce Bloop errors") { + val msg = "Hello" + val input = "Main.scala" + TestInputs( + os.rel / input -> + s"""object Main { + | def main(args: Array[String]): Unit = { + | println("$msg") + | } + |} + |""".stripMargin + ).fromRoot { root => + // ensure the test will be run on a fresh Bloop instance + os.proc(TestUtil.cli, "bloop", "exit", "--power").call(cwd = root) + (0 to 2).foreach { _ => + val res = os.proc(TestUtil.cli, "run", input, extraOptions) + .call(cwd = root, stderr = os.Pipe) + expect(res.out.trim() == msg) + expect(!res.err.trim().toLowerCase.contains("error")) + } + } + } + test(s"warn about invalid values present in JAVA_OPTS") { val expectedOutput = "Hello" TestInputs(os.rel / "example.sc" -> s"println(\"$expectedOutput\")") diff --git a/project/deps.sc b/project/deps.sc index 22cfcddd8a..6bb6ac5b09 100644 --- a/project/deps.sc +++ b/project/deps.sc @@ -101,7 +101,7 @@ object Deps { def signingCli = "0.2.3" def signingCliJvmVersion = 17 def javaClassName = "0.1.3" - def bloop = "1.5.16-sc-1" + def bloop = "1.5.16-sc-2" } // DO NOT hardcode a Scala version in this dependency string // This dependency is used to ensure that Ammonite is available for Scala versions