Skip to content

Commit a3a7ed6

Browse files
authored
Merge pull request #224 from vigoo/scala3
Scala 3 support
2 parents d215bcb + b524aff commit a3a7ed6

File tree

10 files changed

+738
-709
lines changed

10 files changed

+738
-709
lines changed

.travis.yml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
language: scala
22
scala:
33
- 2.12.12
4-
- 2.13.5
4+
- 2.13.6
5+
- 3.0.0
56
before_install:
67
- git fetch --tags
78
- if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then bash
@@ -23,12 +24,18 @@ stages:
2324
- name: microsite
2425
if: ((branch = master AND type = push) AND NOT fork)
2526

26-
script: sbt ++$TRAVIS_SCALA_VERSION clean coverage test coverageReport && bash <(curl -s https://codecov.io/bash)
27+
script: |
28+
if [ "$TRAVIS_SCALA_VERSION" = "3.0.0" ]; then
29+
sbt ++$TRAVIS_SCALA_VERSION clean test
30+
else
31+
sbt ++$TRAVIS_SCALA_VERSION clean coverage test coverageReport && bash <(curl -s https://codecov.io/bash);
32+
fi
2733
2834
jobs:
2935
include:
30-
- scala: 2.12.14
31-
scala: 2.13.6
36+
- scala: 2.12.12
37+
- scala: 2.13.6
38+
- scala: 3.0.0
3239
- stage: release
3340
name: "Release"
3441
script: sbt ci-release

build.sbt

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,26 @@ dynverSonatypeSnapshots in ThisBuild := true
77

88
val scala212 = "2.12.12"
99
val scala213 = "2.13.6"
10+
val scala3 = "3.0.0"
1011

1112
val scalacOptions212 = Seq("-Ypartial-unification", "-deprecation")
1213
val scalacOptions213 = Seq("-deprecation")
14+
val scalacOptions3 = Seq("-deprecation", "-Ykind-projector")
1315

1416
lazy val commonSettings =
1517
Seq(
1618
scalaVersion := scala213,
17-
crossScalaVersions := List(scala212, scala213),
19+
crossScalaVersions := List(scala212, scala213, scala3),
1820

1921
organization := "io.github.vigoo",
2022

21-
addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.10.3"),
23+
libraryDependencies ++=
24+
(CrossVersion.partialVersion(scalaVersion.value) match {
25+
case Some((3, _)) => Seq.empty
26+
case _ => Seq(
27+
compilerPlugin("org.typelevel" % "kind-projector" % "0.13.0" cross CrossVersion.full),
28+
)
29+
}),
2230

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

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

7079
libraryDependencies ++= Seq(
71-
"org.specs2" %% "specs2-core" % "4.9.2" % "test"
72-
)
80+
"dev.zio" %% "zio-test" % "1.0.8" % Test,
81+
"dev.zio" %% "zio-test-sbt" % "1.0.8" % Test
82+
),
83+
84+
testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")
7385
)
7486

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

90102
libraryDependencies ++= Seq(
91103
"org.typelevel" %% "cats-effect" % "2.5.1",
92-
"org.specs2" %% "specs2-core" % "4.12.0" % "test"
93-
)
104+
"dev.zio" %% "zio-test" % "1.0.8" % Test,
105+
"dev.zio" %% "zio-test-sbt" % "1.0.8" % Test,
106+
),
107+
108+
testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")
94109
).dependsOn(core)
95110

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

99114
libraryDependencies ++= Seq(
100115
"org.typelevel" %% "cats-effect" % "3.1.1",
101-
"org.specs2" %% "specs2-core" % "4.12.0" % "test"
102-
)
116+
"dev.zio" %% "zio-test" % "1.0.8" % Test,
117+
"dev.zio" %% "zio-test-sbt" % "1.0.8" % Test,
118+
),
119+
120+
testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")
103121
).dependsOn(core)
104122

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

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

clipp-cats-effect/src/test/scala/io/github/vigoo/clipp/CatsEffectSpecs.scala

Lines changed: 56 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -5,74 +5,70 @@ import cats.effect._
55
import io.github.vigoo.clipp.catseffect._
66
import io.github.vigoo.clipp.errors.{CustomError, ParserError}
77
import io.github.vigoo.clipp.syntax._
8-
import org.specs2.matcher.Matcher
9-
import org.specs2.mutable.Specification
8+
import zio.test._
9+
import zio.test.Assertion._
10+
import zio.test.environment.TestEnvironment
1011

11-
class CatsEffectSpecs extends Specification {
12+
object CatsEffectSpecs extends DefaultRunnableSpec {
1213

13-
"Cats Effect interface" should {
14-
"successfully parse" in {
15-
val test = {
16-
val spec = flag("Test", 'x')
17-
Clipp.parseOrFail[Boolean](List("-x"), spec)
18-
}
14+
override def spec: ZSpec[TestEnvironment, Any] =
15+
suite("Cats Effect interface")(
16+
test("successfully parse") {
17+
val test = {
18+
val spec = flag("Test", 'x')
19+
Clipp.parseOrFail[Boolean](List("-x"), spec)
20+
}
1921

20-
test.unsafeRunSync() === true
21-
}
22+
assert(test.unsafeRunSync())(isTrue)
23+
},
2224

23-
"fail on bad spec" in {
24-
val test = {
25-
val spec = flag("Test", 'x')
26-
Clipp.parseOrFail[Boolean](List("x"), spec)
27-
.map(Right.apply[Throwable, Boolean])
28-
.handleErrorWith(error => IO.pure(Left.apply[Throwable, Boolean](error)))
29-
}
25+
test("fail on bad spec") {
26+
val test = {
27+
val spec = flag("Test", 'x')
28+
Clipp.parseOrFail[Boolean](List("x"), spec)
29+
.map(Right.apply[Throwable, Boolean])
30+
.handleErrorWith(error => IO.pure(Left.apply[Throwable, Boolean](error)))
31+
}
3032

31-
test.unsafeRunSync() should beLeft
32-
}
33+
assert(test.unsafeRunSync())(isLeft(anything))
34+
},
3335

34-
"fail or print succeeds" in {
35-
val test = {
36-
val spec = flag("Test", 'x')
37-
Clipp.parseOrDisplayErrors(List("x"), spec, ()) { _ => IO.unit }
38-
}
36+
test("fail or print succeeds") {
37+
val test = {
38+
val spec = flag("Test", 'x')
39+
Clipp.parseOrDisplayErrors(List("x"), spec, ()) { _ => IO.unit }
40+
}
3941

40-
test.unsafeRunSync()
41-
ok
42-
}
42+
assert(test.unsafeRunSync())(isUnit)
43+
},
4344

44-
"liftEffect arbitrary effects to the parser" in {
45-
"success" in {
46-
Parser.extractParameters(
47-
Seq("-v"),
48-
for {
49-
verbose <- flag("verbose", 'v')
50-
result <- liftEffect("test", "ex1") {
51-
IO.pure(verbose.toString)
52-
}
53-
} yield result
54-
) should beRight()
55-
}
45+
suite("liftEffect arbitrary effects to the parser")(
46+
test("success") {
47+
assert(Parser.extractParameters(
48+
Seq("-v"),
49+
for {
50+
verbose <- flag("verbose", 'v')
51+
result <- liftEffect("test", "ex1") {
52+
IO.pure(verbose.toString)
53+
}
54+
} yield result
55+
))(isRight(anything))
56+
},
5657

57-
"failure" in {
58-
Parser.extractParameters(
59-
Seq("-v"),
60-
for {
61-
verbose <- flag("verbose", 'v')
62-
result <- liftEffect("test", "ex1") {
63-
IO.raiseError(new RuntimeException("lifted function fails"))
64-
}
65-
} yield result
66-
) should failWithErrors(CustomError("lifted function fails"))
67-
}
68-
}
69-
}
58+
test("failure") {
59+
assert(Parser.extractParameters(
60+
Seq("-v"),
61+
for {
62+
verbose <- flag("verbose", 'v')
63+
result <- liftEffect("test", "ex1") {
64+
IO.raiseError(new RuntimeException("lifted function fails"))
65+
}
66+
} yield result
67+
))(failWithErrors(CustomError("lifted function fails")))
68+
}
69+
)
70+
)
7071

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

clipp-cats-effect3/src/test/scala/io/github/vigoo/clipp/CatsEffectSpecs.scala

Lines changed: 56 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,74 +6,70 @@ import cats.effect.unsafe.implicits.global
66
import io.github.vigoo.clipp.catseffect3._
77
import io.github.vigoo.clipp.errors.{CustomError, ParserError}
88
import io.github.vigoo.clipp.syntax._
9-
import org.specs2.matcher.Matcher
10-
import org.specs2.mutable.Specification
9+
import zio.test._
10+
import zio.test.Assertion._
11+
import zio.test.environment.TestEnvironment
1112

12-
class CatsEffectSpecs extends Specification {
13+
object CatsEffectSpecs extends DefaultRunnableSpec {
1314

14-
"Cats Effect 3 interface" should {
15-
"successfully parse" in {
16-
val test = {
17-
val spec = flag("Test", 'x')
18-
Clipp.parseOrFail[Boolean](List("-x"), spec)
19-
}
15+
override def spec: ZSpec[TestEnvironment, Any] =
16+
suite("Cats Effect 3 interface")(
17+
test("successfully parse") {
18+
val test = {
19+
val spec = flag("Test", 'x')
20+
Clipp.parseOrFail[Boolean](List("-x"), spec)
21+
}
2022

21-
test.unsafeRunSync() === true
22-
}
23+
assert(test.unsafeRunSync())(isTrue)
24+
},
2325

24-
"fail on bad spec" in {
25-
val test = {
26-
val spec = flag("Test", 'x')
27-
Clipp.parseOrFail[Boolean](List("x"), spec)
28-
.map(Right.apply[Throwable, Boolean])
29-
.handleErrorWith(error => IO.pure(Left.apply[Throwable, Boolean](error)))
30-
}
26+
test("fail on bad spec") {
27+
val test = {
28+
val spec = flag("Test", 'x')
29+
Clipp.parseOrFail[Boolean](List("x"), spec)
30+
.map(Right.apply[Throwable, Boolean])
31+
.handleErrorWith(error => IO.pure(Left.apply[Throwable, Boolean](error)))
32+
}
3133

32-
test.unsafeRunSync() should beLeft
33-
}
34+
assert(test.unsafeRunSync())(isLeft(anything))
35+
},
3436

35-
"fail or print succeeds" in {
36-
val test = {
37-
val spec = flag("Test", 'x')
38-
Clipp.parseOrDisplayErrors(List("x"), spec, ()) { _ => IO.unit }
39-
}
37+
test("fail or print succeeds") {
38+
val test = {
39+
val spec = flag("Test", 'x')
40+
Clipp.parseOrDisplayErrors(List("x"), spec, ()) { _ => IO.unit }
41+
}
4042

41-
test.unsafeRunSync()
42-
ok
43-
}
43+
assert(test.unsafeRunSync())(isUnit)
44+
},
4445

45-
"liftEffect arbitrary effects to the parser" in {
46-
"success" in {
47-
Parser.extractParameters(
48-
Seq("-v"),
49-
for {
50-
verbose <- flag("verbose", 'v')
51-
result <- liftEffect("test", "ex1") {
52-
IO.pure(verbose.toString)
53-
}
54-
} yield result
55-
) should beRight()
56-
}
46+
suite("liftEffect arbitrary effects to the parser")(
47+
test("success") {
48+
assert(Parser.extractParameters(
49+
Seq("-v"),
50+
for {
51+
verbose <- flag("verbose", 'v')
52+
result <- liftEffect("test", "ex1") {
53+
IO.pure(verbose.toString)
54+
}
55+
} yield result
56+
))(isRight(anything))
57+
},
5758

58-
"failure" in {
59-
Parser.extractParameters(
60-
Seq("-v"),
61-
for {
62-
verbose <- flag("verbose", 'v')
63-
result <- liftEffect("test", "ex1") {
64-
IO.raiseError(new RuntimeException("lifted function fails"))
65-
}
66-
} yield result
67-
) should failWithErrors(CustomError("lifted function fails"))
68-
}
69-
}
70-
}
59+
test("failure") {
60+
assert(Parser.extractParameters(
61+
Seq("-v"),
62+
for {
63+
verbose <- flag("verbose", 'v')
64+
result <- liftEffect("test", "ex1") {
65+
IO.raiseError(new RuntimeException("lifted function fails"))
66+
}
67+
} yield result
68+
))(failWithErrors(CustomError("lifted function fails")))
69+
}
70+
)
71+
)
7172

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

0 commit comments

Comments
 (0)