From df9e214c3a31cd6f0b44836d550738a2539dd0a2 Mon Sep 17 00:00:00 2001 From: Kamil Podsiadlo Date: Sat, 22 Jan 2022 11:46:27 +0100 Subject: [PATCH 1/4] build: cross compile Scala 3 & Scala Native Drop 3.0.x and pretend it never existed, use 3.1.x for JVM, JS and Native platforms --- build.sbt | 12 +++++++++--- project/plugins.sbt | 11 +++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/build.sbt b/build.sbt index b58f4aaf..0592412b 100644 --- a/build.sbt +++ b/build.sbt @@ -6,7 +6,7 @@ def previousVersion = "0.7.0" def scala213 = "2.13.6" def scala212 = "2.12.15" def scala211 = "2.11.12" -def scala3 = "3.0.1" +def scala3 = "3.1.1" def junitVersion = "4.13.2" def gcp = "com.google.cloud" % "google-cloud-storage" % "2.1.7" inThisBuild( @@ -49,8 +49,10 @@ addCommandAlias( ) val isPreScala213 = Set[Option[(Long, Long)]](Some((2, 11)), Some((2, 12))) val scala2Versions = List(scala213, scala212, scala211) + val scala3Versions = List(scala3) val allScalaVersions = scala2Versions ++ scala3Versions + def isNotScala211(v: Option[(Long, Long)]): Boolean = !v.contains((2, 11)) def isScala2(v: Option[(Long, Long)]): Boolean = v.exists(_._1 == 2) val isScala3Setting = Def.setting { @@ -126,18 +128,21 @@ lazy val mimaEnable: List[Def.Setting[_]] = List( else Set("org.scalameta" % moduleName.value % previousVersion) } ) + val sharedJVMSettings: List[Def.Setting[_]] = List( crossScalaVersions := allScalaVersions ) ++ mimaEnable + val sharedJSSettings: List[Def.Setting[_]] = List( skipIdeaSettings, crossScalaVersions := allScalaVersions.filterNot(_.startsWith("0.")) ) val sharedJSConfigure: Project => Project = _.disablePlugins(MimaPlugin) + val sharedNativeSettings: List[Def.Setting[_]] = List( skipIdeaSettings, - crossScalaVersions := scala2Versions + crossScalaVersions := allScalaVersions ) val sharedNativeConfigure: Project => Project = _.disablePlugins(ScalafixPlugin, MimaPlugin) @@ -273,7 +278,7 @@ lazy val munitScalacheck = crossProject(JSPlatform, JVMPlatform, NativePlatform) libraryDependencies += { val partialVersion = CrossVersion.partialVersion(scalaVersion.value) if (isNotScala211(partialVersion)) - "org.scalacheck" %%% "scalacheck" % "1.15.4" + "org.scalacheck" %%% "scalacheck" % "1.16.0" else "org.scalacheck" %%% "scalacheck" % "1.15.2" } @@ -287,6 +292,7 @@ lazy val munitScalacheck = crossProject(JSPlatform, JVMPlatform, NativePlatform) ) .jsConfigure(sharedJSConfigure) .jsSettings(sharedJSSettings) + lazy val munitScalacheckJVM = munitScalacheck.jvm lazy val munitScalacheckJS = munitScalacheck.js lazy val munitScalacheckNative = munitScalacheck.native diff --git a/project/plugins.sbt b/project/plugins.sbt index 077a8ee3..b1041afa 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -3,10 +3,13 @@ addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.10.0") addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.2.23") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.3") addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.31") -addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.1.0") -addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.1.0") -addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.0") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.6.0") + +addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.9.0") + +addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.2.0") +addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.4") + addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.0.1") addSbtPlugin("com.lightbend.sbt" % "sbt-java-formatter" % "0.6.1") From 0c156f0da3d14cb40df5c1c51d3b23b6f9854705 Mon Sep 17 00:00:00 2001 From: Kamil Podsiadlo Date: Sat, 22 Jan 2022 11:54:09 +0100 Subject: [PATCH 2/4] refactor: unify usage of parens for Scala 3 Scala 3 doesn't allow to call method with parentheses without them. Normally class can extends trait/interface and overwrite their def's using val/override val no matter if def was declared with or without parentheses. However for Scala 3 this is no llonger true. This PR uses a workaround with underscores. --- .../src/main/scala/munit/Framework.scala | 6 ++--- .../junitinterface/CustomFingerprint.scala | 3 ++- .../internal/junitinterface/JUnitEvent.scala | 17 +++++++++----- .../junitinterface/JUnitFramework.scala | 2 +- .../junitinterface/JUnitReporter.scala | 4 ++-- .../internal/junitinterface/JUnitRunner.scala | 22 +++++++++++++------ .../internal/junitinterface/JUnitTask.scala | 9 ++++---- 7 files changed, 39 insertions(+), 24 deletions(-) diff --git a/munit/non-jvm/src/main/scala/munit/Framework.scala b/munit/non-jvm/src/main/scala/munit/Framework.scala index 6bbc0a76..e994efe4 100644 --- a/munit/non-jvm/src/main/scala/munit/Framework.scala +++ b/munit/non-jvm/src/main/scala/munit/Framework.scala @@ -5,12 +5,12 @@ import munit.internal.junitinterface.CustomRunners import munit.internal.junitinterface.JUnitFramework class Framework extends JUnitFramework { - override val name = "munit" - val munitFingerprint = new CustomFingerprint("munit.Suite", isModule = false) + override def name(): String = "munit" + val munitFingerprint = new CustomFingerprint("munit.Suite", _isModule = false) val customRunners = new CustomRunners( List( munitFingerprint, - new CustomFingerprint("munit.Suite", isModule = true) + new CustomFingerprint("munit.Suite", _isModule = true) ) ) } diff --git a/munit/non-jvm/src/main/scala/munit/internal/junitinterface/CustomFingerprint.scala b/munit/non-jvm/src/main/scala/munit/internal/junitinterface/CustomFingerprint.scala index 6d8e1aea..1d845208 100644 --- a/munit/non-jvm/src/main/scala/munit/internal/junitinterface/CustomFingerprint.scala +++ b/munit/non-jvm/src/main/scala/munit/internal/junitinterface/CustomFingerprint.scala @@ -4,8 +4,9 @@ import sbt.testing.SubclassFingerprint class CustomFingerprint( val suite: String, - val isModule: Boolean + _isModule: Boolean ) extends SubclassFingerprint { + override def isModule(): Boolean = _isModule override def superclassName(): String = suite override def requireNoArgConstructor(): Boolean = true } diff --git a/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitEvent.scala b/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitEvent.scala index 291b9c59..cf033e85 100644 --- a/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitEvent.scala +++ b/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitEvent.scala @@ -8,11 +8,16 @@ import sbt.testing._ final class JUnitEvent( taskDef: TaskDef, - val fullyQualifiedName: String, - val status: Status, - val selector: Selector, - val throwable: OptionalThrowable = new OptionalThrowable, - val duration: Long = -1L + _fullyQualifiedName: String, + _status: Status, + _selector: Selector, + _throwable: OptionalThrowable = new OptionalThrowable, + _duration: Long = -1L ) extends Event { - def fingerprint: Fingerprint = taskDef.fingerprint + override def status(): Status = _status + override def selector(): Selector = _selector + override def throwable(): OptionalThrowable = _throwable + override def duration(): Long = _duration + override def fullyQualifiedName(): String = _fullyQualifiedName + override def fingerprint(): Fingerprint = taskDef.fingerprint() } diff --git a/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitFramework.scala b/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitFramework.scala index 1ea9510e..c35d0192 100644 --- a/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitFramework.scala +++ b/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitFramework.scala @@ -8,7 +8,7 @@ import sbt.testing._ abstract class JUnitFramework extends Framework { - val name: String = "Scala.js JUnit test framework" + override def name(): String = "Scala.js JUnit test framework" def customRunners: CustomRunners diff --git a/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitReporter.scala b/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitReporter.scala index a88d60eb..be7e5a2c 100644 --- a/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitReporter.scala +++ b/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitReporter.scala @@ -91,7 +91,7 @@ final class JUnitReporter( throwable: OptionalThrowable = new OptionalThrowable ): Unit = { val testName = - taskDef.fullyQualifiedName + "." + + taskDef.fullyQualifiedName() + "." + settings.decodeName(method) val selector = new TestSelector(testName) eventHandler.handle( @@ -215,7 +215,7 @@ final class JUnitReporter( private def findTestFileName(trace: Array[StackTraceElement]): String = trace - .find(_.getClassName == taskDef.fullyQualifiedName) + .find(_.getClassName == taskDef.fullyQualifiedName()) .map(_.getFileName) .orNull diff --git a/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitRunner.scala b/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitRunner.scala index 43eb1294..59cef135 100644 --- a/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitRunner.scala +++ b/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitRunner.scala @@ -9,23 +9,31 @@ import munit.internal.PlatformCompat final class JUnitRunner( val args: Array[String], - val remoteArgs: Array[String], + _remoteArgs: Array[String], runSettings: RunSettings, classLoader: ClassLoader, customRunners: CustomRunners ) extends Runner { PlatformCompat.setThisClassLoader(classLoader) - def tasks(taskDefs: Array[TaskDef]): Array[Task] = + override def remoteArgs(): Array[String] = _remoteArgs + + override def tasks(taskDefs: Array[TaskDef]): Array[Task] = taskDefs.map(new JUnitTask(_, runSettings, classLoader)) - def done(): String = "" + override def done(): String = "" - def serializeTask(task: Task, serializer: TaskDef => String): String = - serializer(task.taskDef) + override def serializeTask( + task: Task, + serializer: TaskDef => String + ): String = + serializer(task.taskDef()) - def deserializeTask(task: String, deserializer: String => TaskDef): Task = + override def deserializeTask( + task: String, + deserializer: String => TaskDef + ): Task = new JUnitTask(deserializer(task), runSettings, classLoader) - def receiveMessage(msg: String): Option[String] = None + override def receiveMessage(msg: String): Option[String] = None } diff --git a/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitTask.scala b/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitTask.scala index d866a8af..780b768f 100644 --- a/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitTask.scala +++ b/munit/non-jvm/src/main/scala/munit/internal/junitinterface/JUnitTask.scala @@ -16,12 +16,13 @@ import scala.concurrent.ExecutionContext.Implicits.global * under the hood and stay consistent with JVM JUnit. */ final class JUnitTask( - val taskDef: TaskDef, + _taskDef: TaskDef, runSettings: RunSettings, classLoader: ClassLoader ) extends Task { - def tags: Array[String] = Array.empty + override def taskDef(): TaskDef = _taskDef + override def tags(): Array[String] = Array.empty def execute( eventHandler: EventHandler, @@ -36,12 +37,12 @@ final class JUnitTask( loggers: Array[Logger], continuation: Array[Task] => Unit ): Unit = { - PlatformCompat.newRunner(taskDef, classLoader) match { + PlatformCompat.newRunner(taskDef(), classLoader) match { case None => case Some(runner) => runner.filter(runSettings.tags) val reporter = - new JUnitReporter(eventHandler, loggers, runSettings, taskDef) + new JUnitReporter(eventHandler, loggers, runSettings, taskDef()) val notifier: RunNotifier = new MUnitRunNotifier(reporter) runner.runAsync(notifier).foreach(_ => continuation(Array())) } From 02d787805a042aa9285595a6e99539984deb8a8e Mon Sep 17 00:00:00 2001 From: Kamil Podsiadlo Date: Fri, 8 Apr 2022 10:10:37 +0200 Subject: [PATCH 3/4] fix: add necessary parens to method calls --- .../scala/munit/ScalaCheckExceptionFrameworkSuite.scala | 6 +++--- .../src/test/scala/munit/ComparisonFailExceptionSuite.scala | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/shared/src/main/scala/munit/ScalaCheckExceptionFrameworkSuite.scala b/tests/shared/src/main/scala/munit/ScalaCheckExceptionFrameworkSuite.scala index 3ecc85bc..956ea96f 100644 --- a/tests/shared/src/main/scala/munit/ScalaCheckExceptionFrameworkSuite.scala +++ b/tests/shared/src/main/scala/munit/ScalaCheckExceptionFrameworkSuite.scala @@ -52,12 +52,12 @@ class ScalaCheckExceptionFrameworkSuites tags = Set(OnlyJVM), onEvent = { event => if ( - event.throwable.isDefined && - event.throwable().get.getCause() != null + event.throwable().isDefined() && + event.throwable().get().getCause() != null ) { event .throwable() - .get + .get() .getCause .getStackTrace() .take(2) diff --git a/tests/shared/src/test/scala/munit/ComparisonFailExceptionSuite.scala b/tests/shared/src/test/scala/munit/ComparisonFailExceptionSuite.scala index 63ac009d..e657c015 100644 --- a/tests/shared/src/test/scala/munit/ComparisonFailExceptionSuite.scala +++ b/tests/shared/src/test/scala/munit/ComparisonFailExceptionSuite.scala @@ -20,11 +20,11 @@ class ComparisonFailExceptionSuite extends BaseSuite { // console still uses `munitPrint()`, which would have displayed `List("1", // "2", "3")` instead of `List(1, 2, 3)`. assertNoDiff( - e.getActual, + e.getActual(), "List(1, 2, 3)" ) assertNoDiff( - e.getExpected, + e.getExpected(), "List(1, 2)" ) assertEquals(e.expected, List(1, 2)) From 20a2c540082d8c02cf961e75da9c1cc0a901eca3 Mon Sep 17 00:00:00 2001 From: Kamil Podsiadlo Date: Sat, 9 Apr 2022 15:06:27 +0200 Subject: [PATCH 4/4] fix, js: remove `Pattern.MULTILINE` from regex. More information can be found at https://www.scala-js.org/news/2021/08/04/announcing-scalajs-1.7.0/#fixes-with-compatibility-concerns --- tests/shared/src/test/scala/munit/BaseFrameworkSuite.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/shared/src/test/scala/munit/BaseFrameworkSuite.scala b/tests/shared/src/test/scala/munit/BaseFrameworkSuite.scala index b24cd9e9..4393393b 100644 --- a/tests/shared/src/test/scala/munit/BaseFrameworkSuite.scala +++ b/tests/shared/src/test/scala/munit/BaseFrameworkSuite.scala @@ -82,8 +82,7 @@ abstract class BaseFrameworkSuite extends BaseSuite { } } implicit val ec = munitExecutionContext - val elapsedTimePattern = - Pattern.compile(" \\d+\\.\\d+s ?", Pattern.MULTILINE) + val elapsedTimePattern = Pattern.compile(" \\d+\\.\\d+s ?") TestingConsole.out = out TestingConsole.err = out for {