From 8d53310ff4ef034285800c8984664462158929bd Mon Sep 17 00:00:00 2001 From: Russ Remple <38769008+russellremple@users.noreply.github.com> Date: Thu, 23 Dec 2021 12:12:47 -0800 Subject: [PATCH] For 1-15, potentially drop Scala 2.11 support and add Scala 3 (#41) * for 1-15, drop _2.11 and add _3 * bump scoverage plugin * bump scoverage plugin M3 * Drop ScalaCheck 1.12, drop Scala 2.11 * mima and initial _3 * put 2.11 back, use project matrix --- .travis.yml | 4 +- README.md | 2 +- build.sbt | 239 +++++++++++------- .../scala/org/scalacheck/ops/GenOps.scala | 4 +- .../scalacheck/ops/ArbitraryAsGenSpec.scala | 0 .../scalacheck/ops/NewtypeTypeNameSpec.scala | 0 .../scalacheck/ops/ArbitraryAsGenSpec.scala | 23 ++ .../scalacheck/ops/NewtypeTypeNameSpec.scala | 20 ++ .../scala/org/scalacheck/ops/GenOpsSpec.scala | 4 +- .../scalacheck/ops/SeedExtractorSpec.scala | 6 +- .../time/GenericDateTimeGeneratorsSpec.scala | 16 +- .../ops/time/TruncatedJavaTimeSpec.scala | 10 +- .../joda/ImplicitJodaTimeGenerators.scala | 4 +- project/Dependencies.scala | 57 +++-- project/plugins.sbt | 3 +- 15 files changed, 246 insertions(+), 146 deletions(-) rename core/src/test/{scala => scala-2}/org/scalacheck/ops/ArbitraryAsGenSpec.scala (100%) rename core/src/test/{scala => scala-2}/org/scalacheck/ops/NewtypeTypeNameSpec.scala (100%) create mode 100644 core/src/test/scala-3/org/scalacheck/ops/ArbitraryAsGenSpec.scala create mode 100644 core/src/test/scala-3/org/scalacheck/ops/NewtypeTypeNameSpec.scala diff --git a/.travis.yml b/.travis.yml index b5efff1..5676034 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,10 +11,10 @@ before_script: - curl -L -o $HOME/.sbt/launchers/1.5.3/sbt-launch.jar https://repo1.maven.org/maven2/org/scala-sbt/sbt-launch/1.5.3/sbt-launch-1.5.3.jar script: - - sbt clean coverage +test coverageAggregate + - sbt clean coverage test coverageAggregate # Upload coverage reports to codecov.io before checking binary compatibility - bash <(curl -s https://codecov.io/bash) - - sbt +mimaReportBinaryIssues + - sbt mimaReportBinaryIssues # Avoid unnecessary cache updates before_cache: diff --git a/README.md b/README.md index 239fb1b..d0fc78d 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ no version suffix would pull in ScalaCheck version 1.12.6. | Artifact Name | Version Limit | ScalaCheck | Supported JDK | Supported Scala | | :-----------------: | :------------: | :--------: | :-----------: | :--------------: | -| scalacheck-ops_1-15 | x >= 2.5.2 | 1.15.2 | 8 | 2.11, 2.12, 2.13 | +| scalacheck-ops_1-15 | x >= 2.5.2 | 1.15.4 | 8 | 2.12, 2.13, 3 | | scalacheck-ops_1-14 | x >= 2.0 | 1.14.3 | 8 | 2.11, 2.12, 2.13 | | scalacheck-ops_1-13 | x >= 2.0 | 1.13.5 | 8 | 2.11, 2.12 | | scalacheck-ops_1-13 | 1.5 <= x < 2.0 | 1.13.4 | 6 - 8 | 2.10 - 2.11 | diff --git a/build.sbt b/build.sbt index d580fed..a39c092 100644 --- a/build.sbt +++ b/build.sbt @@ -24,20 +24,24 @@ mimaFailOnNoPrevious := false // don't publish the aggregate root project publish / skip := true -def commonProject(id: String, artifact: String, path: String): Project = { - Project(id, file(path)).settings( +def commonSettings(artifact: String): Seq[Setting[_]] = + Seq( name := artifact, - mimaPreviousArtifacts := Set(organization.value %% artifact % "2.6.0"), + mimaPreviousArtifacts := ( + if (scalaBinaryVersion.value == "3") Set.empty // remove once _3 is published + else Set(organization.value %% artifact % "2.6.0") + ), - scalacOptions := Seq( + scalacOptions ++= Seq( // "-Xfatal-warnings", // some methods in Scala 2.13 are deprecated, but I don't want to maintain to copies of source "-deprecation:false", "-feature", + "-encoding", "UTF-8" + ) ++ (if (scalaBinaryVersion.value == "3") Seq.empty else Seq( "-Xlint", "-Ywarn-dead-code", - "-encoding", "UTF-8" - ), + )), // show full stack traces in test failures Test / testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-oF"), @@ -49,98 +53,141 @@ def commonProject(id: String, artifact: String, path: String): Project = { Compile / packageDoc / publishArtifact := false, // Don't publish the test artifacts, nobody should depend on these - Test / publishArtifact := false, + Test / publishArtifact := false ) -} - -def scSuffix(scalaCheckVersion: String): String = scalaCheckVersion match { - case ScalaCheck_1_12 => "_1-12" - case ScalaCheck_1_13 => "_1-13" - case ScalaCheck_1_14 => "_1-14" - case ScalaCheck_1_15 => "_1-15" -} - -def scalaVersions(scalaCheckVersion: String): Seq[String] = scalaCheckVersion match { - case ScalaCheck_1_12 => Seq(Scala_2_11) - case ScalaCheck_1_13 => Seq(Scala_2_11, Scala_2_12) - case ScalaCheck_1_14 => Seq(Scala_2_11, Scala_2_12, Scala_2_13) - case ScalaCheck_1_15 => Seq(Scala_2_11, Scala_2_12, Scala_2_13) -} - -def coreProject(srcPath: File, testPath: File, scalaCheckVersion: String): Project = { - val suffix = scSuffix(scalaCheckVersion) - val targetPath = s"core$suffix" - commonProject(targetPath, s"scalacheck-ops$suffix", targetPath).settings( - scalaVersion := crossScalaVersions.value.head, - crossScalaVersions := scalaVersions(scalaCheckVersion), - Compile / sourceDirectory := (srcPath / "src" / "main").getAbsoluteFile, - Test / sourceDirectory := (testPath / "src" / "test").getAbsoluteFile, - scalacOptions ++= { - scalaVersion.value match { - case Scala_2_13 => Seq("-Ymacro-annotations") - case _ => Seq() - } - }, - libraryDependencies ++= { - Seq( - izumiReflect, - scalaCheck(scalaCheckVersion), - tagging, - ) ++ { - scalaVersion.value match { - case Scala_2_11 | Scala_2_12 => Seq( - compilerPlugin("org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.full) - ) - case _ => Seq() - } - } - } ++ { - // Test-only dependencies - Seq( - scalaTest(scalaCheckVersion), - newtype, - ) ++ { - scalaCheckVersion match { - case ScalaCheck_1_12 | ScalaCheck_1_13 => Seq() - case ScalaCheck_1_14 | ScalaCheck_1_15 => Seq( - scalaTestPlusScalaCheck(scalaCheckVersion), - ) - } - - } - }.map(_ % Test) - ) -} - -lazy val `core_1-12` = coreProject(file("core_1-12"), file("core_1-12"), ScalaCheck_1_12) -lazy val `core_1-13` = coreProject(file("core"), file("core-1-13-test"), ScalaCheck_1_13) -lazy val `core_1-14` = coreProject(file("core"), file("core"), ScalaCheck_1_14) -lazy val `core_1-15` = coreProject(file("core"), file("core"), ScalaCheck_1_15) - - -def jodaProject(scalaCheckVersion: String): Project = { - val projectPath = "joda" - val suffix = scSuffix(scalaCheckVersion) - commonProject(s"joda$suffix", s"scalacheck-ops-joda$suffix", s"$projectPath$suffix").settings( - scalaVersion := crossScalaVersions.value.head, - crossScalaVersions := scalaVersions(scalaCheckVersion), - Compile / sourceDirectory := file(s"$projectPath/src/main").getAbsoluteFile, - Test / sourceDirectory := file(s"$projectPath/src/test").getAbsoluteFile, - // don't include dependencies that come from scalacheck-ops core project + +lazy val `core` = projectMatrix + .settings( + // default locations, overridden in custom rows where needed + Compile / sourceDirectory := (file("core") / "src" / "main").getAbsoluteFile, + Test / sourceDirectory := (file("core") / "src" / "test").getAbsoluteFile, + + scalacOptions ++= (scalaVersion.value match { + case Scala_2_13 => Seq("-Ymacro-annotations") + case _ => Seq() + }), + libraryDependencies ++= Seq( - jodaTime, + izumiReflect, + tagging, + newtype // Test-only + ) ++ (scalaVersion.value match { + case Scala_2_11 | Scala_2_12 => Seq( + compilerPlugin("org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.full) + ) + case _ => Seq() + }) + ) + .customRow( + scalaVersions = Seq(Scala_2_11), + axisValues = Seq(ScalaCheckAxis.v1_12, VirtualAxis.jvm), + settings = commonSettings(ScalaCheckAxis.v1_12.artifact) ++ Seq( + coverageEnabled := false, // Scala 2.11 + Compile / sourceDirectory := (file("core_1-12") / "src" / "main").getAbsoluteFile, + Test / sourceDirectory := (file("core_1-12") / "src" / "test").getAbsoluteFile, + libraryDependencies ++= Seq( + ScalaCheckAxis.v1_12.scalaCheck, + ScalaCheckAxis.v1_12.scalaTest + ) + ) + ) + .customRow( + scalaVersions = Seq(Scala_2_11), + axisValues = Seq(ScalaCheckAxis.v1_13, VirtualAxis.jvm), + settings = commonSettings(ScalaCheckAxis.v1_13.artifact) ++ Seq( + coverageEnabled := false, // Scala 2.11 + Test / sourceDirectory := (file("core-1-13-test") / "src" / "test").getAbsoluteFile, + libraryDependencies ++= Seq( + ScalaCheckAxis.v1_13.scalaCheck, + ScalaCheckAxis.v1_13.scalaTest + ) + ) + ) + .customRow( + scalaVersions = Seq(Scala_2_12), + axisValues = Seq(ScalaCheckAxis.v1_13, VirtualAxis.jvm), + settings = commonSettings(ScalaCheckAxis.v1_13.artifact) ++ Seq( + Test / sourceDirectory := (file("core-1-13-test") / "src" / "test").getAbsoluteFile, + libraryDependencies ++= Seq( + ScalaCheckAxis.v1_13.scalaCheck, + ScalaCheckAxis.v1_13.scalaTest + ) + ) + ) + .customRow( + scalaVersions = Seq(Scala_2_11), + axisValues = Seq(ScalaCheckAxis.v1_14, VirtualAxis.jvm), + settings = commonSettings(ScalaCheckAxis.v1_14.artifact) ++ Seq( + coverageEnabled := false, // Scala 2.11 + libraryDependencies ++= Seq( + ScalaCheckAxis.v1_14.scalaCheck, + ScalaCheckAxis.v1_14.scalaTest, + ScalaCheckAxis.v1_14.scalaTestPlusScalaCheck(scalaVersion.value) + ) + ) + ) + .customRow( + scalaVersions = Seq(Scala_2_12, Scala_2_13), + axisValues = Seq(ScalaCheckAxis.v1_14, VirtualAxis.jvm), + settings = commonSettings(ScalaCheckAxis.v1_14.artifact) ++ Seq( + libraryDependencies ++= Seq( + ScalaCheckAxis.v1_14.scalaCheck, + ScalaCheckAxis.v1_14.scalaTest, + ScalaCheckAxis.v1_14.scalaTestPlusScalaCheck(scalaVersion.value) + ) + ) + ) + .customRow( + scalaVersions = Seq(Scala_2_12, Scala_2_13, Scala_3), + axisValues = Seq(ScalaCheckAxis.v1_15, VirtualAxis.jvm), + settings = commonSettings(ScalaCheckAxis.v1_15.artifact) ++ Seq( + libraryDependencies ++= Seq( + ScalaCheckAxis.v1_15.scalaCheck, + ScalaCheckAxis.v1_15.scalaTest, + ScalaCheckAxis.v1_15.scalaTestPlusScalaCheck(scalaVersion.value) + ) ) - ).dependsOn( - (scalaCheckVersion match { - case ScalaCheck_1_12 => `core_1-12` - case ScalaCheck_1_13 => `core_1-13` - case ScalaCheck_1_14 => `core_1-14` - case ScalaCheck_1_15 => `core_1-15` - }) % "compile;test->test" ) -} -lazy val `joda_1-12` = jodaProject(ScalaCheck_1_12) -lazy val `joda_1-13` = jodaProject(ScalaCheck_1_13) -lazy val `joda_1-14` = jodaProject(ScalaCheck_1_14) -lazy val `joda_1-15` = jodaProject(ScalaCheck_1_15) +lazy val `joda` = projectMatrix + .dependsOn(`core` % "compile;test->test") + .settings( + Compile / sourceDirectory := file(s"joda/src/main").getAbsoluteFile, + Test / sourceDirectory := file(s"joda/src/test").getAbsoluteFile, + + // don't include dependencies that come from scalacheck-ops core project + libraryDependencies += jodaTime + ) + .customRow( + scalaVersions = Seq(Scala_2_11), + axisValues = Seq(ScalaCheckAxis.v1_12, VirtualAxis.jvm), + settings = commonSettings(ScalaCheckAxis.v1_12.subArtifact("joda")) :+ + (coverageEnabled := false) // Scala 2.11 + ) + .customRow( + scalaVersions = Seq(Scala_2_11), + axisValues = Seq(ScalaCheckAxis.v1_13, VirtualAxis.jvm), + settings = commonSettings(ScalaCheckAxis.v1_13.subArtifact("joda")) :+ + (coverageEnabled := false) // Scala 2.11 + ) + .customRow( + scalaVersions = Seq(Scala_2_12), + axisValues = Seq(ScalaCheckAxis.v1_13, VirtualAxis.jvm), + settings = commonSettings(ScalaCheckAxis.v1_13.subArtifact("joda")) + ) + .customRow( + scalaVersions = Seq(Scala_2_11), + axisValues = Seq(ScalaCheckAxis.v1_14, VirtualAxis.jvm), + settings = commonSettings(ScalaCheckAxis.v1_14.subArtifact("joda")) :+ + (coverageEnabled := false) // Scala 2.11 + ) + .customRow( + scalaVersions = Seq(Scala_2_12, Scala_2_13), + axisValues = Seq(ScalaCheckAxis.v1_14, VirtualAxis.jvm), + settings = commonSettings(ScalaCheckAxis.v1_14.subArtifact("joda")) + ) + .customRow( + scalaVersions = Seq(Scala_2_12, Scala_2_13, Scala_3), + axisValues = Seq(ScalaCheckAxis.v1_15, VirtualAxis.jvm), + settings = commonSettings(ScalaCheckAxis.v1_15.subArtifact("joda")) + ) diff --git a/core/src/main/scala/org/scalacheck/ops/GenOps.scala b/core/src/main/scala/org/scalacheck/ops/GenOps.scala index 8fae46e..e6a2bad 100644 --- a/core/src/main/scala/org/scalacheck/ops/GenOps.scala +++ b/core/src/main/scala/org/scalacheck/ops/GenOps.scala @@ -20,8 +20,8 @@ object GenOps { } map pf } - def enumValue[E <: Enumeration](enum: E): Gen[enum.Value] = - Gen.oneOf[enum.Value](enum.values.toSeq) + def enumValue[E <: Enumeration](enumuration: E): Gen[enumuration.Value] = + Gen.oneOf[enumuration.Value](enumuration.values.toSeq) def boolean: Gen[Boolean] = Gen.oneOf(true, false) diff --git a/core/src/test/scala/org/scalacheck/ops/ArbitraryAsGenSpec.scala b/core/src/test/scala-2/org/scalacheck/ops/ArbitraryAsGenSpec.scala similarity index 100% rename from core/src/test/scala/org/scalacheck/ops/ArbitraryAsGenSpec.scala rename to core/src/test/scala-2/org/scalacheck/ops/ArbitraryAsGenSpec.scala diff --git a/core/src/test/scala/org/scalacheck/ops/NewtypeTypeNameSpec.scala b/core/src/test/scala-2/org/scalacheck/ops/NewtypeTypeNameSpec.scala similarity index 100% rename from core/src/test/scala/org/scalacheck/ops/NewtypeTypeNameSpec.scala rename to core/src/test/scala-2/org/scalacheck/ops/NewtypeTypeNameSpec.scala diff --git a/core/src/test/scala-3/org/scalacheck/ops/ArbitraryAsGenSpec.scala b/core/src/test/scala-3/org/scalacheck/ops/ArbitraryAsGenSpec.scala new file mode 100644 index 0000000..11d233f --- /dev/null +++ b/core/src/test/scala-3/org/scalacheck/ops/ArbitraryAsGenSpec.scala @@ -0,0 +1,23 @@ +package org.scalacheck.ops + +import org.scalacheck.{Arbitrary, Gen} +import org.scalatest.freespec.AnyFreeSpec + +class ArbitraryAsGenSpec extends AnyFreeSpec { + + private val it = classOf[ArbitraryAsGen].getSimpleName + + s"$it should implicitly convert a Gen to Arbitrary" in { + def f(arb: Arbitrary[Char]): Unit = () + f(Gen.numChar) + } + + private def implicitGen(implicit gen: Gen[Char]): Unit = () + + s"$it should convert an implicit Arbitrary to an implicit Gen" in { + /* + * Note this compiles in Scala 3, not Scala 2 + */ + assertCompiles("implicitGen") + } +} diff --git a/core/src/test/scala-3/org/scalacheck/ops/NewtypeTypeNameSpec.scala b/core/src/test/scala-3/org/scalacheck/ops/NewtypeTypeNameSpec.scala new file mode 100644 index 0000000..eeb9cf3 --- /dev/null +++ b/core/src/test/scala-3/org/scalacheck/ops/NewtypeTypeNameSpec.scala @@ -0,0 +1,20 @@ +package org.scalacheck.ops + +import org.scalatest.freespec.AnyFreeSpec + +class NewtypeTypeNameSpec extends AnyFreeSpec { + /* + * Note differences in type name emitted by Scala 3 vs. Scala 2 + */ + "Find a TypeName of a newtype" in { + assertResult("org.scalacheck.ops.NewtypeExample$IdType") { + implicitly[TypeName[NewtypeExample.IdType]].typeName + } + } + + "Find a TypeName of a newsubtype" in { + assertResult("org.scalacheck.ops.NewtypeExample$IdSubtype") { + implicitly[TypeName[NewtypeExample.IdSubtype]].typeName + } + } +} diff --git a/core/src/test/scala/org/scalacheck/ops/GenOpsSpec.scala b/core/src/test/scala/org/scalacheck/ops/GenOpsSpec.scala index a737abb..036f6cc 100644 --- a/core/src/test/scala/org/scalacheck/ops/GenOpsSpec.scala +++ b/core/src/test/scala/org/scalacheck/ops/GenOpsSpec.scala @@ -102,9 +102,9 @@ class GenOpsSpec extends AnyFlatSpec { behavior of "Gen.enumValue" it should "create a generator from an Enumeration" in { - forAll(Gen.enumValue(TestValues)) { enum => + forAll(Gen.enumValue(TestValues)) { (enumeration: TestValues.Value) => // Should be of the expected type - assert(enum == TestValues.withName(enum.toString)) + assert(enumeration == TestValues.withName(enumeration.toString)) } } } diff --git a/core/src/test/scala/org/scalacheck/ops/SeedExtractorSpec.scala b/core/src/test/scala/org/scalacheck/ops/SeedExtractorSpec.scala index 8e0c923..0a27c4b 100644 --- a/core/src/test/scala/org/scalacheck/ops/SeedExtractorSpec.scala +++ b/core/src/test/scala/org/scalacheck/ops/SeedExtractorSpec.scala @@ -29,7 +29,7 @@ class SeedExtractorSpec extends AnyFreeSpec { "verify this test catches collisions" in { implicit val collisionProneSeedExtractor: SeedExtractor[Int] = SeedExtractor.fromLong(_ % 2) - forAll(Gen.listOfN(1000, arbitrary[Int]), collisionCheckParams: _*) { ints: Seq[Int] => + forAll(Gen.listOfN(1000, arbitrary[Int]), collisionCheckParams: _*) { (ints: Seq[Int]) => whenever(ints.nonEmpty) { val collisions = groupCollisions(ints) assert(collisions.nonEmpty) @@ -45,13 +45,13 @@ class SeedExtractorSpec extends AnyFreeSpec { val typeName = classTag[A].runtimeClass.getSimpleName s"$it[$typeName]$suffix should extract a consistent seed" in { - forAll { a: A => + forAll { (a: A) => assert(extractor.seed(a) == extractor.seed(a)) } } s"$it[$typeName]$suffix should avoid collisions" in { - forAll(Gen.listOfN(1000, arbitrary[A]), collisionCheckParams: _*) { as: Seq[A] => + forAll(Gen.listOfN(1000, arbitrary[A]), collisionCheckParams: _*) { (as: Seq[A]) => val collisions = groupCollisions(as) collisions should have size 0 } diff --git a/core/src/test/scala/org/scalacheck/ops/time/GenericDateTimeGeneratorsSpec.scala b/core/src/test/scala/org/scalacheck/ops/time/GenericDateTimeGeneratorsSpec.scala index 3097039..3fe398c 100644 --- a/core/src/test/scala/org/scalacheck/ops/time/GenericDateTimeGeneratorsSpec.scala +++ b/core/src/test/scala/org/scalacheck/ops/time/GenericDateTimeGeneratorsSpec.scala @@ -26,7 +26,7 @@ private[time] abstract class GenericDateTimeGeneratorsSpec[Generators <: Abstrac behavior of s"$genClassName.before" it should "not generate errors" in { - forAll() { start: gen.InstantType => + forAll() { (start: gen.InstantType) => val sampleIter = gen.before(start).sampleIterator val samples = sampleIter.take(10).toSeq assert(samples.forall(_.isDefined)) @@ -34,8 +34,8 @@ private[time] abstract class GenericDateTimeGeneratorsSpec[Generators <: Abstrac } it should s"always generate $genClassName instances less than the given instant" in { - forAll() { start: gen.InstantType => - forAll(gen.before(start)) { before: gen.InstantType => + forAll() { (start: gen.InstantType) => + forAll(gen.before(start)) { (before: gen.InstantType) => before should be <= start } } @@ -44,7 +44,7 @@ private[time] abstract class GenericDateTimeGeneratorsSpec[Generators <: Abstrac behavior of s"$genClassName.after" it should "not generate errors" in { - forAll() { start: gen.InstantType => + forAll() { (start: gen.InstantType) => val sampleIter = gen.after(start).sampleIterator val samples = sampleIter.take(10).toSeq assert(samples.forall(_.isDefined)) @@ -52,8 +52,8 @@ private[time] abstract class GenericDateTimeGeneratorsSpec[Generators <: Abstrac } it should s"always generate $genClassName instances greater than the given instant" in { - forAll() { start: gen.InstantType => - forAll(gen.after(start)) { after: gen.InstantType => + forAll() { (start: gen.InstantType) => + forAll(gen.after(start)) { (after: gen.InstantType) => after should be >= start } } @@ -62,7 +62,7 @@ private[time] abstract class GenericDateTimeGeneratorsSpec[Generators <: Abstrac behavior of s"$genClassName.around" it should "not generate errors" in { - forAll() { start: gen.InstantType => + forAll() { (start: gen.InstantType) => val sampleIter = gen.around(start).sampleIterator val samples = sampleIter.take(10).toSeq assert(samples.forall(_.isDefined)) @@ -70,7 +70,7 @@ private[time] abstract class GenericDateTimeGeneratorsSpec[Generators <: Abstrac } it should s"always generate $genClassName that are within the given range of the given time" in { - forAll() { start: gen.InstantType => + forAll() { (start: gen.InstantType) => forAll(gen.around(start, gen.defaultRange)) { around => around should ( be >= gen.subtractToFloor(start, gen.defaultRange) and diff --git a/core/src/test/scala/org/scalacheck/ops/time/TruncatedJavaTimeSpec.scala b/core/src/test/scala/org/scalacheck/ops/time/TruncatedJavaTimeSpec.scala index a217d8b..615e33a 100644 --- a/core/src/test/scala/org/scalacheck/ops/time/TruncatedJavaTimeSpec.scala +++ b/core/src/test/scala/org/scalacheck/ops/time/TruncatedJavaTimeSpec.scala @@ -14,7 +14,7 @@ class TruncatedJavaTimeSpec extends AnyFreeSpec { val it = "Gen[Instant]" s"$it.truncatedToMillis removes all nanoseconds and milliseconds" in { - forAll(Gen.javaInstant.beforeNow.truncatedToMillis) { instant: Instant => + forAll(Gen.javaInstant.beforeNow.truncatedToMillis) { (instant: Instant) => assertResult(0)(instant.getLong(ChronoField.NANO_OF_SECOND) % 1000) } } @@ -24,25 +24,25 @@ class TruncatedJavaTimeSpec extends AnyFreeSpec { val it = "Gen[LocalDateTime]" s"$it.truncatedToMillis removes all nanoseconds and milliseconds" in { - forAll(Gen.javaLocalDateTime.beforeNow.truncatedToMillis) { datetime: LocalDateTime => + forAll(Gen.javaLocalDateTime.beforeNow.truncatedToMillis) { (datetime: LocalDateTime) => assertResult(0)(datetime.getLong(ChronoField.NANO_OF_SECOND) % 1000) } } s"$it.truncatedTo(ChronoUnit.SECONDS) removes all milliseconds" in { - forAll(Gen.javaLocalDateTime.beforeNow.truncatedTo(ChronoUnit.SECONDS)) { datetime: LocalDateTime => + forAll(Gen.javaLocalDateTime.beforeNow.truncatedTo(ChronoUnit.SECONDS)) { (datetime: LocalDateTime) => assertResult(0)(datetime.getLong(ChronoField.MILLI_OF_SECOND)) } } s"$it.truncatedTo(ChronoUnit.MINUTES) removes all seconds" in { - forAll(Gen.javaLocalDateTime.beforeNow.truncatedTo(ChronoUnit.MINUTES)) { datetime: LocalDateTime => + forAll(Gen.javaLocalDateTime.beforeNow.truncatedTo(ChronoUnit.MINUTES)) { (datetime: LocalDateTime) => assertResult(0)(datetime.getLong(ChronoField.SECOND_OF_MINUTE)) } } s"$it.truncatedTo(ChronoUnit.HOURS) removes all seconds" in { - forAll(Gen.javaLocalDateTime.beforeNow.truncatedTo(ChronoUnit.HOURS)) { datetime: LocalDateTime => + forAll(Gen.javaLocalDateTime.beforeNow.truncatedTo(ChronoUnit.HOURS)) { (datetime: LocalDateTime) => assertResult(0)(datetime.getLong(ChronoField.MINUTE_OF_HOUR)) } } diff --git a/joda/src/main/scala/org/scalacheck/ops/time/joda/ImplicitJodaTimeGenerators.scala b/joda/src/main/scala/org/scalacheck/ops/time/joda/ImplicitJodaTimeGenerators.scala index f4a1793..77e8afd 100644 --- a/joda/src/main/scala/org/scalacheck/ops/time/joda/ImplicitJodaTimeGenerators.scala +++ b/joda/src/main/scala/org/scalacheck/ops/time/joda/ImplicitJodaTimeGenerators.scala @@ -36,12 +36,12 @@ trait ImplicitJodaTimeGenerators { implicit def arbDateTime(implicit params: JodaTimeParams = JodaDateTimeGenerators.defaultParams): Arbitrary[DateTime] = { val maxMillis = params.chronology.maxMillis - Arbitrary(chooseNum(0, maxMillis).flatMap(new DateTime(_, params.chronology))) + Arbitrary(chooseNum(0L, maxMillis).flatMap(new DateTime(_, params.chronology))) } implicit def arbLocalDateTime(implicit params: JodaTimeParams = JodaLocalDateTimeGenerators.defaultParams): Arbitrary[LocalDateTime] = { val maxMillis = params.chronology.maxMillis - Arbitrary(chooseNum(0, maxMillis).flatMap(new LocalDateTime(_, params.chronology))) + Arbitrary(chooseNum(0L, maxMillis).flatMap(new LocalDateTime(_, params.chronology))) } } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 686dafb..f34dd08 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,11 +5,7 @@ object Dependencies { final val Scala_2_11 = "2.11.12" final val Scala_2_12 = "2.12.12" final val Scala_2_13 = "2.13.6" - - final val ScalaCheck_1_12 = "1.12.6" - final val ScalaCheck_1_13 = "1.13.5" - final val ScalaCheck_1_14 = "1.14.3" - final val ScalaCheck_1_15 = "1.15.2" + final val Scala_3 = "3.1.0" final private val ScalaTest_2 = "2.2.6" @@ -20,37 +16,50 @@ object Dependencies { final private val ScalaTest_3_0 = "3.0.5" final private val ScalaTest_3_2 = "3.2.9" - final private val ScalaTestPlusScalaCheckVersion = "3.2.2.0" + private def scalaTestPlusScalaCheckVersion(scalaVer: String) = CrossVersion.partialVersion(scalaVer) match { + case Some((3, _)) => "3.2.10.0" + case _ => "3.2.2.0" + } final private val IzumiReflectVersion = "1.1.2" final private val JodaTimeVersion = "2.10.10" final private val NewtypeVersion = "0.4.4" - final private val TaggingVersion = "2.3.0" + final private val TaggingVersion = "2.3.2" val izumiReflect: ModuleID = "dev.zio" %% "izumi-reflect" % IzumiReflectVersion - val newtype: ModuleID = "io.estatico" %% "newtype" % NewtypeVersion + val newtype: ModuleID = for3Use2("io.estatico" %% "newtype" % NewtypeVersion) % Test val jodaTime: ModuleID = "joda-time" % "joda-time" % JodaTimeVersion val tagging: ModuleID = "com.softwaremill.common" %% "tagging" % TaggingVersion - def scalaCheck(scalaCheckVersion: String): ModuleID = { - "org.scalacheck" %% "scalacheck" % scalaCheckVersion - } + case class ScalaCheckAxis( + idSuffix: String, + version: String, + scalaTestVersion: String + ) extends VirtualAxis.WeakAxis { + override def directorySuffix: String = s"-$idSuffix" + + def artifact = s"scalacheck-ops_$idSuffix" + + def subArtifact(sub: String) = s"scalacheck-ops-${sub}_$idSuffix" - def scalaTest(scalaCheckVersion: String): ModuleID = { - val scalaTestVersion = scalaCheckVersion match { - case ScalaCheck_1_12 => ScalaTest_2 - case ScalaCheck_1_13 => ScalaTest_3_0 - case ScalaCheck_1_14 | ScalaCheck_1_15 => ScalaTest_3_2 - } - "org.scalatest" %% "scalatest" % scalaTestVersion + def scalaCheck: ModuleID = + "org.scalacheck" %% "scalacheck" % version + + def scalaTest: ModuleID = + "org.scalatest" %% "scalatest" % scalaTestVersion % Test + + def scalaTestPlusScalaCheck(scalaVer: String): ModuleID = + "org.scalatestplus" %% s"scalacheck-${idSuffix}" % scalaTestPlusScalaCheckVersion(scalaVer) % Test } - def scalaTestPlusScalaCheck(scalaCheckVersion: String): ModuleID = { - val artifactName = scalaCheckVersion match { - case ScalaCheck_1_14 => "scalacheck-1-14" - case ScalaCheck_1_15 => "scalacheck-1-15" - } - "org.scalatestplus" %% artifactName % ScalaTestPlusScalaCheckVersion + object ScalaCheckAxis { + val v1_12 = ScalaCheckAxis("1-12", "1.12.6", ScalaTest_2) + val v1_13 = ScalaCheckAxis("1-13", "1.13.5", ScalaTest_3_0) + val v1_14 = ScalaCheckAxis("1-14", "1.14.3", ScalaTest_3_2) + val v1_15 = ScalaCheckAxis("1-15", "1.15.4", ScalaTest_3_2) } + + def for3Use2(m: ModuleID) = m.cross(CrossVersion.for3Use2_13) + } diff --git a/project/plugins.sbt b/project/plugins.sbt index 6a8423e..d14f15b 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,5 @@ addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.8.1") -addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.1") +addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.0-M3") addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.7") +addSbtPlugin("com.eed3si9n" % "sbt-projectmatrix" % "0.9.0")