[distage] Instance not available when running test
loathwine opened this issue · comments
I'm upgrading to distage 1.0.0
and managed to get my wiring test to succeed. However, when I try to run my distage tests I get the following error:
izumi.distage.model.exceptions.ProvisioningException: Provisioner failed on 0 of 9 required operations, just 1 succeeded:
- Unsatisfied preconditions:
[!] Instance is not available in the object graph: {type.izumi.functional.bio.ApplicativeError3[=λ %1,%2,%3 → ZIO[-{Has[=package::System::Service] & Has[=package::Clock::Service] & Has[=package::Random::Service] & Has[=package::Blocking::Service] & Has[=package::Console::Service]},+2,+3]]}.
Required by refs: ø
Here is a complete simplified test with the same error
import cats.Parallel
import cats.effect.{Async, ContextShift}
import distage.plugins.{PluginConfig, PluginDef}
import izumi.distage.model.definition.ModuleDef
import izumi.distage.model.effect.{QuasiAsync, QuasiIO, QuasiIORunner}
import izumi.distage.testkit.TestConfig
import izumi.distage.testkit.scalatest.Spec2
import izumi.functional.bio.Error2
import zio.interop.catz._
import zio.{Task, ZEnv, ZIO}
object MyZIOPlugin extends PluginDef {
addImplicit[QuasiIO[ZIO[ZEnv, Throwable, +*]]]
addImplicit[QuasiAsync[ZIO[ZEnv, Throwable, +*]]]
make[QuasiIORunner[ZIO[ZEnv, Throwable, +*]]].from { iorunner: QuasiIORunner[Task] =>
new QuasiIORunner[ZIO[ZEnv, Throwable, +*]] {
override def run[A](f: => ZIO[ZEnv, Throwable, A]): A =
iorunner.run(f.provideLayer(ZEnv.live))
}
}
addImplicit[Error2[ZIO[ZEnv, +*, +*]]]
}
class MyTest extends Spec2[ZIO[ZEnv, +*, +*]] {
trait MyComponent {
def doSomething: Task[Unit]
}
object MyComponent {
final class Impl(
implicit cs: ContextShift[Task],
async: Async[Task],
parallel: Parallel[Task],
) extends MyComponent {
override def doSomething: Task[Unit] = Task.unit
}
}
override def config: TestConfig = TestConfig(
pluginConfig = PluginConfig.const(MyZIOPlugin),
moduleOverrides = new ModuleDef {
make[MyComponent].from[MyComponent.Impl]
},
configBaseName = "my-test",
)
"My component" should {
"do something" in { comp: MyComponent => comp.doSomething }
}
}
I noticed that you completely removed ZIOPlugin
in your example. However, I had a bit more in mine and haven't been able to remove it all yet.
I'm not a type-level expert but I thought that addImplicit[Error2[ZIO[ZEnv, +*, +*]]]
would add the ApplicativeError3
instance from the error message.
Any help is appreciated!
I'm not a type-level expert but I thought that addImplicit[Error2[ZIO[ZEnv, +, +]]] would add the ApplicativeError3 instance from the error message.
Try also adding addImplicit[ApplicativeError2[ZIO[ZEnv, +*, +*]]]
. Error2
is a subtype of ApplicativeError2
, but distage does not search for subtypes/supertypes, only for exact types. (unlike e.g. Guice)
Also try using .addHas
for your previous issue, I think in the long run it may be much easier to not use ZEnv
as a global effect type, but use Task and .fromHas
/.addHas
to fulfill ZEnv and any other environment dependencies for components that require them.
@Edvin-san
Seems like adding ApplicativeError2[ZIO[ZEnv, +*, +*]]
fixed this particular issue, see fixed Scastie: https://scastie.scala-lang.org/6Ra4TQzdRSiMRUInsP6fdw
@neko-kai Awesome, thanks! I will try to eliminate ZEnv
as a global effect type.