From 7eba8e1fda8ba63b3299c6d0328d65ebd7181f35 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Fri, 3 Jun 2022 07:03:37 -0700 Subject: [PATCH] Re-enable `PluginCoverageScalaJsTest`, fix `dangling UndefinedParam` bug (#464) * Try re-enabling PluginCoverageScalaJsTest * ScoverageCompiler refactoring to support SJS * Scala.js test is working again * Remove unneeded dep * Try adding buildInfo to root * Set crossScalaVersions for buildinfo project * Revert "Remove unneeded dep" This reverts commit 8da1f0132236c44016018b8242d9eec06d266a7b. * Add another sjs test dep * plugin also depends on runtimeJS for tests * Actually enable the sjs compiler plugin :) * Fix expected measured statements 4 -> 2 * Only catch non-fatals * Make isScalaJsEnabled a lazy val * I think these deps are unneeded now --- build.sbt | 18 +++++- .../scala/scoverage/ScoveragePlugin.scala | 3 +- .../scoverage/PluginCoverageScalaJsTest.scala | 6 +- .../scala/scoverage/ScoverageCompiler.scala | 61 ++++++++++++++++--- project/plugins.sbt | 2 + 5 files changed, 73 insertions(+), 17 deletions(-) diff --git a/build.sbt b/build.sbt index 4cd2320e..e24598d0 100644 --- a/build.sbt +++ b/build.sbt @@ -101,7 +101,8 @@ lazy val root = Project("scalac-scoverage", file(".")) runtimeJSDOMTest, reporter, domain, - serializer + serializer, + buildInfo ) lazy val runtime = CrossProject( @@ -136,7 +137,8 @@ lazy val runtimeJSDOMTest = lazy val plugin = project - .dependsOn(runtimeJVM % Test) + // we need both runtimes compiled prior to running tests + .dependsOn(runtimeJVM % Test, runtimeJS % Test) .settings( name := "scalac-scoverage-plugin", crossTarget := target.value / s"scala-${scalaVersion.value}", @@ -148,7 +150,7 @@ lazy val plugin = .settings( Test / unmanagedSourceDirectories += (Test / sourceDirectory).value / "scala-2.12+" ) - .dependsOn(domain, reporter % "test->compile", serializer) + .dependsOn(domain, reporter % "test->compile", serializer, buildInfo % Test) lazy val reporter = project @@ -169,6 +171,16 @@ lazy val reporter = ) .dependsOn(domain, serializer) +lazy val buildInfo = + project + .settings( + crossScalaVersions := bin212 ++ bin213, + buildInfoKeys += BuildInfoKey("scalaJSVersion", scalaJSVersion), + publishArtifact := false, + publishLocal := {} + ) + .enablePlugins(BuildInfoPlugin) + lazy val domain = project .settings( diff --git a/plugin/src/main/scala/scoverage/ScoveragePlugin.scala b/plugin/src/main/scala/scoverage/ScoveragePlugin.scala index b2b459ba..90235d7e 100644 --- a/plugin/src/main/scala/scoverage/ScoveragePlugin.scala +++ b/plugin/src/main/scala/scoverage/ScoveragePlugin.scala @@ -10,6 +10,7 @@ import scala.tools.nsc.plugins.Plugin import scala.tools.nsc.plugins.PluginComponent import scala.tools.nsc.transform.Transform import scala.tools.nsc.transform.TypingTransformers +import scala.util.control.NonFatal import scoverage.domain.Coverage import scoverage.domain.Statement @@ -102,7 +103,7 @@ class ScoverageInstrumentationComponent( try { rootMirror.getClassIfDefined("scala.scalajs.js.Any") != NoSymbol } catch { - case _: Throwable => false + case NonFatal(_) => false } } diff --git a/plugin/src/test/scala/scoverage/PluginCoverageScalaJsTest.scala b/plugin/src/test/scala/scoverage/PluginCoverageScalaJsTest.scala index a767202c..e4f94054 100644 --- a/plugin/src/test/scala/scoverage/PluginCoverageScalaJsTest.scala +++ b/plugin/src/test/scala/scoverage/PluginCoverageScalaJsTest.scala @@ -6,8 +6,8 @@ import munit.FunSuite */ class PluginCoverageScalaJsTest extends FunSuite with MacroSupport { - test("scoverage should ignore default undefined parameter".ignore) { - val compiler = ScoverageCompiler.default + test("scoverage should ignore default undefined parameter") { + val compiler = ScoverageCompiler.defaultJS compiler.compileCodeSnippet( """import scala.scalajs.js | @@ -16,6 +16,6 @@ class PluginCoverageScalaJsTest extends FunSuite with MacroSupport { |}""".stripMargin ) assert(!compiler.reporter.hasErrors) - compiler.assertNMeasuredStatements(4) + compiler.assertNMeasuredStatements(2) } } diff --git a/plugin/src/test/scala/scoverage/ScoverageCompiler.scala b/plugin/src/test/scala/scoverage/ScoverageCompiler.scala index 0bf79338..f06aba2c 100644 --- a/plugin/src/test/scala/scoverage/ScoverageCompiler.scala +++ b/plugin/src/test/scala/scoverage/ScoverageCompiler.scala @@ -11,6 +11,7 @@ import scala.tools.nsc.plugins.PluginComponent import scala.tools.nsc.transform.Transform import scala.tools.nsc.transform.TypingTransformers +import buildinfo.BuildInfo import scoverage.reporter.IOUtils private[scoverage] object ScoverageCompiler { @@ -24,9 +25,22 @@ private[scoverage] object ScoverageCompiler { def classPath: Seq[String] = getScalaJars.map( _.getAbsolutePath - ) :+ sbtCompileDir.getAbsolutePath :+ runtimeClasses.getAbsolutePath + ) :+ sbtCompileDir.getAbsolutePath :+ runtimeClasses("jvm").getAbsolutePath - def settings: Settings = { + def jsClassPath: Seq[String] = + getScalaJsJars.map( + _.getAbsolutePath + ) :+ sbtCompileDir.getAbsolutePath :+ runtimeClasses("js").getAbsolutePath + + def settings: Settings = settings(classPath) + + def jsSettings: Settings = { + val s = settings(jsClassPath) + s.plugin.value = List(getScalaJsCompilerJar.getAbsolutePath) + s + } + + def settings(classPath: Seq[String]): Settings = { val s = new scala.tools.nsc.Settings s.Xprint.value = List("all", "_") s.deprecation.value = true @@ -46,6 +60,11 @@ private[scoverage] object ScoverageCompiler { new ScoverageCompiler(settings, reporter) } + def defaultJS: ScoverageCompiler = { + val reporter = new scala.tools.nsc.reporters.ConsoleReporter(jsSettings) + new ScoverageCompiler(jsSettings, reporter) + } + def locationCompiler: LocationCompiler = { val reporter = new scala.tools.nsc.reporters.ConsoleReporter(settings) new LocationCompiler(settings, reporter) @@ -56,6 +75,19 @@ private[scoverage] object ScoverageCompiler { scalaJars.map(findScalaJar) } + private def getScalaJsJars: List[File] = + findJar( + "org.scala-js", + s"scalajs-library_$ShortScalaVersion", + BuildInfo.scalaJSVersion + ) :: getScalaJars + + private def getScalaJsCompilerJar: File = findJar( + "org.scala-js", + s"scalajs-compiler_$ScalaVersion", + BuildInfo.scalaJSVersion + ) + private def sbtCompileDir: File = { val dir = new File( s"./plugin/target/scala-$ScalaVersion/classes" @@ -67,20 +99,28 @@ private[scoverage] object ScoverageCompiler { dir } - private def runtimeClasses: File = new File( - s"./runtime/jvm/target/scala-$ScalaVersion/classes" + private def runtimeClasses(platform: String): File = new File( + s"./runtime/$platform/target/scala-$ScalaVersion/classes" ) private def findScalaJar(artifactId: String): File = - findIvyJar("org.scala-lang", artifactId, ScalaVersion) - .orElse(findCoursierJar(artifactId, ScalaVersion)) + findJar("org.scala-lang", artifactId, ScalaVersion) + + private def findJar( + groupId: String, + artifactId: String, + version: String + ): File = + findIvyJar(groupId, artifactId, version) + .orElse(findCoursierJar(groupId, artifactId, version)) .getOrElse { throw new FileNotFoundException( - s"Could not locate $artifactId/$ScalaVersion" + s"Could not locate $groupId:$artifactId:$version" ) } private def findCoursierJar( + groupId: String, artifactId: String, version: String ): Option[File] = { @@ -89,9 +129,10 @@ private[scoverage] object ScoverageCompiler { ".cache/coursier", // Linux "Library/Caches/Coursier", // MacOSX "AppData/Local/Coursier/cache" // Windows - ).map(loc => - s"$userHome/$loc/v1/https/repo1.maven.org/maven2/org/scala-lang/$artifactId/$version/$artifactId-$version.jar" - ) + ).map { loc => + val gid = groupId.replace('.', '/') + s"$userHome/$loc/v1/https/repo1.maven.org/maven2/$gid/$artifactId/$version/$artifactId-$version.jar" + } jarPaths.map(new File(_)).find(_.exists()) } diff --git a/project/plugins.sbt b/project/plugins.sbt index 54d4cc8d..f7e8a8e4 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -6,4 +6,6 @@ addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6") addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.33") +addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0") + libraryDependencies += "org.scala-js" %% "scalajs-env-jsdom-nodejs" % "1.1.0"