Skip to content

Commit

Permalink
Cross build for all Scala versions again - will start 2.x with Scala
Browse files Browse the repository at this point in the history
2.11 support dropped instead; more robust test support, compatible with
  Java 18
  • Loading branch information
orbang committed Nov 12, 2022
1 parent ab856bd commit b83acc6
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 204 deletions.
16 changes: 10 additions & 6 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@
name := "sclap"

ThisBuild / organization := "io.jobial"
ThisBuild / crossScalaVersions := Seq("2.12.15", "2.13.7")
ThisBuild / version := "1.3.6"
ThisBuild / crossScalaVersions := Seq("2.11.12", "2.12.15", "2.13.7")
ThisBuild / scalaVersion := "2.13.7"
ThisBuild / version := "1.4.0"
ThisBuild / scalacOptions += "-target:jvm-1.8"
ThisBuild / javacOptions ++= Seq("-source", "11", "-target", "11")
ThisBuild / publishArtifact in (Test, packageBin) := true
ThisBuild / publishArtifact in (Test, packageSrc) := true
ThisBuild / publishArtifact in (Test, packageDoc) := true
ThisBuild / Test / fork := true

import sbt.Keys.{description, publishConfiguration}
import xerial.sbt.Sonatype._
Expand All @@ -34,13 +38,13 @@ lazy val commonSettings = Seq(
addCompilerPlugin("org.typelevel" % "kind-projector" % "0.13.2" cross CrossVersion.full),
scalacOptions ++= (if (scalaBinaryVersion.value != "2.13") Seq("-Ypartial-unification") else Seq())
)

lazy val CatsVersion = "2.7.0"
lazy val CatsEffectVersion = "2.5.4"
lazy val CatsVersion = "2.0.0"
lazy val CatsEffectVersion = "2.0.0"
lazy val ScalaLoggingVersion = "3.9.2"
lazy val PicocliVersion = "4.6.1"
lazy val ScalatestVersion = "3.2.3"
lazy val ZioVersion = "2.5.1.0" // TODO: upgrade when Cats version is upgraded
lazy val ZioVersion = "2.0.0.0-RC13" // TODO: upgrade when Cats version is upgraded

lazy val root: Project = project
.in(file("."))
Expand Down
166 changes: 8 additions & 158 deletions sclap-app/src/test/scala/io/jobial/sclap/CommandLineParserTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
package io.jobial.sclap

import cats.effect.IO
import cats.evidence.===
import io.jobial.sclap.core.{ArgumentValueParser, ArgumentValuePrinter, IncorrectCommandLineUsage, IncorrectCommandLineUsageInSubcommand}
import org.scalatest.flatspec.AsyncFlatSpec

Expand All @@ -32,167 +33,16 @@ class CommandLineParserTest
} yield
IO.raiseError[Unit](new Throwable("an error"))
}

runCommandLineTestCases(spec)(
Seq() -> failWithThrowable[Unit, Throwable](t => assert(t.getMessage == "an error"),
out = Some(""), err = Some("""an error
Seq() -> failWithThrowable[Unit, Throwable]({ t: Throwable => assert(t.getMessage == "an error") },
{ out: String => out == "" }, (_: String).startsWith("""an error
java.lang.Throwable: an error
at io.jobial.sclap.CommandLineParserTest.$anonfun$new$1(CommandLineParserTest.scala:33)
at cats.free.Free.$anonfun$map$1(Free.scala:18)
at cats.free.Free.$anonfun$foldMap$3(Free.scala:156)
at cats.Monad.$anonfun$map$1(Monad.scala:16)
at cats.data.IndexedStateT.$anonfun$flatMap$3(IndexedStateT.scala:28)
at cats.Eval$.loop$1(Eval.scala:363)
at cats.Eval$.cats$Eval$$evaluate(Eval.scala:368)
at cats.Eval$FlatMap.value(Eval.scala:307)
at io.jobial.sclap.impl.picocli.PicocliCommandLineParser.$anonfun$executeCommandLine$5(PicocliCommandLineParser.scala:381)
at cats.effect.internals.IORunLoop$.liftedTree3$1(IORunLoop.scala:229)
at cats.effect.internals.IORunLoop$.step(IORunLoop.scala:229)
at cats.effect.IO.unsafeRunTimed(IO.scala:320)
at cats.effect.IO.unsafeRunSync(IO.scala:239)
at io.jobial.sclap.CommandLineParserTestHelperNoImplicits.$anonfun$runCommandLineTest$1(CommandLineParserTestHelperNoImplicits.scala:49)
at scala.util.Try$.apply(Try.scala:213)
at io.jobial.sclap.OutputCaptureUtils.$anonfun$captureOutput$1(OutputCaptureUtils.scala:99)
at cats.effect.internals.IORunLoop$.cats$effect$internals$IORunLoop$$loop(IORunLoop.scala:87)
at cats.effect.internals.IORunLoop$.start(IORunLoop.scala:34)
at cats.effect.IO.unsafeRunAsync(IO.scala:257)
at cats.effect.IO.unsafeToFuture(IO.scala:344)
at io.jobial.sclap.CommandLineParserTestHelperNoImplicits.$anonfun$runCommandLineTestCases$3(CommandLineParserTestHelperNoImplicits.scala:75)
at org.scalatest.flatspec.AsyncFlatSpecLike.transformToOutcomeParam$1(AsyncFlatSpecLike.scala:139)
at org.scalatest.flatspec.AsyncFlatSpecLike.$anonfun$registerTestToRun$1(AsyncFlatSpecLike.scala:145)
at org.scalatest.AsyncTestSuite.$anonfun$transformToOutcome$1(AsyncTestSuite.scala:240)
at org.scalatest.flatspec.AsyncFlatSpecLike$$anon$5.apply(AsyncFlatSpecLike.scala:1698)
at org.scalatest.AsyncTestSuite.withFixture(AsyncTestSuite.scala:313)
at org.scalatest.AsyncTestSuite.withFixture$(AsyncTestSuite.scala:312)
at org.scalatest.flatspec.AsyncFlatSpec.withFixture(AsyncFlatSpec.scala:2221)
at org.scalatest.flatspec.AsyncFlatSpecLike.invokeWithAsyncFixture$1(AsyncFlatSpecLike.scala:1696)
at org.scalatest.flatspec.AsyncFlatSpecLike.$anonfun$runTest$1(AsyncFlatSpecLike.scala:1710)
at org.scalatest.AsyncSuperEngine.runTestImpl(AsyncEngine.scala:374)
at org.scalatest.flatspec.AsyncFlatSpecLike.runTest(AsyncFlatSpecLike.scala:1710)
at org.scalatest.flatspec.AsyncFlatSpecLike.runTest$(AsyncFlatSpecLike.scala:1689)
at org.scalatest.flatspec.AsyncFlatSpec.runTest(AsyncFlatSpec.scala:2221)
at org.scalatest.flatspec.AsyncFlatSpecLike.$anonfun$runTests$1(AsyncFlatSpecLike.scala:1768)
at org.scalatest.AsyncSuperEngine.$anonfun$runTestsInBranch$1(AsyncEngine.scala:432)
at scala.collection.LinearSeqOptimized.foldLeft(LinearSeqOptimized.scala:126)
at scala.collection.LinearSeqOptimized.foldLeft$(LinearSeqOptimized.scala:122)
at scala.collection.immutable.List.foldLeft(List.scala:91)
at org.scalatest.AsyncSuperEngine.traverseSubNodes$1(AsyncEngine.scala:406)
at org.scalatest.AsyncSuperEngine.runTestsInBranch(AsyncEngine.scala:479)
at org.scalatest.AsyncSuperEngine.$anonfun$runTestsInBranch$1(AsyncEngine.scala:460)
at scala.collection.LinearSeqOptimized.foldLeft(LinearSeqOptimized.scala:126)
at scala.collection.LinearSeqOptimized.foldLeft$(LinearSeqOptimized.scala:122)
at scala.collection.immutable.List.foldLeft(List.scala:91)
at org.scalatest.AsyncSuperEngine.traverseSubNodes$1(AsyncEngine.scala:406)
at org.scalatest.AsyncSuperEngine.runTestsInBranch(AsyncEngine.scala:487)
at org.scalatest.AsyncSuperEngine.runTestsImpl(AsyncEngine.scala:555)
at org.scalatest.flatspec.AsyncFlatSpecLike.runTests(AsyncFlatSpecLike.scala:1768)
at org.scalatest.flatspec.AsyncFlatSpecLike.runTests$(AsyncFlatSpecLike.scala:1767)
at org.scalatest.flatspec.AsyncFlatSpec.runTests(AsyncFlatSpec.scala:2221)
at org.scalatest.Suite.run(Suite.scala:1112)
at org.scalatest.Suite.run$(Suite.scala:1094)
at org.scalatest.flatspec.AsyncFlatSpec.org$scalatest$flatspec$AsyncFlatSpecLike$$super$run(AsyncFlatSpec.scala:2221)
at org.scalatest.flatspec.AsyncFlatSpecLike.$anonfun$run$1(AsyncFlatSpecLike.scala:1813)
at org.scalatest.AsyncSuperEngine.runImpl(AsyncEngine.scala:625)
at org.scalatest.flatspec.AsyncFlatSpecLike.run(AsyncFlatSpecLike.scala:1813)
at org.scalatest.flatspec.AsyncFlatSpecLike.run$(AsyncFlatSpecLike.scala:1811)
at org.scalatest.flatspec.AsyncFlatSpec.run(AsyncFlatSpec.scala:2221)
at org.scalatest.tools.SuiteRunner.run(SuiteRunner.scala:45)
at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$13(Runner.scala:1320)
at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$13$adapted(Runner.scala:1314)
at scala.collection.immutable.List.foreach(List.scala:431)
at org.scalatest.tools.Runner$.doRunRunRunDaDoRunRun(Runner.scala:1314)
at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24(Runner.scala:993)
at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24$adapted(Runner.scala:971)
at org.scalatest.tools.Runner$.withClassLoaderAndDispatchReporter(Runner.scala:1480)
at org.scalatest.tools.Runner$.runOptionallyWithPassFailReporter(Runner.scala:971)
at org.scalatest.tools.Runner$.run(Runner.scala:798)
at org.scalatest.tools.Runner.run(Runner.scala)
at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.runScalaTest2or3(ScalaTestRunner.java:38)
at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.main(ScalaTestRunner.java:25)
""")),
Seq("-a", "hello") -> failWithThrowable[Unit, Throwable](t => assert(t.getMessage == "an error"),
out = Some(""), err = Some("""an error
at io.jobial.sclap.CommandLineParserTest""")),
Seq("-a", "hello") -> failWithThrowable[Unit, Throwable]({ t: Throwable => assert(t.getMessage == "an error") },
{ out: String => out == "" }, (_: String).startsWith("""an error
java.lang.Throwable: an error
at io.jobial.sclap.CommandLineParserTest.$anonfun$new$1(CommandLineParserTest.scala:33)
at cats.free.Free.$anonfun$map$1(Free.scala:18)
at cats.free.Free.$anonfun$foldMap$3(Free.scala:156)
at cats.Monad.$anonfun$map$1(Monad.scala:16)
at cats.data.IndexedStateT.$anonfun$flatMap$3(IndexedStateT.scala:28)
at cats.Eval$.loop$1(Eval.scala:363)
at cats.Eval$.cats$Eval$$evaluate(Eval.scala:368)
at cats.Eval$FlatMap.value(Eval.scala:307)
at io.jobial.sclap.impl.picocli.PicocliCommandLineParser.$anonfun$executeCommandLine$5(PicocliCommandLineParser.scala:381)
at cats.effect.internals.IORunLoop$.liftedTree3$1(IORunLoop.scala:229)
at cats.effect.internals.IORunLoop$.step(IORunLoop.scala:229)
at cats.effect.IO.unsafeRunTimed(IO.scala:320)
at cats.effect.IO.unsafeRunSync(IO.scala:239)
at io.jobial.sclap.CommandLineParserTestHelperNoImplicits.$anonfun$runCommandLineTest$1(CommandLineParserTestHelperNoImplicits.scala:49)
at scala.util.Try$.apply(Try.scala:213)
at io.jobial.sclap.OutputCaptureUtils.$anonfun$captureOutput$1(OutputCaptureUtils.scala:99)
at cats.effect.internals.IORunLoop$.cats$effect$internals$IORunLoop$$loop(IORunLoop.scala:87)
at cats.effect.internals.IORunLoop$.start(IORunLoop.scala:34)
at cats.effect.IO.unsafeRunAsync(IO.scala:257)
at cats.effect.IO.unsafeToFuture(IO.scala:344)
at io.jobial.sclap.CommandLineParserTestHelperNoImplicits.$anonfun$runCommandLineTestCases$3(CommandLineParserTestHelperNoImplicits.scala:75)
at org.scalatest.flatspec.AsyncFlatSpecLike.transformToOutcomeParam$1(AsyncFlatSpecLike.scala:139)
at org.scalatest.flatspec.AsyncFlatSpecLike.$anonfun$registerTestToRun$1(AsyncFlatSpecLike.scala:145)
at org.scalatest.AsyncTestSuite.$anonfun$transformToOutcome$1(AsyncTestSuite.scala:240)
at org.scalatest.flatspec.AsyncFlatSpecLike$$anon$5.apply(AsyncFlatSpecLike.scala:1698)
at org.scalatest.AsyncTestSuite.withFixture(AsyncTestSuite.scala:313)
at org.scalatest.AsyncTestSuite.withFixture$(AsyncTestSuite.scala:312)
at org.scalatest.flatspec.AsyncFlatSpec.withFixture(AsyncFlatSpec.scala:2221)
at org.scalatest.flatspec.AsyncFlatSpecLike.invokeWithAsyncFixture$1(AsyncFlatSpecLike.scala:1696)
at org.scalatest.flatspec.AsyncFlatSpecLike.$anonfun$runTest$1(AsyncFlatSpecLike.scala:1710)
at org.scalatest.AsyncSuperEngine.runTestImpl(AsyncEngine.scala:374)
at org.scalatest.flatspec.AsyncFlatSpecLike.runTest(AsyncFlatSpecLike.scala:1710)
at org.scalatest.flatspec.AsyncFlatSpecLike.runTest$(AsyncFlatSpecLike.scala:1689)
at org.scalatest.flatspec.AsyncFlatSpec.runTest(AsyncFlatSpec.scala:2221)
at org.scalatest.flatspec.AsyncFlatSpecLike.$anonfun$runTests$1(AsyncFlatSpecLike.scala:1768)
at org.scalatest.AsyncSuperEngine.$anonfun$runTestsInBranch$3(AsyncEngine.scala:435)
at org.scalatest.Status.$anonfun$thenRun$1(Status.scala:227)
at org.scalatest.Status.$anonfun$thenRun$1$adapted(Status.scala:225)
at org.scalatest.ScalaTestStatefulStatus.whenCompleted(Status.scala:648)
at org.scalatest.Status.thenRun(Status.scala:225)
at org.scalatest.Status.thenRun$(Status.scala:220)
at org.scalatest.ScalaTestStatefulStatus.thenRun(Status.scala:511)
at org.scalatest.AsyncSuperEngine.$anonfun$runTestsInBranch$1(AsyncEngine.scala:435)
at scala.collection.LinearSeqOptimized.foldLeft(LinearSeqOptimized.scala:126)
at scala.collection.LinearSeqOptimized.foldLeft$(LinearSeqOptimized.scala:122)
at scala.collection.immutable.List.foldLeft(List.scala:91)
at org.scalatest.AsyncSuperEngine.traverseSubNodes$1(AsyncEngine.scala:406)
at org.scalatest.AsyncSuperEngine.runTestsInBranch(AsyncEngine.scala:479)
at org.scalatest.AsyncSuperEngine.$anonfun$runTestsInBranch$1(AsyncEngine.scala:460)
at scala.collection.LinearSeqOptimized.foldLeft(LinearSeqOptimized.scala:126)
at scala.collection.LinearSeqOptimized.foldLeft$(LinearSeqOptimized.scala:122)
at scala.collection.immutable.List.foldLeft(List.scala:91)
at org.scalatest.AsyncSuperEngine.traverseSubNodes$1(AsyncEngine.scala:406)
at org.scalatest.AsyncSuperEngine.runTestsInBranch(AsyncEngine.scala:487)
at org.scalatest.AsyncSuperEngine.runTestsImpl(AsyncEngine.scala:555)
at org.scalatest.flatspec.AsyncFlatSpecLike.runTests(AsyncFlatSpecLike.scala:1768)
at org.scalatest.flatspec.AsyncFlatSpecLike.runTests$(AsyncFlatSpecLike.scala:1767)
at org.scalatest.flatspec.AsyncFlatSpec.runTests(AsyncFlatSpec.scala:2221)
at org.scalatest.Suite.run(Suite.scala:1112)
at org.scalatest.Suite.run$(Suite.scala:1094)
at org.scalatest.flatspec.AsyncFlatSpec.org$scalatest$flatspec$AsyncFlatSpecLike$$super$run(AsyncFlatSpec.scala:2221)
at org.scalatest.flatspec.AsyncFlatSpecLike.$anonfun$run$1(AsyncFlatSpecLike.scala:1813)
at org.scalatest.AsyncSuperEngine.runImpl(AsyncEngine.scala:625)
at org.scalatest.flatspec.AsyncFlatSpecLike.run(AsyncFlatSpecLike.scala:1813)
at org.scalatest.flatspec.AsyncFlatSpecLike.run$(AsyncFlatSpecLike.scala:1811)
at org.scalatest.flatspec.AsyncFlatSpec.run(AsyncFlatSpec.scala:2221)
at org.scalatest.tools.SuiteRunner.run(SuiteRunner.scala:45)
at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$13(Runner.scala:1320)
at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$13$adapted(Runner.scala:1314)
at scala.collection.immutable.List.foreach(List.scala:431)
at org.scalatest.tools.Runner$.doRunRunRunDaDoRunRun(Runner.scala:1314)
at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24(Runner.scala:993)
at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24$adapted(Runner.scala:971)
at org.scalatest.tools.Runner$.withClassLoaderAndDispatchReporter(Runner.scala:1480)
at org.scalatest.tools.Runner$.runOptionallyWithPassFailReporter(Runner.scala:971)
at org.scalatest.tools.Runner$.run(Runner.scala:798)
at org.scalatest.tools.Runner.run(Runner.scala)
at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.runScalaTest2or3(ScalaTestRunner.java:38)
at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.main(ScalaTestRunner.java:25)
"""))
at io.jobial.sclap.CommandLineParserTest"""))
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,28 +123,49 @@ trait CommandLineParserTestHelperNoImplicits extends CommandLineParserNoImplicit
}
})

def failWith[T](check: Throwable => Assertion, out: String => Boolean, err: String => Boolean) =
TestFailureCheck[T](
{ testResult: TestResult[T] =>
testResult.result match {
case Right(r) =>
IO(fail(s"expected failure, got $testResult"))
case Left(t) =>
IO(assert(out(testResult.out))) *>
IO(assert(err(testResult.err))) *>
IO(check(t))
}
})

def failWithThrowable[T, X <: Throwable : ClassTag](f: X => Assertion = { _: X => Succeeded }, out: Option[String] = None, err: Option[String] = None) =
failWith[T]({
case x: X =>
f(x)
case x: Throwable =>
fail(s"wrong exception is thrown: ", x)
}, out, err)
}: Throwable => Assertion, out, err)

def failWithThrowable[T, X <: Throwable : ClassTag](f: X => Assertion, out: String => Boolean, err: String => Boolean) =
failWith[T]({
case x: X =>
f(x)
case x: Throwable =>
fail(s"wrong exception is thrown: ", x)
}: Throwable => Assertion, out, err)

def failCommandExecutionWith[X <: Throwable : ClassTag](f: X => Assertion = { _: X => Succeeded }, out: Option[String] = None, err: Option[String] = None) =
failWithThrowable[(Option[String], Any), X](f, out, err)

def failWithUsageHelpRequested[T](help: String) =
failWithThrowable[T, UsageHelpRequested](_ => Succeeded, out = Some(help), None)
failWithThrowable[T, UsageHelpRequested]({ _: Throwable => Succeeded }, out = Some(help), None)

def failWithVersionHelpRequested[T](version: String) =
failWithThrowable[T, VersionHelpRequested](_ => Succeeded, out = Some(version), None)
failWithThrowable[T, VersionHelpRequested]({ _: Throwable => Succeeded }, out = Some(version), None)

def failCommandLineParsingWith[T](message: String) =
failWithThrowable[T, CommandLineParsingFailed](t => assert(t.getMessage == message))
failWithThrowable[T, CommandLineParsingFailed] { t: Throwable => assert(t.getMessage == message) }

def failSubcommandLineParsingWith[T](message: String) =
failWithThrowable[T, CommandLineParsingFailedForSubcommand](t => assert(t.getMessage == message))
failWithThrowable[T, CommandLineParsingFailedForSubcommand] { t: Throwable => assert(t.getMessage == message) }

def createNewInstanceOf[T <: {def main(args: Array[String]): Unit}](o: T) =
createNewInstanceOfWithConstructor(o) { classOfApp =>
Expand Down
Loading

0 comments on commit b83acc6

Please sign in to comment.