Repository: 7mind/izumi
Pull request #1171 (2020-08-05 19:32:01)

Update to ZIO 1.0, ZIO cats interop 2.1.4.0


Patch:
diff --git a/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/impl/BIOAsyncZio.scala b/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/impl/BIOAsyncZio.scala
index 46b4371f5..5c114ab3f 100644
--- a/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/impl/BIOAsyncZio.scala
+++ b/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/impl/BIOAsyncZio.scala
@@ -69,8 +69,8 @@ class BIOAsyncZio extends BIOAsync3[ZIO] with BIOLocal[ZIO] {
     f.onExit(cleanup apply ZIOExit.toBIOExit(_))
   }
 
-  @inline override final def traverse[R, E, A, B](l: Iterable[A])(f: A => ZIO[R, E, B]): ZIO[R, E, List[B]] = ZIO.foreach(l)(f)
-  @inline override final def sequence[R, E, A, B](l: Iterable[ZIO[R, E, A]]): ZIO[R, E, List[A]] = ZIO.collectAll(l)
+  @inline override final def traverse[R, E, A, B](l: Iterable[A])(f: A => ZIO[R, E, B]): ZIO[R, E, List[B]] = ZIO.foreach(l.toList)(f)
+  @inline override final def sequence[R, E, A, B](l: Iterable[ZIO[R, E, A]]): ZIO[R, E, List[A]] = ZIO.collectAll(l.toList)
   @inline override final def traverse_[R, E, A](l: Iterable[A])(f: A => ZIO[R, E, Unit]): ZIO[R, E, Unit] = ZIO.foreach_(l)(f)
   @inline override final def sequence_[R, E](l: Iterable[ZIO[R, E, Unit]]): ZIO[R, E, Unit] = ZIO.foreach_(l)(identity)
 
@@ -118,10 +118,10 @@ class BIOAsyncZio extends BIOAsync3[ZIO] with BIOLocal[ZIO] {
   @inline override final def uninterruptible[R, E, A](r: ZIO[R, E, A]): ZIO[R, E, A] = r.uninterruptible
 
   @inline override final def parTraverseN[R, E, A, B](maxConcurrent: Int)(l: Iterable[A])(f: A => ZIO[R, E, B]): ZIO[R, E, List[B]] =
-    ZIO.foreachParN(maxConcurrent)(l)(f(_).interruptible)
+    ZIO.foreachParN(maxConcurrent)(l.toList)(f(_).interruptible)
   @inline override final def parTraverseN_[R, E, A, B](maxConcurrent: Int)(l: Iterable[A])(f: A => ZIO[R, E, B]): ZIO[R, E, Unit] =
     ZIO.foreachParN_(maxConcurrent)(l)(f(_).interruptible)
-  @inline override final def parTraverse[R, E, A, B](l: Iterable[A])(f: A => ZIO[R, E, B]): ZIO[R, E, List[B]] = ZIO.foreachPar(l)(f(_).interruptible)
+  @inline override final def parTraverse[R, E, A, B](l: Iterable[A])(f: A => ZIO[R, E, B]): ZIO[R, E, List[B]] = ZIO.foreachPar(l.toList)(f(_).interruptible)
   @inline override final def parTraverse_[R, E, A, B](l: Iterable[A])(f: A => ZIO[R, E, B]): ZIO[R, E, Unit] = ZIO.foreachPar_(l)(f(_).interruptible)
 
   @inline override final def zipWithPar[R, E, A, B, C](fa: ZIO[R, E, A], fb: ZIO[R, E, B])(f: (A, B) => C): ZIO[R, E, C] = fa.zipWithPar(fb)(f)
diff --git a/logstage/logstage-rendering-circe/src/main/scala/izumi/logstage/api/rendering/json/LogstageCirceRenderingPolicy.scala b/logstage/logstage-rendering-circe/src/main/scala/izumi/logstage/api/rendering/json/LogstageCirceRenderingPolicy.scala
index 8dec2e1e9..674db3f61 100644
--- a/logstage/logstage-rendering-circe/src/main/scala/izumi/logstage/api/rendering/json/LogstageCirceRenderingPolicy.scala
+++ b/logstage/logstage-rendering-circe/src/main/scala/izumi/logstage/api/rendering/json/LogstageCirceRenderingPolicy.scala
@@ -17,6 +17,11 @@ class LogstageCirceRenderingPolicy(
 
   import LogstageCirceRenderingPolicy._
 
+  protected def EventKey = "event"
+  protected def ContextKey = "context"
+  protected def MetaKey = "meta"
+  protected def TextKey = "text"
+
   override def render(entry: Log.Entry): String = {
     val result = mutable.ArrayBuffer[(String, Json)]()
 
@@ -28,7 +33,7 @@ class LogstageCirceRenderingPolicy(
     )
 
     if (params.nonEmpty) {
-      result += "event" -> params.asJson
+      result += EventKey -> params.asJson
     }
 
     val ctx = parametersToJson[LogArg](
@@ -38,7 +43,7 @@ class LogstageCirceRenderingPolicy(
     )
 
     if (ctx.nonEmpty) {
-      result += "context" -> ctx.asJson
+      result += ContextKey -> ctx.asJson
     }
 
     result ++= makeEventEnvelope(entry, formatted)
@@ -78,8 +83,8 @@ class LogstageCirceRenderingPolicy(
     )
 
     val tail = Seq(
-      "meta" -> eventInfo,
-      "text" -> Json.fromFields(
+      MetaKey -> eventInfo,
+      TextKey -> Json.fromFields(
         Seq(
           "template" -> Json.fromString(formatted.template),
           "message" -> Json.fromString(formatted.message),
diff --git a/project/Versions.scala b/project/Versions.scala
index 2bebbb92d..487d9c1aa 100644
--- a/project/Versions.scala
+++ b/project/Versions.scala
@@ -13,8 +13,8 @@ object V {
 
   val cats = "2.1.1"
   val cats_effect = "2.1.4"
-  val zio = "1.0.0-RC21-2"
-  val zio_interop_cats = "2.1.3.0-RC16"
+  val zio = "1.0.0"
+  val zio_interop_cats = "2.1.4.0"
 
   val circe = "0.13.0"
   val circe_generic_extras = "0.13.0"


Test patch:
diff --git a/distage/distage-core/src/test/scala/izumi/distage/dsl/DSLTest.scala b/distage/distage-core/src/test/scala/izumi/distage/dsl/DSLTest.scala
index 5cf4c5519..aa42277cd 100644
--- a/distage/distage-core/src/test/scala/izumi/distage/dsl/DSLTest.scala
+++ b/distage/distage-core/src/test/scala/izumi/distage/dsl/DSLTest.scala
@@ -6,6 +6,7 @@ import izumi.distage.fixtures.BasicCases._
 import izumi.distage.fixtures.SetCases._
 import izumi.distage.injector.MkInjector
 import izumi.distage.model.definition.Binding.{SetElementBinding, SingletonBinding}
+import izumi.distage.model.definition.StandardAxis.{Env, Repo}
 import izumi.distage.model.definition.{Binding, BindingTag, Bindings, ImplDef, Module}
 import izumi.fundamentals.platform.functional.Identity
 import izumi.fundamentals.platform.language.SourceFilePosition
@@ -634,6 +635,19 @@ class DSLTest extends AnyWordSpec with MkInjector {
       assert(res2.getMessage contains "`trait DIResource`")
     }
 
+    "define multiple bindings with different axis but the same implementation" in {
+      class X
+
+      val module = new ModuleDef {
+        make[X].tagged(Repo.Prod, Env.Prod)
+        make[X].tagged(Repo.Dummy, Env.Prod)
+        make[X].tagged(Env.Test)
+      }
+      val bindings = (module ++ module).overridenBy(module).bindings
+      assert(bindings.size == 3)
+      assert(bindings.map(_.tags) == Set(Set[BindingTag](Repo.Prod, Env.Prod), Set[BindingTag](Repo.Dummy, Env.Prod), Set[BindingTag](Env.Test)))
+    }
+
   }
 
 }
diff --git a/distage/distage-core/src/test/scala/izumi/distage/injector/AxisTest.scala b/distage/distage-core/src/test/scala/izumi/distage/injector/AxisTest.scala
index e592293a5..d734a7dad 100644
--- a/distage/distage-core/src/test/scala/izumi/distage/injector/AxisTest.scala
+++ b/distage/distage-core/src/test/scala/izumi/distage/injector/AxisTest.scala
@@ -6,6 +6,7 @@ import izumi.distage.model.PlannerInput
 import izumi.distage.model.definition.StandardAxis.Repo
 import izumi.distage.model.definition.{Activation, BootstrapModuleDef, ModuleDef}
 import izumi.distage.model.plan.Roots
+import org.scalatest.exceptions.TestFailedException
 import org.scalatest.wordspec.AnyWordSpec
 
 class AxisTest extends AnyWordSpec with MkInjector {
@@ -60,12 +61,14 @@ class AxisTest extends AnyWordSpec with MkInjector {
       make[JustTrait].tagged(Repo.Dummy).from[Impl0]
     }
 
-    val context = Injector().produce(PlannerInput(definition, Activation(Repo -> Repo.Prod), Roots.Everything)).unsafeGet()
+    val context = Injector()
+      .produce(PlannerInput(definition, Activation(Repo -> Repo.Prod), Roots.Everything))
+      .unsafeGet()
 
     assert(context.find[JustTrait].isEmpty)
   }
 
-  "report conflict if there's both an implementation with no axis and the current choice" in {
+  "progression test: should report conflict if there's both an implementation with no axis and the current choice" in {
     import BasicCase1._
 
     val definition = new ModuleDef {
@@ -73,10 +76,18 @@ class AxisTest extends AnyWordSpec with MkInjector {
       make[JustTrait].tagged(Repo.Prod).from[Impl1]
     }
 
-    assert(Injector().produce(PlannerInput(definition, Activation(Repo -> Repo.Prod), Roots(DIKey.get[JustTrait]))).unsafeGet().get[JustTrait].isInstanceOf[Impl1])
+    assertThrows[TestFailedException] {
+      assertThrows[Throwable] {
+        val instance = Injector()
+          .produce(PlannerInput(definition, Activation(Repo -> Repo.Prod), Roots(DIKey.get[JustTrait])))
+          .unsafeGet()
+          .get[JustTrait]
+        assert(instance.isInstanceOf[Impl1]) // should fail to produce, not choose `Repo.Prod`
+      }
+    }
   }
 
-  "report conflict if there's both an implementation with no axis and the opposite choice" in {
+  "progression test: should report conflict if there's both an implementation with no axis and the opposite choice" in {
     import BasicCase1._
 
     val definition = new ModuleDef {
@@ -84,7 +95,15 @@ class AxisTest extends AnyWordSpec with MkInjector {
       make[JustTrait].tagged(Repo.Dummy).from[Impl1]
     }
 
-    assert(Injector().produce(PlannerInput(definition, Activation(Repo -> Repo.Prod), Roots(DIKey.get[JustTrait]))).unsafeGet().get[JustTrait].isInstanceOf[Impl0])
+    assertThrows[TestFailedException] {
+      assertThrows[Throwable] {
+        val instance = Injector()
+          .produce(PlannerInput(definition, Activation(Repo -> Repo.Prod), Roots(DIKey.get[JustTrait])))
+          .unsafeGet()
+          .get[JustTrait]
+        assert(instance.isInstanceOf[Impl0]) // should fail to produce, not choose untagged
+      }
+    }
   }
 
 }