diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c195f08..35382366 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,7 @@ jobs: steps: - uses: actions/checkout@v2 - uses: olafurpg/setup-scala@v10 - - run: csbt +testsJVM/test + - run: sbt +testsJVM/test shell: bash env: GOOGLE_APPLICATION_CREDENTIALS: diff --git a/.gitignore b/.gitignore index 7144b1ae..0115f506 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ src_managed/ project/boot/ project/plugins/project/ .bloop +.bsp _site/ diff --git a/build.sbt b/build.sbt index 7a2fbc07..89609cda 100644 --- a/build.sbt +++ b/build.sbt @@ -37,14 +37,11 @@ inThisBuild( ) ), scalaVersion := scala213, - testFrameworks := List( - new TestFramework("munit.Framework") - ), useSuperShell := false ) ) -skip in publish := true +publish / skip := true mimaPreviousArtifacts := Set.empty crossScalaVersions := List() addCommandAlias( @@ -68,7 +65,8 @@ val isScala3Setting = Def.setting { def isScala3(v: Option[(Long, Long)]): Boolean = v.exists(_._1 != 2) // NOTE(olafur): disable Scala.js and Native settings for IntelliJ. -lazy val skipIdeaSettings = SettingKey[Boolean]("ide-skip-project") := true +lazy val skipIdeaSettings = + SettingKey[Boolean]("ide-skip-project").withRank(KeyRanks.Invisible) := true lazy val mimaEnable: List[Def.Setting[_]] = List( mimaBinaryIssueFilters ++= List( ProblemFilters.exclude[DirectMissingMethodProblem]( @@ -138,9 +136,7 @@ val sharedSettings = List( "-Ywarn-unused:imports" ) } - }, - // see - Test / scalacOptions := (Compile / scalacOptions).value + } ) lazy val junit = project @@ -157,15 +153,15 @@ lazy val junit = project "junit" % "junit" % junitVersion, "org.scala-sbt" % "test-interface" % "1.0" ), - javacOptions in Compile ++= List("-target", "1.8", "-source", "1.8"), - javacOptions in (Compile, doc) --= List("-target", "1.8") + Compile / javacOptions ++= List("-target", "1.8", "-source", "1.8"), + Compile / doc / javacOptions --= List("-target", "1.8") ) lazy val munit = crossProject(JSPlatform, JVMPlatform, NativePlatform) .settings( sharedSettings, - unmanagedSourceDirectories.in(Compile) ++= { - val root = baseDirectory.in(ThisBuild).value / "munit" + Compile / unmanagedSourceDirectories ++= { + val root = (ThisBuild / baseDirectory).value / "munit" val base = root / "shared" / "src" / "main" val result = mutable.ListBuffer.empty[File] val partialVersion = CrossVersion.partialVersion(scalaVersion.value) @@ -196,22 +192,20 @@ lazy val munit = crossProject(JSPlatform, JVMPlatform, NativePlatform) libraryDependencies ++= List( "org.scala-native" %%% "test-interface" % scalaNativeVersion ), - unmanagedSourceDirectories.in(Compile) += baseDirectory - .in(ThisBuild) - .value / "munit" / "non-jvm" / "src" / "main" + Compile / unmanagedSourceDirectories += + (ThisBuild / baseDirectory).value / "munit" / "non-jvm" / "src" / "main" ) .jsConfigure(sharedJSConfigure) .jsSettings( sharedJSSettings, libraryDependencies ++= List( ("org.scala-js" %% "scalajs-test-interface" % scalaJSVersion) - .withDottyCompat(scalaVersion.value), + .cross(CrossVersion.for3Use2_13), ("org.scala-js" %% "scalajs-junit-test-runtime" % scalaJSVersion) - .withDottyCompat(scalaVersion.value) + .cross(CrossVersion.for3Use2_13) ), - unmanagedSourceDirectories.in(Compile) += baseDirectory - .in(ThisBuild) - .value / "munit" / "non-jvm" / "src" / "main" + Compile / unmanagedSourceDirectories += + (ThisBuild / baseDirectory).value / "munit" / "non-jvm" / "src" / "main" ) .jvmSettings( sharedJVMSettings, @@ -279,10 +273,10 @@ lazy val tests = crossProject(JSPlatform, JVMPlatform, NativePlatform) buildInfoPackage := "munit", buildInfoKeys := Seq[BuildInfoKey]( "sourceDirectory" -> - baseDirectory.in(ThisBuild).value / "tests" / "shared" / "src" / "main", + (ThisBuild / baseDirectory).value / "tests" / "shared" / "src" / "main", scalaVersion ), - skip in publish := true + publish / skip := true ) .nativeConfigure(sharedNativeConfigure) .nativeSettings(sharedNativeSettings) @@ -300,23 +294,15 @@ lazy val testsNative = tests.native lazy val docs = project .in(file("munit-docs")) .dependsOn(munitJVM, munitScalacheckJVM) - .enablePlugins(MdocPlugin, MUnitReportPlugin, DocusaurusPlugin) + .enablePlugins(MdocPlugin, DocusaurusPlugin) .disablePlugins(MimaPlugin) .settings( sharedSettings, moduleName := "munit-docs", crossScalaVersions := List(scala213, scala212), - unmanagedSources.in(Compile) += sourceDirectory - .in(plugin, Compile) - .value / "scala" / "munit" / "sbtmunit" / "MUnitTestReport.scala", - libraryDependencies ++= List( - "org.scala-lang.modules" %% "scala-xml" % "2.0.0-RC1", - gcp - ), test := {}, - munitRepository := Some("scalameta/munit"), mdocOut := - baseDirectory.in(ThisBuild).value / "website" / "target" / "docs", + (ThisBuild / baseDirectory).value / "website" / "target" / "docs", mdocExtraArguments := List("--no-link-hygiene"), mdocVariables := Map( "VERSION" -> version.value.replaceFirst("\\+.*", ""), @@ -326,3 +312,7 @@ lazy val docs = project ), fork := false ) + +Global / excludeLintKeys ++= Set( + mimaPreviousArtifacts +) diff --git a/docs/getting-started.md b/docs/getting-started.md index 8b3176b9..0d58e83a 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -26,6 +26,11 @@ MUnit is a Scala testing library with the following goals: ```scala libraryDependencies += "org.scalameta" %% "munit" % "@VERSION@" % Test // Use %%% for non-JVM projects. +``` + +If you are using a version of sbt lower than 1.5.0, you will also need to add: + +```scala testFrameworks += new TestFramework("munit.Framework") ``` diff --git a/munit-docs/src/main/java/munit/docs/StorageProxy.java b/munit-docs/src/main/java/munit/docs/StorageProxy.java deleted file mode 100644 index 48666517..00000000 --- a/munit-docs/src/main/java/munit/docs/StorageProxy.java +++ /dev/null @@ -1,12 +0,0 @@ -package munit.docs; - -import java.util.*; -import com.google.cloud.storage.*; -import com.google.cloud.storage.Storage.BlobListOption; -import com.google.api.gax.paging.Page; - -public class StorageProxy { - public static Page list(Storage storage, String bucketName, String prefix) { - return storage.list(bucketName, BlobListOption.pageSize(1000), BlobListOption.prefix(prefix)); - } -} diff --git a/munit-docs/src/main/resources/META-INF/services/mdoc.PreModifier b/munit-docs/src/main/resources/META-INF/services/mdoc.PreModifier deleted file mode 100644 index b4de4315..00000000 --- a/munit-docs/src/main/resources/META-INF/services/mdoc.PreModifier +++ /dev/null @@ -1 +0,0 @@ -docs.MUnitModifier diff --git a/munit-docs/src/main/scala/docs/MUnitModifier.scala b/munit-docs/src/main/scala/docs/MUnitModifier.scala deleted file mode 100644 index 3e2dc547..00000000 --- a/munit-docs/src/main/scala/docs/MUnitModifier.scala +++ /dev/null @@ -1,200 +0,0 @@ -package docs - -import munit.docs.StorageProxy -import mdoc.PreModifier -import mdoc.PreModifierContext -import scala.util.control.NonFatal -import java.{util => ju} -import com.google.cloud.storage.StorageException -import com.google.cloud.storage.StorageOptions -import scala.collection.mutable -import scala.collection.JavaConverters._ -import com.google.cloud.storage.Blob -import java.io.ByteArrayOutputStream -import com.google.gson.Gson -import java.nio.charset.StandardCharsets -import munit.sbtmunit.MUnitTestReport -import sbt.testing.Status -import munit.TestValues.FlakyFailure - -class MUnitModifier extends PreModifier { - val name: String = "munit" - def process(ctx: PreModifierContext): String = { - html.getOrElse { - ctx.reporter.warning("Unable to generate MUnit HTML test report.") - "" - } - } - - private val properties: Map[String, String] = - try { - val props = new ju.Properties() - props.load( - this - .getClass() - .getClassLoader() - .getResourceAsStream("munit.properties") - ) - val m = mutable.Map.empty[String, String] - props.forEach((k, v) => m(k.toString()) = v.toString()) - m.toMap - } catch { - case NonFatal(e) => - e.printStackTrace() - Map.empty - } - lazy val html: Option[String] = - try { - for { - bucketName <- properties.get("munitBucketName") - repository <- properties.get("munitRepository") - } yield { - val storage = StorageOptions.getDefaultInstance().getService() - val blobs = StorageProxy - .list(storage, bucketName, repository) - .iterateAll() - .asScala - renderHtml(blobs) - } - } catch { - case NonFatal(e) => - e match { - case s: StorageException - if e.getMessage() != "Anonymous caller does not have storage.objects.list access to munit-test-reports" => - case _ => - e.printStackTrace() - } - None - } - - private def downloadBlob(blob: Blob): Option[MUnitTestReport.Summary] = { - try { - val out = new ByteArrayOutputStream() - blob.downloadTo(out) - val summary = new Gson().fromJson( - new String(out.toByteArray(), StandardCharsets.UTF_8), - classOf[MUnitTestReport.Summary] - ) - Some(summary) - } catch { - case NonFatal(e) => - e.printStackTrace() - None - } - } - - private def renderHtml(blobs: Iterable[Blob]): String = { - val tests = - mutable.Map.empty[String, mutable.ArrayBuffer[MUnitTestReport.TestEvent]] - for { - blob <- blobs.iterator - summary <- downloadBlob(blob).iterator - group <- summary.groups.iterator - event <- group.events.toIterable - } { - val buffer = - tests.getOrElseUpdate(event.name, mutable.ArrayBuffer.empty) - buffer += event - } - val statuses = Array( - Status.Success, - Status.Failure, - Status.Skipped, - Status.Ignored - ) - val statusHeaders = statuses.map(s => {s}) - val keys = tests.keys.toIndexedSeq.sorted - val testRows = keys.map { name => - val events = tests(name) - val statusMap = events.groupBy(_.status).mapValues(_.size) - val passedCount = statusMap.getOrElse(Status.Success.toString(), 0) - val errorCount = statusMap.getOrElse(Status.Failure.toString(), 0) - val flakyCount = events.count { event => - event.exception != null && - Status.Skipped.toString == event.status && - classOf[FlakyFailure].getName() == event.exception.className - } - val skippedCount = - statusMap.getOrElse(Status.Skipped.toString(), 0) - flakyCount - val ignoredCount = statusMap.getOrElse(Status.Ignored.toString(), 0) - val statusColumns = statuses.map { s => - statusMap.getOrElse(s.toString(), 0) - } - val otherCount = events.length - - passedCount - - errorCount - - flakyCount - - skippedCount - - ignoredCount - val flakyRatio: Double = - if (events.length == 0) 0 - else { - val r = (errorCount + flakyCount).toDouble / events.length - if (r == 0) 0 - else r - } - val totalCount = events.length - val averageDuration = - if (totalCount == 0) 0 - else events.iterator.map(_.duration).filter(_ >= 0).sum / totalCount - val shortName = - if (name.length() > 80) name.take(80) + "..." - else name - - {shortName} - {averageDuration} - {passedCount} - {errorCount} - {flakyCount} - {flakyRatio} - {skippedCount} - {ignoredCount} - {otherCount} - - } - val table = - - - - - - - - - - - - - - - - - {testRows} - -
NameDPEFRSIO
- s""" - - - - -**D**: Average duration in milliseconds, -**P**: Passed, -**E**: Failed, -**F**: Flaky, -**R**: Flaky/Passed ratio, -**S**: Skipped, -**I**: Ignored, -**O**: Other - -$table - - -""" - } -} diff --git a/munit-sbt/src/main/scala/munit/sbtmunit/MUnitReportPlugin.scala b/munit-sbt/src/main/scala/munit/sbtmunit/MUnitReportPlugin.scala index 150d5192..1ac615e8 100644 --- a/munit-sbt/src/main/scala/munit/sbtmunit/MUnitReportPlugin.scala +++ b/munit-sbt/src/main/scala/munit/sbtmunit/MUnitReportPlugin.scala @@ -11,9 +11,9 @@ object MUnitReportPlugin extends AutoPlugin { if ("unknown" == BuildInfo.munitVersion) Nil else List("org.scalameta" %% "munit-docs" % BuildInfo.munitVersion) }, - resourceGenerators.in(Compile) += Def.task[List[File]] { + Compile / resourceGenerators += Def.task[List[File]] { val out = - managedResourceDirectories.in(Compile).value.head / "munit.properties" + (Compile / managedResourceDirectories).value.head / "munit.properties" val props = new java.util.Properties() munitRepository.value.foreach { repo => props.put("munitRepository", repo) diff --git a/project/build.properties b/project/build.properties index dbae93bc..e67343ae 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.4.9 +sbt.version=1.5.0 diff --git a/project/plugins.sbt b/project/plugins.sbt index dac841f5..101dcdde 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,7 +2,6 @@ addSbtPlugin("com.geirsson" % "sbt-ci-release" % "1.5.7") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.10.0") addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.2.19") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.3.4") -addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.5.4") addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.27") addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.0.0") addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.0.0") @@ -11,7 +10,3 @@ addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.5.1") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.8.1") libraryDependencies += "com.google.cloud" % "google-cloud-storage" % "1.113.13" - -unmanagedSourceDirectories.in(Compile) += - baseDirectory.in(ThisBuild).value.getParentFile / - "munit-sbt" / "src" / "main" / "scala"