Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cross-build to scala 3 #244

Merged
merged 8 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
scala: [2.13.15, 2.12.20]
scala: [2.13.15, 2.12.20, 3.3.4]
java: [temurin@21]
runs-on: ${{ matrix.os }}
steps:
Expand All @@ -50,12 +50,12 @@ jobs:
- name: Check that workflows are up to date
run: sbt '++ ${{ matrix.scala }}' githubWorkflowCheck

- run: sbt '++ ${{ matrix.scala }}' scalafmtCheck

- env:
HONEYCOMB_WRITE_KEY: ${{ secrets.HONEYCOMB_WRITE_KEY }}
run: sbt '++ ${{ matrix.scala }}' test

- run: 'bash <(curl -s https://codecov.io/bash)'

- name: Compress target directories
run: tar cf targets.tar target project/target

Expand Down Expand Up @@ -112,6 +112,16 @@ jobs:
tar xf targets.tar
rm targets.tar

- name: Download target directories (3.3.4)
uses: actions/download-artifact@v4
with:
name: target-${{ matrix.os }}-3.3.4-${{ matrix.java }}

- name: Inflate target directories (3.3.4)
run: |
tar xf targets.tar
rm targets.tar

- run: |
git config user.name "Github Actions (dimitarg/weaver-test-extra)"
git config user.email "[email protected]"
Expand Down
3 changes: 3 additions & 0 deletions .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
version = 3.8.2
runner.dialect = scala213source3
maxColumn = 120
32 changes: 26 additions & 6 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ name := "weaver-test-extra"
ThisBuild / organization := "io.github.dimitarg"

ThisBuild / scalaVersion := "2.13.15"
ThisBuild / crossScalaVersions := Seq("2.13.15", "2.12.20")
ThisBuild / githubWorkflowScalaVersions := Seq("2.13.15", "2.12.20")
ThisBuild / crossScalaVersions := Seq("2.13.15", "2.12.20", "3.3.4")
ThisBuild / githubWorkflowScalaVersions := Seq("2.13.15", "2.12.20", "3.3.4")

ThisBuild / githubWorkflowJavaVersions := Seq(JavaSpec.temurin("21"))

ThisBuild / githubWorkflowBuild := Seq(
WorkflowStep.Sbt(
commands = List("scalafmtCheck")
),
WorkflowStep.Sbt(
// scoverage plugin not yet supporting scala 2.13.15
// commands = List("coverage", "test"),
Expand All @@ -34,9 +37,10 @@ ThisBuild / githubWorkflowPublishTargetBranches += RefPredicate.Equals(Ref.Branc

ThisBuild / licenses += ("Apache-2.0", url("https://opensource.org/licenses/Apache-2.0"))

ThisBuild / githubWorkflowBuildPostamble := Seq(WorkflowStep.Run(
commands = List("bash <(curl -s https://codecov.io/bash)")
))
// scoverage plugin not yet supporting scala 2.13.15
// ThisBuild / githubWorkflowBuildPostamble := Seq(WorkflowStep.Run(
// commands = List("bash <(curl -s https://codecov.io/bash)")
// ))

ThisBuild / githubWorkflowPublishPreamble := Seq(WorkflowStep.Run(
List(
Expand Down Expand Up @@ -67,7 +71,23 @@ libraryDependencies ++=Seq(

testFrameworks += new TestFramework("weaver.framework.CatsEffect")

addCompilerPlugin("org.typelevel" % "kind-projector" % "0.13.3" cross CrossVersion.full)
libraryDependencies ++= {
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, n)) =>
List(
compilerPlugin("org.typelevel" % "kind-projector" % "0.13.3" cross CrossVersion.full)
)
case _ =>
Nil
}
}

ThisBuild / scalacOptions ++= {
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 12 | 13)) => Seq("-Xsource:3-cross", "-P:kind-projector:underscore-placeholders")
case _ => Nil
}
}

releasePublishArtifactsAction := PgpKeys.publishSigned.value

Expand Down
1 change: 1 addition & 0 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ addSbtPlugin("org.typelevel" % "sbt-tpolecat" % "0.5.2")
addSbtPlugin("com.github.sbt" % "sbt-release" % "1.4.0")
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.12.2")
addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.0")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2")
2 changes: 1 addition & 1 deletion src/main/scala/weaver/pure/Suite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ trait Suite extends EffectSuite[IO] with BaseCatsSuite with Expectations.Helpers
override implicit protected def effectCompat: EffectCompat[IO] = CatsUnsafeRun

override def getSuite: EffectSuite[IO] = this
}
}
16 changes: 11 additions & 5 deletions src/main/scala/weaver/pure/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@ import cats.effect.IO
import fs2.Stream

package object pure extends Expectations.Helpers {

import util._

def test(name: String)(run: IO[Expectations])(implicit loc: SourceLocation): IO[Test] = {
def test(
name: String
)(run: IO[Expectations])(implicit loc: SourceLocation): IO[Test] = {
failureToExpectations(run)
.map(x => Test(name, x))
}

def pureTest(name: String)(run: => Expectations)(implicit loc: SourceLocation): Test = Test(name, run)
def pureTest(name: String)(run: => Expectations)(implicit
loc: SourceLocation
): Test = Test(name, run)

def parSuite(tests: List[IO[Test]]): Stream[IO, Test] = Stream.evals(tests.parTraverse(identity))
def parSuite(tests: List[IO[Test]]): Stream[IO, Test] =
Stream.evals(tests.parTraverse(identity))

def seqSuite(tests: List[IO[Test]]): Stream[IO, Test] = Stream.evals(tests.sequence)
def seqSuite(tests: List[IO[Test]]): Stream[IO, Test] =
Stream.evals(tests.sequence)
}
29 changes: 19 additions & 10 deletions src/main/scala/weaver/pure/traced/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ package object traced {

type TracedTest = ReaderT[IO, Span[IO], Test]

def tracedTest(name: String)(run: Span[IO] => IO[Expectations])(implicit loc: SourceLocation): TracedTest =
def tracedTest(name: String)(
run: Span[IO] => IO[Expectations]
)(implicit loc: SourceLocation): TracedTest =
ReaderT { parent =>
parent.span(name).use{ span =>
weaver.pure.test(name)(run(span))
parent.span(name).use { span =>
weaver.pure
.test(name)(run(span))
.flatTap { test =>
traceExpectationFailures(span, test)
}
Expand All @@ -28,18 +31,24 @@ package object traced {
_ => IO.unit
)

def tracedParSuite(name: String)(suite: List[TracedTest])(implicit rootSpan: Span[IO]): Stream[IO,Test] =
def tracedParSuite(name: String)(suite: List[TracedTest])(implicit
rootSpan: Span[IO]
): Stream[IO, Test] =
tracedSuite(weaver.pure.parSuite)(name)(suite)(rootSpan)

def tracedSeqSuite(name: String)(suite: List[TracedTest])(implicit rootSpan: Span[IO]): Stream[IO,Test] =

def tracedSeqSuite(name: String)(suite: List[TracedTest])(implicit
rootSpan: Span[IO]
): Stream[IO, Test] =
tracedSuite(weaver.pure.seqSuite)(name)(suite)(rootSpan)

def tracedSuite(toStream: List[IO[Test]] => Stream[IO, Test])(name: String)(suite: List[TracedTest]): Span[IO] => Stream[IO,Test] =
parent =>

def tracedSuite(
toStream: List[IO[Test]] => Stream[IO, Test]
)(name: String)(suite: List[TracedTest]): Span[IO] => Stream[IO, Test] =
parent =>
Stream.resource(parent.span(name)).flatMap { suiteSpan =>
val testsWithSpan = suite.map(_.run(suiteSpan))
toStream(testsWithSpan)

}

}
11 changes: 7 additions & 4 deletions src/main/scala/weaver/pure/util.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@ import weaver.{Test => WeaverTest, Expectations, SourceLocation, TestOutcome}

import cats.effect.IO

private [pure] object util {
def failureToExpectations(x: IO[Expectations])(implicit loc: SourceLocation): IO[Expectations] = {
private[pure] object util {
def failureToExpectations(
x: IO[Expectations]
)(implicit loc: SourceLocation): IO[Expectations] = {
x.handleErrorWith { t =>
IO.delay(t.printStackTrace()).map { _ =>
failure(t.toString())
}
}
}

def toTestOutcome(test: Test): TestOutcome = WeaverTest.pure(test.name.name)(() => test.run)
def toTestOutcome(test: Test): TestOutcome =
WeaverTest.pure(test.name.name)(() => test.run)

def outcomeToString(x: TestOutcome): String = x.formatted(TestOutcome.Verbose)

}
37 changes: 18 additions & 19 deletions src/test/scala/com/dimitarg/example/ExampleResSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,39 @@ import weaver.pure._

object ExampleResSuite extends Suite {

// shared resource
// shared resource
final case class TextFile(lines: List[String])

// describe how to acquire shared resource
val sharedResource: Resource[IO, TextFile] = for {
_ <- Resource.make(
IO(ExecutionContext.fromExecutorService(Executors.newCachedThreadPool()))
)( x =>
IO(x.shutdown)
)
IO(ExecutionContext.fromExecutorService(Executors.newCachedThreadPool()))
)(x => IO(x.shutdown))
xs = fs2.io.readInputStream(
IO(getClass().getResourceAsStream("/foo.txt")),
1024, closeAfterUse = true
)
IO(getClass().getResourceAsStream("/foo.txt")),
1024,
closeAfterUse = true
)
lines <- Resource.eval(
xs.through(fs2.text.utf8.decode).through(fs2.text.lines).compile.toList
xs.through(fs2.text.utf8.decode).through(fs2.text.lines).compile.toList
)
} yield TextFile(lines)


// suite which uses shared resource
val suites: TextFile => Stream[IO, Test] = textFile => Stream(
pureTest("the file has one line") {
expect(textFile.lines.size == 1)
},
pureTest("the file has the expected content") {
expect(textFile.lines == List("Hello, there!"))
}
)
val suites: TextFile => Stream[IO, Test] = textFile =>
Stream(
pureTest("the file has one line") {
expect(textFile.lines.size == 1)
},
pureTest("the file has the expected content") {
expect(textFile.lines == List("Hello, there!"))
}
)

// construct `suitesStream` by acquiring resource and passing that to your `suite` via `flatMap`
override def suitesStream: Stream[IO, Test] =
Stream.resource(sharedResource).flatMap { res =>
suites(res)
}

}
38 changes: 21 additions & 17 deletions src/test/scala/com/dimitarg/example/ExampleSharedResSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,43 @@ final case class SharedResource(foo: FooResource, bar: BarResource)

object FooSuite {

val all: FooResource => Stream[IO, Test] = foo => Stream(
pureTest("the foo foos") {
val all: FooResource => Stream[IO, Test] = foo =>
Stream(
pureTest("the foo foos") {
expect(foo == FooResource())
}
)
}
)
}

object BarSuite {
val all: BarResource => Stream[IO, Test] = bar => Stream(
pureTest("a barsuite test") {
expect(bar.value == 42)
}
)
val all: BarResource => Stream[IO, Test] = bar =>
Stream(
pureTest("a barsuite test") {
expect(bar.value == 42)
}
)
}

object ExampleSharedResSuite extends Suite {

val mkSharedResource: Resource[IO, SharedResource] = for {
_ <- Resource.eval(IO.pure(println("acquiring shared resource")))
res <- Resource.eval(IO.pure(
SharedResource(FooResource(), BarResource(42))
))
res <- Resource.eval(
IO.pure(
SharedResource(FooResource(), BarResource(42))
)
)
} yield res

val suiteUsingAllResources: SharedResource => Stream[IO, Test] = res => Stream(
pureTest("some test"){
val suiteUsingAllResources: SharedResource => Stream[IO, Test] = res =>
Stream(pureTest("some test") {
expect(res.bar.value == 42)
})
})

override def suitesStream: Stream[IO, Test] =
Stream.resource(mkSharedResource).flatMap { r =>
suiteUsingAllResources(r) ++
FooSuite.all(r.foo) ++
BarSuite.all(r.bar)
FooSuite.all(r.foo) ++
BarSuite.all(r.bar)
}
}
2 changes: 1 addition & 1 deletion src/test/scala/com/dimitarg/example/ExampleSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object ExampleSuite extends Suite {

override def suitesStream: Stream[IO, Test] = Stream(
pureTest("a pure test") {
val x = 1
val x = 1
expect(x == 1)
},
pureTest("another pure test") {
Expand Down
Loading