module Effectful.Zoo.Hedgehog.Api.Failure
  ( failure,
    failException,
    failWith,
    failWithCallStack,

    catchAssertion,
    throwAssertion,
  ) where

import Effectful
import Effectful.Dispatch.Dynamic
import Effectful.Error.Static
import Effectful.Zoo.Core
import Effectful.Zoo.Hedgehog.Dynamic
import HaskellWorks.Prelude
import Hedgehog.Internal.Property qualified as H
import Hedgehog.Internal.Source qualified as H

failure :: forall a r. ()
  => HasCallStack
  => r <: Hedgehog
  => Eff r a
failure :: forall a (r :: [Effect]). (HasCallStack, r <: Hedgehog) => Eff r a
failure =
  (HasCallStack => Eff r a) -> Eff r a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack
    Eff r a
HasCallStack => Eff r a
forall (m :: * -> *) a. (MonadTest m, HasCallStack) => m a
H.failure

failException :: forall a r. ()
  => HasCallStack
  => r <: Hedgehog
  => SomeException
  -> Eff r a
failException :: forall a (r :: [Effect]).
(HasCallStack, r <: Hedgehog) =>
SomeException -> Eff r a
failException SomeException
e =
  (HasCallStack => Eff r a) -> Eff r a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => Eff r a) -> Eff r a)
-> (HasCallStack => Eff r a) -> Eff r a
forall a b. (a -> b) -> a -> b
$
    SomeException -> Eff r a
forall (m :: * -> *) a.
(MonadTest m, HasCallStack) =>
SomeException -> m a
H.failException SomeException
e

failWith :: forall a r. ()
  => HasCallStack
  => r <: Hedgehog
  => Maybe H.Diff
  -> String
  -> Eff r a
failWith :: forall a (r :: [Effect]).
(HasCallStack, r <: Hedgehog) =>
Maybe Diff -> String -> Eff r a
failWith Maybe Diff
diff String
msg =
  (HasCallStack => Eff r a) -> Eff r a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => Eff r a) -> Eff r a)
-> (HasCallStack => Eff r a) -> Eff r a
forall a b. (a -> b) -> a -> b
$
    Maybe Diff -> String -> Eff r a
forall (m :: * -> *) a.
(MonadTest m, HasCallStack) =>
Maybe Diff -> String -> m a
H.failWith Maybe Diff
diff String
msg

failWithCallStack :: forall a r. ()
  => r <: Hedgehog
  => CallStack
  -> Maybe H.Diff
  -> String
  -> Eff r a
failWithCallStack :: forall a (r :: [Effect]).
(r <: Hedgehog) =>
CallStack -> Maybe Diff -> String -> Eff r a
failWithCallStack CallStack
cs Maybe Diff
diff String
msg =
  (HasCallStack => Eff r a) -> Eff r a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => Eff r a) -> Eff r a)
-> (HasCallStack => Eff r a) -> Eff r a
forall a b. (a -> b) -> a -> b
$
    Failure -> Eff r a
forall a (r :: [Effect]).
(HasCallStack, r <: Hedgehog) =>
Failure -> Eff r a
throwAssertion (Maybe Span -> String -> Maybe Diff -> Failure
H.Failure (CallStack -> Maybe Span
H.getCaller CallStack
cs) String
msg Maybe Diff
diff)

catchAssertion :: forall a r. ()
  => HasCallStack
  => r <: Hedgehog
  => Eff r a 
  -> (H.Failure -> Eff r a) 
  -> Eff r a
catchAssertion :: forall a (r :: [Effect]).
(HasCallStack, r <: Hedgehog) =>
Eff r a -> (Failure -> Eff r a) -> Eff r a
catchAssertion Eff r a
m Failure -> Eff r a
h =
  (HasCallStack => Eff r a) -> Eff r a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => Eff r a) -> Eff r a)
-> (HasCallStack => Eff r a) -> Eff r a
forall a b. (a -> b) -> a -> b
$
    Hedgehog (Eff r) a -> Eff r a
forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (Hedgehog (Eff r) a -> Eff r a) -> Hedgehog (Eff r) a -> Eff r a
forall a b. (a -> b) -> a -> b
$ Eff r a -> (Failure -> Eff r a) -> Hedgehog (Eff r) a
forall (a :: * -> *) b.
HasCallStack =>
a b -> (Failure -> a b) -> Hedgehog a b
CatchAssertion Eff r a
m Failure -> Eff r a
h

throwAssertion :: forall a r. ()
  => HasCallStack
  => r <: Hedgehog
  => H.Failure
  -> Eff r a
throwAssertion :: forall a (r :: [Effect]).
(HasCallStack, r <: Hedgehog) =>
Failure -> Eff r a
throwAssertion Failure
e =
  (HasCallStack => Eff r a) -> Eff r a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => Eff r a) -> Eff r a)
-> (HasCallStack => Eff r a) -> Eff r a
forall a b. (a -> b) -> a -> b
$
    Hedgehog (Eff r) a -> Eff r a
forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (Hedgehog (Eff r) a -> Eff r a) -> Hedgehog (Eff r) a -> Eff r a
forall a b. (a -> b) -> a -> b
$ Failure -> Hedgehog (Eff r) a
forall (a :: * -> *) b. HasCallStack => Failure -> Hedgehog a b
ThrowAssertion Failure
e