diff --git a/.scalafmt.conf b/.scalafmt.conf index 60771025..00ceef68 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -31,3 +31,9 @@ project.git = true project.excludeFilters = [ ".*-scala-3.*" ] + +fileOverride { + "glob:**/scala-3/**" { + runner.dialect = scala3 + } +} diff --git a/build.sbt b/build.sbt index 23524a28..a57a6272 100644 --- a/build.sbt +++ b/build.sbt @@ -1,3 +1,5 @@ +import sbt.librarymanagement.Configurations.ScalaDocTool + // https://typelevel.org/sbt-typelevel/faq.html#what-is-a-base-version-anyway ThisBuild / tlBaseVersion := "0.0" // your current series x.y @@ -25,18 +27,19 @@ ThisBuild / crossScalaVersions := Seq(scala212, scala213, "3.3.1") ThisBuild / scalaVersion := scala213 // the default Scala val Version = new { - val catsEffect = "3.5.2" - val catsLaws = "2.9.0" - val discipline = "1.5.1" - val expecty = "0.16.0" - val fs2 = "3.5.0" - val junit = "4.13.2" - val portableReflect = "1.1.2" - val scalaJavaTime = "2.4.0" - val scalacheck = "1.17.0" - val scalajsMacroTask = "1.1.1" - val scalajsStubs = "1.1.0" - val testInterface = "1.0" + val catsEffect = "3.5.2" + val catsLaws = "2.9.0" + val discipline = "1.5.1" + val expecty = "0.16.0" + val fs2 = "3.5.0" + val junit = "4.13.2" + val portableReflect = "1.1.2" + val scalaJavaTime = "2.4.0" + val scalacheck = "1.17.0" + val scalajsMacroTask = "1.1.1" + val scalajsStubs = "1.1.0" + val testInterface = "1.0" + val scalacCompatAnnotation = "0.1.4" } lazy val root = tlCrossRootProject.aggregate(core, @@ -55,7 +58,8 @@ lazy val core = crossProject(JVMPlatform, JSPlatform, NativePlatform) "org.typelevel" %%% "cats-effect" % Version.catsEffect, "com.eed3si9n.expecty" %%% "expecty" % Version.expecty, // https://github.com/portable-scala/portable-scala-reflect/issues/23 - "org.portable-scala" %%% "portable-scala-reflect" % Version.portableReflect cross CrossVersion.for3Use2_13 + "org.portable-scala" %%% "portable-scala-reflect" % Version.portableReflect cross CrossVersion.for3Use2_13, + "org.typelevel" %% "scalac-compat-annotation" % Version.scalacCompatAnnotation ) ) @@ -106,6 +110,11 @@ lazy val frameworkNative = framework.native lazy val coreCats = crossProject(JVMPlatform, JSPlatform, NativePlatform) .in(file("modules/core-cats")) .dependsOn(core) + .settings( + libraryDependencies ++= Seq( + "junit" % "junit" % Version.junit % ScalaDocTool + ) + ) .settings(name := "cats-core") lazy val coreCatsJS = coreCats.js diff --git a/modules/core/js/src/main/scala/org/junit/runner/RunWith.scala b/modules/core/js/src/main/scala/org/junit/runner/RunWith.scala index 98c3708b..02389224 100644 --- a/modules/core/js/src/main/scala/org/junit/runner/RunWith.scala +++ b/modules/core/js/src/main/scala/org/junit/runner/RunWith.scala @@ -1,6 +1,9 @@ package org.junit.runner +import org.typelevel.scalaccompat.annotation.unused + /** * Stub used for cross-compilation */ -class RunWith[T](cls: Class[T]) extends scala.annotation.StaticAnnotation +class RunWith[T](@unused cls: Class[T]) + extends scala.annotation.StaticAnnotation diff --git a/modules/core/js/src/main/scala/weaver/PlatformCompat.scala b/modules/core/js/src/main/scala/weaver/PlatformCompat.scala index d1f4679e..f331a229 100644 --- a/modules/core/js/src/main/scala/weaver/PlatformCompat.scala +++ b/modules/core/js/src/main/scala/weaver/PlatformCompat.scala @@ -1,8 +1,8 @@ package weaver - +import org.typelevel.scalaccompat.annotation.unused private[weaver] object PlatformCompat { val platform: Platform = Platform.JS - def getClassLoader(clazz: java.lang.Class[_]): ClassLoader = + def getClassLoader(@unused clazz: java.lang.Class[_]): ClassLoader = new ClassLoader() {} } diff --git a/modules/core/jvm/src/main/scala/weaver/junit/WeaverRunner.scala b/modules/core/jvm/src/main/scala/weaver/junit/WeaverRunner.scala index f77fcbd9..358f374b 100644 --- a/modules/core/jvm/src/main/scala/weaver/junit/WeaverRunner.scala +++ b/modules/core/jvm/src/main/scala/weaver/junit/WeaverRunner.scala @@ -1,13 +1,15 @@ package weaver package junit +import org.typelevel.scalaccompat.annotation.unused + import weaver.TestStatus._ import weaver.internals.Reflection import org.junit.runner.Description import org.junit.runner.notification.RunNotifier -class WeaverRunner(cls: Class[_], dummy: Boolean) +class WeaverRunner(cls: Class[_], @unused dummy: Boolean) extends org.junit.runner.Runner { type F[A] = Any diff --git a/modules/core/native/src/main/scala/org/junit/runner/RunWith.scala b/modules/core/native/src/main/scala/org/junit/runner/RunWith.scala index 98c3708b..0ba6ff2c 100644 --- a/modules/core/native/src/main/scala/org/junit/runner/RunWith.scala +++ b/modules/core/native/src/main/scala/org/junit/runner/RunWith.scala @@ -1,6 +1,8 @@ package org.junit.runner +import org.typelevel.scalaccompat.annotation.unused /** * Stub used for cross-compilation */ -class RunWith[T](cls: Class[T]) extends scala.annotation.StaticAnnotation +class RunWith[T](@unused cls: Class[T]) + extends scala.annotation.StaticAnnotation diff --git a/modules/core/native/src/main/scala/weaver/PlatformCompat.scala b/modules/core/native/src/main/scala/weaver/PlatformCompat.scala index f981fbf9..7d588b18 100644 --- a/modules/core/native/src/main/scala/weaver/PlatformCompat.scala +++ b/modules/core/native/src/main/scala/weaver/PlatformCompat.scala @@ -1,8 +1,9 @@ package weaver +import org.typelevel.scalaccompat.annotation.unused private[weaver] object PlatformCompat { val platform: Platform = Platform.Native - def getClassLoader(clazz: java.lang.Class[_]): ClassLoader = + def getClassLoader(@unused clazz: java.lang.Class[_]): ClassLoader = new ClassLoader() {} } diff --git a/modules/core/shared/src/main/scala-3/weaver/Expect.scala b/modules/core/shared/src/main/scala-3/weaver/Expect.scala index 6aa396a0..dfc9f4bb 100644 --- a/modules/core/shared/src/main/scala-3/weaver/Expect.scala +++ b/modules/core/shared/src/main/scala-3/weaver/Expect.scala @@ -1,8 +1,5 @@ package weaver -import cats.data.{ NonEmptyList, ValidatedNel } -import cats.syntax.all._ - import com.eed3si9n.expecty._ import internals._ diff --git a/modules/core/shared/src/main/scala/weaver/Test.scala b/modules/core/shared/src/main/scala/weaver/Test.scala index 397ee715..56a9be4a 100644 --- a/modules/core/shared/src/main/scala/weaver/Test.scala +++ b/modules/core/shared/src/main/scala/weaver/Test.scala @@ -40,6 +40,6 @@ object Test { def apply[F[_]](name: String, f: F[Expectations])( implicit F: EffectCompat[F] - ): F[TestOutcome] = apply(name, (_: Log[F]) => f) + ): F[TestOutcome] = apply[F](name, (_: Log[F]) => f) } diff --git a/modules/core/shared/src/main/scala/weaver/suites.scala b/modules/core/shared/src/main/scala/weaver/suites.scala index b3a118f8..975ebbf7 100644 --- a/modules/core/shared/src/main/scala/weaver/suites.scala +++ b/modules/core/shared/src/main/scala/weaver/suites.scala @@ -7,8 +7,8 @@ import cats.effect.{ Async, Resource } import cats.syntax.all._ import fs2.Stream -import org.junit.runner.RunWith import org.portablescala.reflect.annotation.EnableReflectiveInstantiation +import org.junit.runner.RunWith // Just a non-parameterized marker trait to help SBT's test detection logic. @EnableReflectiveInstantiation @@ -131,13 +131,13 @@ abstract class MutableFSuite[F[_]] extends RunnableSuite[F] { } def pureTest(name: TestName)(run : => Expectations) : Unit = registerTest(name)(_ => Test(name.name, effectCompat.effect.delay(run))) - def loggedTest(name: TestName)(run: Log[F] => F[Expectations]) : Unit = registerTest(name)(_ => Test(name.name, log => run(log))) + def loggedTest(name: TestName)(run: Log[F] => F[Expectations]) : Unit = registerTest(name)(_ => Test[F](name.name, log => run(log))) def test(name: TestName) : PartiallyAppliedTest = new PartiallyAppliedTest(name) class PartiallyAppliedTest(name : TestName) { def apply(run: => F[Expectations]) : Unit = registerTest(name)(_ => Test(name.name, run)) def apply(run : Res => F[Expectations]) : Unit = registerTest(name)(res => Test(name.name, run(res))) - def apply(run : (Res, Log[F]) => F[Expectations]) : Unit = registerTest(name)(res => Test(name.name, log => run(res, log))) + def apply(run : (Res, Log[F]) => F[Expectations]) : Unit = registerTest(name)(res => Test[F](name.name, log => run(res, log))) // this alias helps using pattern matching on `Res` def usingRes(run : Res => F[Expectations]) : Unit = apply(run) diff --git a/modules/framework-cats/jvm/src/test/scala/MetaJVM.scala b/modules/framework-cats/jvm/src/test/scala/MetaJVM.scala index d21d8dcc..e49e0d2d 100644 --- a/modules/framework-cats/jvm/src/test/scala/MetaJVM.scala +++ b/modules/framework-cats/jvm/src/test/scala/MetaJVM.scala @@ -132,7 +132,7 @@ object MetaJVM { } } - abstract class LazyAccessSequential(global: GlobalRead, index: Int) + abstract class LazyAccessSequential(global: GlobalRead) extends IOSuite { type Res = LazyState def sharedResource: Resource[IO, Res] = { @@ -157,10 +157,10 @@ object MetaJVM { // Using sleeps to force sequential runs of suites class LazyAccessSequential0(global: GlobalRead) - extends LazyAccessSequential(global, 0) + extends LazyAccessSequential(global) class LazyAccessSequential1(global: GlobalRead) - extends LazyAccessSequential(global, 1) + extends LazyAccessSequential(global) class LazyAccessSequential2(global: GlobalRead) - extends LazyAccessSequential(global, 2) + extends LazyAccessSequential(global) } diff --git a/modules/framework-cats/shared/src/test/scala/Meta.scala b/modules/framework-cats/shared/src/test/scala/Meta.scala index e6079933..90ddd5c8 100644 --- a/modules/framework-cats/shared/src/test/scala/Meta.scala +++ b/modules/framework-cats/shared/src/test/scala/Meta.scala @@ -2,7 +2,7 @@ package weaver package framework package test -import scala.annotation.nowarn +import org.typelevel.scalaccompat.annotation._ import cats.effect._ @@ -14,7 +14,7 @@ object Meta { object Boom extends Error("Boom") with scala.util.control.NoStackTrace - @nowarn("cat=w-flag-dead-code") + @nowarn2("cat=w-flag-dead-code") object CrashingSuite extends SimpleIOSuite { throw Boom } @@ -102,7 +102,7 @@ object Meta { override implicit protected def effectCompat: UnsafeRun[IO] = SetTimeUnsafeRun - loggedTest("erroring with causes") { log => + loggedTest("erroring with causes") { _ => throw CustomException( "surfaced error", CustomException("first cause", diff --git a/modules/framework/js-native/src/main/scala/DogFoodCompat.scala b/modules/framework/js-native/src/main/scala/DogFoodCompat.scala index dc6b7d97..d794752c 100644 --- a/modules/framework/js-native/src/main/scala/DogFoodCompat.scala +++ b/modules/framework/js-native/src/main/scala/DogFoodCompat.scala @@ -4,6 +4,7 @@ package framework import cats.data.Chain import cats.effect.Resource import cats.syntax.all._ +import org.typelevel.scalaccompat.annotation.unused private[weaver] trait DogFoodCompat[F[_]] { self: DogFood[F] => @@ -15,7 +16,7 @@ private[weaver] trait DogFoodCompat[F[_]] { self: DogFood[F] => runner: WeaverRunner[F], eventHandler: sbt.testing.EventHandler, logger: sbt.testing.Logger, - maxParallelism: Int)(tasks: List[sbt.testing.Task]): F[Unit] = { + @unused maxParallelism: Int)(tasks: List[sbt.testing.Task]): F[Unit] = { tasks.traverse { task => self.framework.unsafeRun.fromFuture { task.asInstanceOf[AsyncTask].executeFuture(eventHandler, Array(logger)) diff --git a/modules/framework/js-native/src/main/scala/RunnerCompat.scala b/modules/framework/js-native/src/main/scala/RunnerCompat.scala index a37921d6..f57f4d77 100644 --- a/modules/framework/js-native/src/main/scala/RunnerCompat.scala +++ b/modules/framework/js-native/src/main/scala/RunnerCompat.scala @@ -2,6 +2,7 @@ package weaver package framework import java.nio.ByteBuffer +import org.typelevel.scalaccompat.annotation.unused import scala.collection.mutable.ListBuffer import scala.concurrent.Future @@ -138,7 +139,7 @@ trait RunnerCompat[F[_]] { self: sbt.testing.Runner => } } - def finaliseError(outcomes: Ref[ + def finaliseError(@unused outcomes: Ref[ F, Chain[TestOutcome]]): Throwable => F[Unit] = { error => val outcome = @@ -177,7 +178,7 @@ trait RunnerCompat[F[_]] { self: sbt.testing.Runner => } private[weaver] object ReadWriter { - class Reader(bytes: ByteBuffer, private var pt: Int) { + class Reader(bytes: ByteBuffer, @unused private var pt: Int) { def readString() = { val stringSize = bytes.getInt() val ar = new Array[Byte](stringSize) diff --git a/modules/framework/jvm/src/main/scala/DogFoodCompat.scala b/modules/framework/jvm/src/main/scala/DogFoodCompat.scala index 81f3b81b..2c3480fa 100644 --- a/modules/framework/jvm/src/main/scala/DogFoodCompat.scala +++ b/modules/framework/jvm/src/main/scala/DogFoodCompat.scala @@ -5,6 +5,7 @@ import cats.effect.Resource import cats.effect.implicits._ import sbt.testing._ +import org.typelevel.scalaccompat.annotation.unused private[weaver] trait DogFoodCompat[F[_]] { self: DogFood[F] => @@ -13,13 +14,11 @@ private[weaver] trait DogFoodCompat[F[_]] { self: DogFood[F] => def blocker: BlockerCompat[F] def runTasksCompat( - runner: WeaverRunner[F], + @unused runner: WeaverRunner[F], eventHandler: EventHandler, logger: Logger, maxParallelism: Int)(tasks: List[sbt.testing.Task]): F[Unit] = { - effect.void { - @scala.annotation.nowarn("msg=implicit numeric widening") val r = tasks.toVector.parTraverseN[F, Unit](maxParallelism) { task => blocker.block(discard[Array[Task]](task.execute(eventHandler, Array(logger)))) diff --git a/modules/framework/jvm/src/main/scala/RunnerCompat.scala b/modules/framework/jvm/src/main/scala/RunnerCompat.scala index 8494d466..d4834c5e 100644 --- a/modules/framework/jvm/src/main/scala/RunnerCompat.scala +++ b/modules/framework/jvm/src/main/scala/RunnerCompat.scala @@ -1,5 +1,6 @@ package weaver package framework +import org.typelevel.scalaccompat.annotation.unused import java.io.PrintStream import java.util.concurrent.ConcurrentLinkedQueue @@ -37,7 +38,7 @@ trait RunnerCompat[F[_]] { self: sbt.testing.Runner => } // Required on js - def receiveMessage(msg: String): Option[String] = None + def receiveMessage(@unused msg: String): Option[String] = None // Flag meant to be raised if build-tool call `done` protected val isDone: AtomicBoolean = new AtomicBoolean(false) @@ -57,9 +58,9 @@ trait RunnerCompat[F[_]] { self: sbt.testing.Runner => val stillRunning = new AtomicInteger(0) val waitForResourcesShutdown = new java.util.concurrent.Semaphore(0) - val tasksAndSuites = taskDefs.toList.map { taskDef => - taskDef -> suiteLoader(taskDef) - }.collect { case (taskDef, Some(suite)) => (taskDef, suite) } + val tasksAndSuites = (taskDefs.toList.mapFilter { taskDef => + suiteLoader(taskDef).tupleLeft(taskDef) + }) def makeTasks( taskDef: TaskDef, @@ -240,7 +241,7 @@ trait RunnerCompat[F[_]] { self: sbt.testing.Runner => .productR(broker.send(TestFinished(outcome))), finalizer) } - )).handleErrorWith { case scala.util.control.NonFatal(_) => + )).recoverWith { case scala.util.control.NonFatal(_) => effect.unit // avoid non-fatal errors propagating up } } diff --git a/modules/framework/shared/src/main/scala/weaver/framework/DogFood.scala b/modules/framework/shared/src/main/scala/weaver/framework/DogFood.scala index 67ae7d41..6b0ebbca 100644 --- a/modules/framework/shared/src/main/scala/weaver/framework/DogFood.scala +++ b/modules/framework/shared/src/main/scala/weaver/framework/DogFood.scala @@ -38,7 +38,7 @@ abstract class DogFood[F[_]]( for { eventHandler <- effect.delay(new MemoryEventHandler()) logger <- effect.delay(new MemoryLogger()) - _ <- getTasks(suites, logger).use { case (runner, tasks) => + _ <- getTasks(suites).use { case (runner, tasks) => runTasks(runner, eventHandler, logger, maxParallelism)(tasks.toList) } _ <- patience.fold(effect.unit)(framework.unsafeRun.sleep) @@ -71,8 +71,8 @@ abstract class DogFood[F[_]]( } private def getTasks( - suites: Seq[Fingerprinted], - logger: Logger): Resource[F, (WeaverRunner[F], Array[sbt.testing.Task])] = { + suites: Seq[Fingerprinted] + ): Resource[F, (WeaverRunner[F], Array[sbt.testing.Task])] = { val acquire = Sync[F].delay { val cl = PlatformCompat.getClassLoader(this.getClass()) framework.weaverRunner(Array(), Array(), cl, None) diff --git a/modules/framework/shared/src/main/scala/weaver/framework/Fingerprints.scala b/modules/framework/shared/src/main/scala/weaver/framework/Fingerprints.scala index 29bdf3fd..75b6d0a5 100644 --- a/modules/framework/shared/src/main/scala/weaver/framework/Fingerprints.scala +++ b/modules/framework/shared/src/main/scala/weaver/framework/Fingerprints.scala @@ -6,7 +6,6 @@ import scala.reflect.ClassTag import cats.effect.Sync import weaver.internals.Reflection._ -import weaver.{ EffectSuite, GlobalResourceF } import sbt.testing.{ Fingerprint, SubclassFingerprint, TaskDef } @@ -59,6 +58,7 @@ abstract class WeaverFingerprints[F[_]](implicit F: Sync[F]) { loadModule(taskDef.fullyQualifiedName(), classLoader) val init = cast(module)(GlobalResourcesInitClass) Some(GlobalResourcesRef(init)) + case _ => None } } @@ -76,7 +76,7 @@ abstract class WeaverFingerprints[F[_]](implicit F: Sync[F]) { /** * A fingerprint that searches only for classes extending * [[weaver.EffectSuite]]. that have a constructor that takes a single - * [[weaver.GlobalResources.Read]] parameter. + * [[weaver.GlobalResourceF.Read]] parameter. */ object ResourceSharingSuiteFingerprint extends WeaverFingerprint { def isModule() = false diff --git a/modules/framework/shared/src/main/scala/weaver/framework/WeaverFramework.scala b/modules/framework/shared/src/main/scala/weaver/framework/WeaverFramework.scala index 6335ab23..8a940668 100644 --- a/modules/framework/shared/src/main/scala/weaver/framework/WeaverFramework.scala +++ b/modules/framework/shared/src/main/scala/weaver/framework/WeaverFramework.scala @@ -3,8 +3,6 @@ package framework import java.io.PrintStream -import weaver.{ Platform, discard } - import sbt.testing.{ Framework => BaseFramework, Runner => BaseRunner, _ } class WeaverFramework[F[_]]( diff --git a/modules/scalacheck/shared/src/test/scala/weaver/scalacheck/CheckersConcurrencyTest.scala b/modules/scalacheck/shared/src/test/scala/weaver/scalacheck/CheckersConcurrencyTest.scala index 663c5144..733ce19c 100644 --- a/modules/scalacheck/shared/src/test/scala/weaver/scalacheck/CheckersConcurrencyTest.scala +++ b/modules/scalacheck/shared/src/test/scala/weaver/scalacheck/CheckersConcurrencyTest.scala @@ -9,9 +9,6 @@ import scala.concurrent.duration._ import cats.effect.Outcome._ import cats.effect.testkit.TestControl import cats.effect.{ IO, Ref } -import cats.syntax.all._ - -import weaver.TestStatus import org.scalacheck.Gen diff --git a/modules/scalacheck/shared/src/test/scala/weaver/scalacheck/CheckersTest.scala b/modules/scalacheck/shared/src/test/scala/weaver/scalacheck/CheckersTest.scala index ba6c5f2b..e7d9cb62 100644 --- a/modules/scalacheck/shared/src/test/scala/weaver/scalacheck/CheckersTest.scala +++ b/modules/scalacheck/shared/src/test/scala/weaver/scalacheck/CheckersTest.scala @@ -4,7 +4,6 @@ package scalacheck import scala.concurrent.duration._ import cats.effect.IO -import cats.syntax.all._ import org.scalacheck.Gen diff --git a/modules/scalacheck/shared/src/test/scala/weaver/scalacheck/PropertyDogFoodTest.scala b/modules/scalacheck/shared/src/test/scala/weaver/scalacheck/PropertyDogFoodTest.scala index 4715d18d..cf0e5b95 100644 --- a/modules/scalacheck/shared/src/test/scala/weaver/scalacheck/PropertyDogFoodTest.scala +++ b/modules/scalacheck/shared/src/test/scala/weaver/scalacheck/PropertyDogFoodTest.scala @@ -4,7 +4,6 @@ package scalacheck import scala.concurrent.duration._ import cats.effect.{ IO, Resource } -import cats.syntax.all._ import weaver.framework._