Skip to content

Commit

Permalink
Merge branch 'main' into generic-aspect
Browse files Browse the repository at this point in the history
  • Loading branch information
fwbrasil authored Nov 12, 2024
2 parents 91103e1 + c28bdcf commit a3220e0
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 23 deletions.
2 changes: 1 addition & 1 deletion kyo-core/shared/src/test/scala/kyo/ClockTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ class ClockTest extends Test:
yield
val elapsedWall = wallEnd - wallStart
val elapsedShifted = shiftedEnd - wallStart
assert(elapsedWall >= 4.millis && elapsedWall < 20.millis)
assert(elapsedWall >= 4.millis && elapsedWall < 40.millis)
assert(elapsedShifted > elapsedWall)
}

Expand Down
2 changes: 1 addition & 1 deletion kyo-data/shared/src/main/scala/kyo/Flat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ private object FlatMacro:
report.errorAndAbort(
s"Cannot prove ${code(t.show)} isn't nested. " +
s"This error can be reported an unsupported pending effect is passed to a method. " +
s"If that's not the case, provide an implicit evidence ${code(s"kyo.Flat[${print(t)}]")}."
s"If that's not the case, provide an implicit evidence ${code(s"kyo.Flat[${t.show}]")}."
)

check(t)
Expand Down
46 changes: 25 additions & 21 deletions kyo-data/shared/src/test/scala/kyo/FlatTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,36 +50,40 @@ class FlatTest extends Test:

"nok" - {

"pending type" in {
assertDoesNotCompile("implicitly[Flat[Int < Any]]")
assertDoesNotCompile("implicitly[Flat[Int < Options]]")
assertDoesNotCompile("implicitly[Flat[Int < Nothing]]")
"pending type" in pendingUntilFixed {
typeCheckFailure("implicitly[Flat[Int < Any]]")(_ => false)
typeCheckFailure("implicitly[Flat[Int < Options]]")(_ => false)
typeCheckFailure("implicitly[Flat[Int < Nothing]]")(_ => false)
()
}

"nested" in {
assertDoesNotCompile("implicitly[Flat[Int < IOs < IOs]]")
assertDoesNotCompile("implicitly[Flat[Any < IOs < IOs]]")
"nested" in pendingUntilFixed {
typeCheckFailure("implicitly[Flat[Int < IOs < IOs]]")(_ => false)
typeCheckFailure("implicitly[Flat[Any < IOs < IOs]]")(_ => false)
()
}

"nested w/ mismatch" in {
assertDoesNotCompile("implicitly[Flat[Int < Options < IOs]]")
assertDoesNotCompile("implicitly[Flat[Int < IOs < Options]]")
"nested w/ mismatch" in pendingUntilFixed {
typeCheckFailure("implicitly[Flat[Int < Options < IOs]]")(_ => false)
typeCheckFailure("implicitly[Flat[Int < IOs < Options]]")(_ => false)
()
}

"generic" in {
def test1[A] =
assertDoesNotCompile("implicitly[Flat[A]]")
assertDoesNotCompile("implicitly[Flat[A | Int]]")
assertDoesNotCompile("implicitly[Flat[A < Options]]")
assertDoesNotCompile("implicitly[Flat[A < Any]]")
end test1
test1[Int]
succeed
typeCheckFailure("def f[A] = implicitly[Flat[A]]")(_.contains("No given instance of type kyo.Flat[A]"))
typeCheckFailure("def f[A] = implicitly[Flat[A | Int]]")(_.contains("No given instance of type kyo.Flat[A | Int]"))
}

"generic pending" in pendingUntilFixed {
typeCheckFailure("def f[A] = implicitly[Flat[A < Options]]")(_ => false)
typeCheckFailure("def f[A] = implicitly[Flat[A < Any]]")(_ => false)
()
}

"any" in {
assertDoesNotCompile("implicitly[Flat[Any]]")
assertDoesNotCompile("implicitly[Flat[Any < IOs]]")
"any" in pendingUntilFixed {
typeCheckFailure("implicitly[Flat[Any]]")(_.contains("No given instance of type kyo.Flat[Any]"))
typeCheckFailure("implicitly[Flat[Any < IOs]]")(_ => false)
()
}
}

Expand Down
18 changes: 18 additions & 0 deletions kyo-data/shared/src/test/scala/kyo/Test.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
package kyo

import org.scalatest.Assertion
import org.scalatest.NonImplicitAssertions
import org.scalatest.freespec.AsyncFreeSpec
import scala.compiletime.testing.Error
import scala.compiletime.testing.typeCheckErrors
import scala.util.Try

abstract class Test extends AsyncFreeSpec with NonImplicitAssertions:
given tryCanEqual[A]: CanEqual[Try[A], Try[A]] = CanEqual.derived
given eitherCanEqual[A, B]: CanEqual[Either[A, B], Either[A, B]] = CanEqual.derived
given throwableCanEqual: CanEqual[Throwable, Throwable] = CanEqual.derived

inline def typeCheck(inline code: String): Result[String, Unit] =
try
val errors = typeCheckErrors(code)
if errors.isEmpty then Result.unit else Result.fail(errors.iterator.map(_.message).mkString("\n"))
catch
case cause: Throwable =>
Result.panic(new RuntimeException("Compilation failed", cause))
end typeCheck

inline def typeCheckFailure(inline code: String)(inline predicate: String => Boolean): Assertion =
typeCheck(code) match
case Result.Fail(errors) => if predicate(errors) then succeed else fail(s"Predicate not satisfied by $errors")
case Result.Panic(exception) => fail(exception.getMessage)
case Result.Success(_) => fail("Code type-checked successfully, expected a failure")
end Test

0 comments on commit a3220e0

Please sign in to comment.