-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1283 from Grryum/zio2-withrun-instance-fix-with-test
Fix bug with zioTofuBiInstance, add tests for zio2-core module, add logging mid test with bug related function for zio2 logging.
- Loading branch information
Showing
9 changed files
with
213 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 5 additions & 7 deletions
12
modules/interop/zio2/core/src/main/scala/tofu/zioFunctions.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,13 @@ | ||
package tofu | ||
|
||
import izumi.reflect.Tag | ||
import tofu.higherKind.bi.{EmbedBK, FunctorBK} | ||
import tofu.syntax.functorbk._ | ||
import tofu.zioInstances.implicits._ | ||
import zio.{IO, ZIO, Tag => ZTag} | ||
|
||
import scala.annotation.nowarn | ||
import zio.{IO, Tag, ZIO} | ||
|
||
object zioFunctions { | ||
@nowarn | ||
def expose[U[_[_, _]]: EmbedBK: FunctorBK: Tag.auto.T]: U[ZIO[U[IO], +_, +_]] = | ||
EmbedBK.of[ZIO[U[IO], +_, +_], U](ZIO.environmentWith(_.get[U[IO]](ZTag[U[IO]]).widenb)) | ||
|
||
def expose[U[bf[_, _]]: EmbedBK: FunctorBK](implicit ev: Tag[U[IO]]): U[ZIO[U[IO], +_, +_]] = | ||
EmbedBK.of[ZIO[U[IO], +_, +_], U](ZIO.environmentWith(_.get[U[IO]].widenb)) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
modules/interop/zio2/core/src/test/scala/tofu/zioInstances/RunZioSpec.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package tofu.zioInstances | ||
|
||
import tofu.WithRun | ||
import tofu.zioInstances.implicits._ | ||
import zio._ | ||
import zio.test._ | ||
import tofu.bi.BiRun | ||
|
||
object RunZioSpec extends ZIOSpecDefault { | ||
case class Context(x: Int) | ||
private val app: RIO[Context, Int] = ZIO.serviceWith[Context](_.x) | ||
private val someResult = 111 | ||
|
||
override def spec = | ||
suite("RunZioSpec")( | ||
test("should summon and run WithRun instance without errors") { | ||
for { | ||
result <- WithRun[RIO[Context, _], Task, Context].runContext(app)(Context(someResult)) | ||
} yield assertTrue(result == someResult) | ||
}, | ||
test("should summon and run BiRun instance without errors") { | ||
for { | ||
result <- BiRun[ZIO[Context, +_, +_], IO[+_, +_], Context, Context].runLeft(app)(Context(someResult)) | ||
} yield assertTrue(result == someResult) | ||
} | ||
) | ||
} |
137 changes: 137 additions & 0 deletions
137
modules/interop/zio2/logging/src/test/scala-2/tofu/logging/zlogs/ZLogBiMidSpec.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package tofu.logging | ||
package zlogs | ||
|
||
import derevo.derive | ||
import tofu.logging.derivation.{loggable, loggingBiMid} | ||
import zio._ | ||
import zio.URLayer | ||
import tofu.logging.bi.LoggingBiCompanion | ||
import tofu.higherKind.bi.BiTemplate | ||
import tofu.zioInstances.implicits._ | ||
import tofu.zioFunctions | ||
import zio.test.ZIOSpecDefault | ||
import zio.test._ | ||
import tofu.higherKind.bi.RepresentableB | ||
import tofu.higherKind | ||
import tofu.higherKind.bi.FunBK | ||
|
||
object ZLogBiMidSpec extends ZIOSpecDefault { | ||
import tofu.logging.zlogs.Lurker.Point | ||
val cls = s"<${classOf[Lurker[Any]].getName()}>" | ||
|
||
def go[E, A](z: ZIO[Lurker.Dep, E, A]): ZIO[Any, Nothing, (Either[E, A], Vector[String])] = | ||
(for { | ||
ref <- Ref.make(Vector[String]()) | ||
// TODO: remake to true ZIO style | ||
e <- z.provide(ZTestLog.layer, Lurker.attachLog, ZLayer.succeed(ref)).either | ||
logs <- ref.get | ||
} yield (e, logs)) | ||
|
||
override def spec = | ||
suite("ZLogBiMidSpec")( | ||
test("simple walk") { | ||
for { | ||
(res, logs) <- go(Lurker.DO.move(Point(20, 3))) | ||
} yield assertTrue( | ||
logs == Vector( | ||
s"[Debug] $cls entering move (target = Point{x=20,y=3})", | ||
s"[Debug] $cls leaving move (target = Point{x=20,y=3}) result is Point{x=5,y=3}", | ||
), | ||
res == Right(Point(5, 3)) | ||
) | ||
}, | ||
test("attack") { | ||
for { | ||
(res, logs) <- go(Lurker.DO.attack(Point(20, 3))) | ||
} yield assertTrue( | ||
res == Left(Lurker.Normal), | ||
logs == Vector( | ||
s"[Debug] $cls entering attack (target = Point{x=20,y=3})", | ||
s"[Error] $cls error during attack (target = Point{x=20,y=3}) error is cant do this operation in Normal state", | ||
) | ||
) | ||
}, | ||
test("burrow and attack") { | ||
for { | ||
(res, logs) <- go(Lurker.DO.burrowChange *> Lurker.DO.attack(Point(2, 3))) | ||
} yield assertTrue( | ||
res == Right(true), | ||
logs == Vector( | ||
s"[Debug] $cls entering burrowChange ()", | ||
s"[Debug] $cls leaving burrowChange () result is ()", | ||
s"[Debug] $cls entering attack (target = Point{x=2,y=3})", | ||
s"[Debug] $cls leaving attack (target = Point{x=2,y=3}) result is true", | ||
) | ||
) | ||
} | ||
) | ||
} | ||
|
||
@derive(loggingBiMid) | ||
trait Lurker[F[_, _]] extends BiTemplate[F] { | ||
import Lurker._ | ||
def move(target: Point): F[State, Point] | ||
def burrowChange: FS[Unit] | ||
def attack(target: Point): F[State, Boolean] | ||
} | ||
|
||
object Lurker extends LoggingBiCompanion[Lurker] { | ||
// TODO: use `@derive(representableB)` from derivation module when it is ready | ||
implicit def reprBInstance: RepresentableB[Lurker] = new RepresentableB[Lurker] { | ||
override def bitabulate[F[_, _]](repr: FunBK[higherKind.bi.RepBK[Lurker, _, _], F]): Lurker[F] = | ||
new Lurker[F] { | ||
def move(target: Point): F[State, Point] = | ||
repr(higherKind.bi.RepBK[Lurker](_.move(target))) | ||
def burrowChange: FS[Unit] = | ||
repr(higherKind.bi.RepBK[Lurker](_.burrowChange)) | ||
def attack(target: Point): F[State, Boolean] = | ||
repr(higherKind.bi.RepBK[Lurker](_.attack(target))) | ||
} | ||
} | ||
|
||
type Dep = Lurker[IO] | ||
|
||
sealed trait State | ||
case object Normal extends State | ||
case object Buried extends State | ||
implicit val wrongStateLoggable: Loggable[State] = | ||
Loggable[String].contramap(st => s"cant do this operation in $st state") | ||
|
||
lazy val DO: Lurker[ZIO[Dep, +_, +_]] = zioFunctions.expose[Lurker] | ||
|
||
@derive(loggable) | ||
final case class Point(x: Long, y: Long) | ||
|
||
class Test(ref: Ref.Synchronized[(State, Point)], maxDistance: Long = 5) extends Lurker[IO] { | ||
|
||
private def moveOne(cur: Long, target: Long) = { | ||
val shift = target - cur | ||
val dist = shift.abs.min(maxDistance) | ||
if (shift >= 0) cur + dist else cur - dist | ||
} | ||
def move(target: Point): IO[State, Point] = | ||
ref.modifyZIO { | ||
case (Normal, pt) => | ||
val res = Point(moveOne(pt.x, target.x), moveOne(pt.y, target.y)) | ||
ZIO.succeed((res, (Normal, res))) | ||
case (Buried, _) => ZIO.fail(Buried) | ||
} | ||
|
||
def burrowChange: IO[Nothing, Unit] = ref.update { | ||
case (Normal, pt) => (Buried, pt) | ||
case (Buried, pt) => (Normal, pt) | ||
} | ||
|
||
def attack(target: Point): IO[State, Boolean] = ref.get.flatMap { | ||
case (Normal, _) => | ||
ZIO.fail(Normal) | ||
case (Buried, pt) => | ||
ZIO.succeed((pt.x - target.x).abs < maxDistance && (pt.y - target.x).abs < maxDistance) | ||
} | ||
} | ||
|
||
val make: UIO[Lurker[IO]] = Ref.Synchronized.make((Normal: State, Point(0, 0))).map(new Test(_)) | ||
|
||
val attachLog: URLayer[ZLogging.Make, Dep] = | ||
ZLayer.fromZIO(ZIO.serviceWithZIO[ZLogging.Make](implicit logs => make.map(_.attachLogs))) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
modules/interop/zio2/logging/src/test/scala/tofu/logging/zlogs/ZTestLog.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package tofu.logging | ||
package zlogs | ||
|
||
import zio._ | ||
import org.slf4j.helpers.MessageFormatter | ||
|
||
class ZTestLog(svc: String, val ref: Ref[Vector[String]]) extends Logging[UIO] { | ||
override def write(level: Logging.Level, message: String, values: LoggedValue*): UIO[Unit] = { | ||
val formatted = MessageFormatter.arrayFormat(message, values.toArray).getMessage() | ||
ref.update(_ :+ s"[$level] <$svc> $formatted") | ||
} | ||
} | ||
|
||
object ZTestLog { | ||
def make(): URIO[Ref[Vector[String]], Logging.Make[UIO]] = | ||
ZIO.serviceWith[Ref[Vector[String]]](ref => (svc: String) => new ZTestLog(svc, ref)) | ||
|
||
val layer: URLayer[Ref[Vector[String]], ZLogging.Make] = | ||
ZLayer.fromZIO(make()) | ||
} |
28 changes: 13 additions & 15 deletions
28
modules/logging/derivation/src/main/scala-3/tofu/logging/derivation/package.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,21 @@ | ||
package tofu.logging | ||
package tofu.logging.derivation | ||
|
||
import magnolia1.TypeInfo | ||
import scala.collection.compat._ | ||
import scala.deriving.Mirror | ||
import tofu.logging.Loggable | ||
|
||
package object derivation { | ||
extension (x: Loggable.type) inline def derived[A](using Mirror.Of[A]): Loggable[A] = loggable.derived[A] | ||
|
||
extension (x: Loggable.type) inline def derived[A](using Mirror.Of[A]): Loggable[A] = loggable.derived[A] | ||
private[derivation] def strJoin(typeName: String, strings: IterableOnce[String]): String = | ||
if (strings.iterator.isEmpty) typeName else strings.iterator.mkString(s"$typeName{", ",", "}") | ||
|
||
private[derivation] def strJoin(typeName: String, strings: IterableOnce[String]): String = | ||
if (strings.iterator.isEmpty) typeName else strings.iterator.mkString(s"$typeName{", ",", "}") | ||
private[derivation] def calcTypeName(typeName: TypeInfo, seen: Set[TypeInfo] = Set()): String = | ||
if (seen(typeName)) "#" | ||
else { | ||
val args = typeName.typeParams | ||
val name = typeName.full | ||
|
||
private[derivation] def calcTypeName(typeName: TypeInfo, seen: Set[TypeInfo] = Set()): String = | ||
if (seen(typeName)) "#" | ||
else { | ||
val args = typeName.typeParams | ||
val name = typeName.full | ||
|
||
if (args.isEmpty) name | ||
else args.iterator.map(calcTypeName(_, seen + typeName)).mkString(name + "[", ",", "]") | ||
} | ||
} | ||
if (args.isEmpty) name | ||
else args.iterator.map(calcTypeName(_, seen + typeName)).mkString(name + "[", ",", "]") | ||
} |