Skip to content

Commit

Permalink
Merge pull request #224 from vigoo/scala3
Browse files Browse the repository at this point in the history
Scala 3 support
  • Loading branch information
vigoo authored May 30, 2021
2 parents d215bcb + b524aff commit a3a7ed6
Show file tree
Hide file tree
Showing 10 changed files with 738 additions and 709 deletions.
15 changes: 11 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
language: scala
scala:
- 2.12.12
- 2.13.5
- 2.13.6
- 3.0.0
before_install:
- git fetch --tags
- if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then bash
Expand All @@ -23,12 +24,18 @@ stages:
- name: microsite
if: ((branch = master AND type = push) AND NOT fork)

script: sbt ++$TRAVIS_SCALA_VERSION clean coverage test coverageReport && bash <(curl -s https://codecov.io/bash)
script: |
if [ "$TRAVIS_SCALA_VERSION" = "3.0.0" ]; then
sbt ++$TRAVIS_SCALA_VERSION clean test
else
sbt ++$TRAVIS_SCALA_VERSION clean coverage test coverageReport && bash <(curl -s https://codecov.io/bash);
fi
jobs:
include:
- scala: 2.12.14
scala: 2.13.6
- scala: 2.12.12
- scala: 2.13.6
- scala: 3.0.0
- stage: release
name: "Release"
script: sbt ci-release
Expand Down
36 changes: 27 additions & 9 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,26 @@ dynverSonatypeSnapshots in ThisBuild := true

val scala212 = "2.12.12"
val scala213 = "2.13.6"
val scala3 = "3.0.0"

val scalacOptions212 = Seq("-Ypartial-unification", "-deprecation")
val scalacOptions213 = Seq("-deprecation")
val scalacOptions3 = Seq("-deprecation", "-Ykind-projector")

lazy val commonSettings =
Seq(
scalaVersion := scala213,
crossScalaVersions := List(scala212, scala213),
crossScalaVersions := List(scala212, scala213, scala3),

organization := "io.github.vigoo",

addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.10.3"),
libraryDependencies ++=
(CrossVersion.partialVersion(scalaVersion.value) match {
case Some((3, _)) => Seq.empty
case _ => Seq(
compilerPlugin("org.typelevel" % "kind-projector" % "0.13.0" cross CrossVersion.full),
)
}),

libraryDependencies ++= Seq(
"org.typelevel" %% "cats-core" % "2.6.1",
Expand All @@ -33,6 +41,7 @@ lazy val commonSettings =
scalacOptions ++= (CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 12)) => scalacOptions212
case Some((2, 13)) => scalacOptions213
case Some((3, 0)) => scalacOptions3
case _ => Nil
}),

Expand Down Expand Up @@ -68,8 +77,11 @@ lazy val core = Project("clipp-core", file("clipp-core")).settings(commonSetting
description := "Clipp core",

libraryDependencies ++= Seq(
"org.specs2" %% "specs2-core" % "4.9.2" % "test"
)
"dev.zio" %% "zio-test" % "1.0.8" % Test,
"dev.zio" %% "zio-test-sbt" % "1.0.8" % Test
),

testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")
)

lazy val zio = Project("clipp-zio", file("clipp-zio")).settings(commonSettings).settings(
Expand All @@ -89,17 +101,23 @@ lazy val catsEffect = Project("clipp-cats-effect", file("clipp-cats-effect")).se

libraryDependencies ++= Seq(
"org.typelevel" %% "cats-effect" % "2.5.1",
"org.specs2" %% "specs2-core" % "4.12.0" % "test"
)
"dev.zio" %% "zio-test" % "1.0.8" % Test,
"dev.zio" %% "zio-test-sbt" % "1.0.8" % Test,
),

testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")
).dependsOn(core)

lazy val catsEffect3 = Project("clipp-cats-effect3", file("clipp-cats-effect3")).settings(commonSettings).settings(
description := "Clipp Cats-Effect 3 interface",

libraryDependencies ++= Seq(
"org.typelevel" %% "cats-effect" % "3.1.1",
"org.specs2" %% "specs2-core" % "4.12.0" % "test"
)
"dev.zio" %% "zio-test" % "1.0.8" % Test,
"dev.zio" %% "zio-test-sbt" % "1.0.8" % Test,
),

testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")
).dependsOn(core)

lazy val docs = project
Expand Down Expand Up @@ -142,7 +160,7 @@ lazy val docs = project
//micrositeAnalyticsToken := "UA-56320875-2",
includeFilter in makeSite := "*.html" | "*.css" | "*.png" | "*.jpg" | "*.gif" | "*.js" | "*.swf" | "*.txt" | "*.xml" | "*.svg",
)
.dependsOn(core, catsEffect, zio, catsEffect3)
.dependsOn(core, catsEffect, zio)

// Temporary fix to avoid including mdoc in the published POM

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,74 +5,70 @@ import cats.effect._
import io.github.vigoo.clipp.catseffect._
import io.github.vigoo.clipp.errors.{CustomError, ParserError}
import io.github.vigoo.clipp.syntax._
import org.specs2.matcher.Matcher
import org.specs2.mutable.Specification
import zio.test._
import zio.test.Assertion._
import zio.test.environment.TestEnvironment

class CatsEffectSpecs extends Specification {
object CatsEffectSpecs extends DefaultRunnableSpec {

"Cats Effect interface" should {
"successfully parse" in {
val test = {
val spec = flag("Test", 'x')
Clipp.parseOrFail[Boolean](List("-x"), spec)
}
override def spec: ZSpec[TestEnvironment, Any] =
suite("Cats Effect interface")(
test("successfully parse") {
val test = {
val spec = flag("Test", 'x')
Clipp.parseOrFail[Boolean](List("-x"), spec)
}

test.unsafeRunSync() === true
}
assert(test.unsafeRunSync())(isTrue)
},

"fail on bad spec" in {
val test = {
val spec = flag("Test", 'x')
Clipp.parseOrFail[Boolean](List("x"), spec)
.map(Right.apply[Throwable, Boolean])
.handleErrorWith(error => IO.pure(Left.apply[Throwable, Boolean](error)))
}
test("fail on bad spec") {
val test = {
val spec = flag("Test", 'x')
Clipp.parseOrFail[Boolean](List("x"), spec)
.map(Right.apply[Throwable, Boolean])
.handleErrorWith(error => IO.pure(Left.apply[Throwable, Boolean](error)))
}

test.unsafeRunSync() should beLeft
}
assert(test.unsafeRunSync())(isLeft(anything))
},

"fail or print succeeds" in {
val test = {
val spec = flag("Test", 'x')
Clipp.parseOrDisplayErrors(List("x"), spec, ()) { _ => IO.unit }
}
test("fail or print succeeds") {
val test = {
val spec = flag("Test", 'x')
Clipp.parseOrDisplayErrors(List("x"), spec, ()) { _ => IO.unit }
}

test.unsafeRunSync()
ok
}
assert(test.unsafeRunSync())(isUnit)
},

"liftEffect arbitrary effects to the parser" in {
"success" in {
Parser.extractParameters(
Seq("-v"),
for {
verbose <- flag("verbose", 'v')
result <- liftEffect("test", "ex1") {
IO.pure(verbose.toString)
}
} yield result
) should beRight()
}
suite("liftEffect arbitrary effects to the parser")(
test("success") {
assert(Parser.extractParameters(
Seq("-v"),
for {
verbose <- flag("verbose", 'v')
result <- liftEffect("test", "ex1") {
IO.pure(verbose.toString)
}
} yield result
))(isRight(anything))
},

"failure" in {
Parser.extractParameters(
Seq("-v"),
for {
verbose <- flag("verbose", 'v')
result <- liftEffect("test", "ex1") {
IO.raiseError(new RuntimeException("lifted function fails"))
}
} yield result
) should failWithErrors(CustomError("lifted function fails"))
}
}
}
test("failure") {
assert(Parser.extractParameters(
Seq("-v"),
for {
verbose <- flag("verbose", 'v')
result <- liftEffect("test", "ex1") {
IO.raiseError(new RuntimeException("lifted function fails"))
}
} yield result
))(failWithErrors(CustomError("lifted function fails")))
}
)
)

private def failWithErrors[T](error0: ParserError, errorss: ParserError*): Matcher[Either[ParserFailure, T]] =
(result: Either[ParserFailure, T]) =>
result match {
case Right(_) => ko("Expected failure, got success")
case Left(ParserFailure(errors, _, _)) =>
errors should beEqualTo(NonEmptyList(error0, errorss.toList))
}
private def failWithErrors[T](error0: ParserError, errorss: ParserError*): Assertion[Either[ParserFailure, T]] =
isLeft(hasField("errors", (f: ParserFailure) => f.errors, equalTo(NonEmptyList(error0, errorss.toList))))
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,74 +6,70 @@ import cats.effect.unsafe.implicits.global
import io.github.vigoo.clipp.catseffect3._
import io.github.vigoo.clipp.errors.{CustomError, ParserError}
import io.github.vigoo.clipp.syntax._
import org.specs2.matcher.Matcher
import org.specs2.mutable.Specification
import zio.test._
import zio.test.Assertion._
import zio.test.environment.TestEnvironment

class CatsEffectSpecs extends Specification {
object CatsEffectSpecs extends DefaultRunnableSpec {

"Cats Effect 3 interface" should {
"successfully parse" in {
val test = {
val spec = flag("Test", 'x')
Clipp.parseOrFail[Boolean](List("-x"), spec)
}
override def spec: ZSpec[TestEnvironment, Any] =
suite("Cats Effect 3 interface")(
test("successfully parse") {
val test = {
val spec = flag("Test", 'x')
Clipp.parseOrFail[Boolean](List("-x"), spec)
}

test.unsafeRunSync() === true
}
assert(test.unsafeRunSync())(isTrue)
},

"fail on bad spec" in {
val test = {
val spec = flag("Test", 'x')
Clipp.parseOrFail[Boolean](List("x"), spec)
.map(Right.apply[Throwable, Boolean])
.handleErrorWith(error => IO.pure(Left.apply[Throwable, Boolean](error)))
}
test("fail on bad spec") {
val test = {
val spec = flag("Test", 'x')
Clipp.parseOrFail[Boolean](List("x"), spec)
.map(Right.apply[Throwable, Boolean])
.handleErrorWith(error => IO.pure(Left.apply[Throwable, Boolean](error)))
}

test.unsafeRunSync() should beLeft
}
assert(test.unsafeRunSync())(isLeft(anything))
},

"fail or print succeeds" in {
val test = {
val spec = flag("Test", 'x')
Clipp.parseOrDisplayErrors(List("x"), spec, ()) { _ => IO.unit }
}
test("fail or print succeeds") {
val test = {
val spec = flag("Test", 'x')
Clipp.parseOrDisplayErrors(List("x"), spec, ()) { _ => IO.unit }
}

test.unsafeRunSync()
ok
}
assert(test.unsafeRunSync())(isUnit)
},

"liftEffect arbitrary effects to the parser" in {
"success" in {
Parser.extractParameters(
Seq("-v"),
for {
verbose <- flag("verbose", 'v')
result <- liftEffect("test", "ex1") {
IO.pure(verbose.toString)
}
} yield result
) should beRight()
}
suite("liftEffect arbitrary effects to the parser")(
test("success") {
assert(Parser.extractParameters(
Seq("-v"),
for {
verbose <- flag("verbose", 'v')
result <- liftEffect("test", "ex1") {
IO.pure(verbose.toString)
}
} yield result
))(isRight(anything))
},

"failure" in {
Parser.extractParameters(
Seq("-v"),
for {
verbose <- flag("verbose", 'v')
result <- liftEffect("test", "ex1") {
IO.raiseError(new RuntimeException("lifted function fails"))
}
} yield result
) should failWithErrors(CustomError("lifted function fails"))
}
}
}
test("failure") {
assert(Parser.extractParameters(
Seq("-v"),
for {
verbose <- flag("verbose", 'v')
result <- liftEffect("test", "ex1") {
IO.raiseError(new RuntimeException("lifted function fails"))
}
} yield result
))(failWithErrors(CustomError("lifted function fails")))
}
)
)

private def failWithErrors[T](error0: ParserError, errorss: ParserError*): Matcher[Either[ParserFailure, T]] =
(result: Either[ParserFailure, T]) =>
result match {
case Right(_) => ko("Expected failure, got success")
case Left(ParserFailure(errors, _, _)) =>
errors should beEqualTo(NonEmptyList(error0, errorss.toList))
}
private def failWithErrors[T](error0: ParserError, errorss: ParserError*): Assertion[Either[ParserFailure, T]] =
isLeft(hasField("errors", (f: ParserFailure) => f.errors, equalTo(NonEmptyList(error0, errorss.toList))))
}
Loading

0 comments on commit a3a7ed6

Please sign in to comment.