module Effectful.Zoo.Hedgehog.Api.Assert
  ( assert,
    (===),
    (/==),
    onNothingFail,
    onNothingFailM,
    onLeftFail,
    onLeftFailM,
  ) where

import Effectful
import Effectful.Dispatch.Dynamic
import Effectful.Zoo.Core
import Effectful.Zoo.Hedgehog.Api.Failure
import Effectful.Zoo.Hedgehog.Dynamic
import HaskellWorks.Prelude
import Hedgehog qualified as H

infix 4 ===, /==

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

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

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

onNothingFail :: forall a r. ()
  => HasCallStack
  => r <: Hedgehog
  => Maybe a
  -> Eff r a
onNothingFail :: forall a (r :: [Effect]).
(HasCallStack, r <: Hedgehog) =>
Maybe a -> Eff r a
onNothingFail Maybe a
mv =
  (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
$
    case Maybe a
mv of
      Just a
a -> a -> Eff r a
forall a. a -> Eff r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a
      Maybe a
Nothing -> Maybe Diff -> String -> Eff r a
forall a (r :: [Effect]).
(HasCallStack, r <: Hedgehog) =>
Maybe Diff -> String -> Eff r a
failWith Maybe Diff
forall a. Maybe a
Nothing String
"Expected Just, but got Nothing"

onNothingFailM :: forall a r. ()
  => HasCallStack
  => r <: Hedgehog
  => Eff r (Maybe a)
  -> Eff r a
onNothingFailM :: forall a (r :: [Effect]).
(HasCallStack, r <: Hedgehog) =>
Eff r (Maybe a) -> Eff r a
onNothingFailM Eff r (Maybe a)
f =
  (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
$
    Eff r (Maybe a)
f Eff r (Maybe a) -> (Maybe a -> Eff r a) -> Eff r a
forall a b. Eff r a -> (a -> Eff r b) -> Eff r b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe a -> Eff r a
forall a (r :: [Effect]).
(HasCallStack, r <: Hedgehog) =>
Maybe a -> Eff r a
onNothingFail

onLeftFail :: forall e a r. ()
  => HasCallStack
  => Show e
  => r <: Hedgehog
  => Either e a
  -> Eff r a
onLeftFail :: forall e a (r :: [Effect]).
(HasCallStack, Show e, r <: Hedgehog) =>
Either e a -> Eff r a
onLeftFail Either e a
ea =
  (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
$
    case Either e a
ea of
      Right a
a -> a -> Eff r a
forall a. a -> Eff r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a
      Left e
e -> Maybe Diff -> String -> Eff r a
forall a (r :: [Effect]).
(HasCallStack, r <: Hedgehog) =>
Maybe Diff -> String -> Eff r a
failWith Maybe Diff
forall a. Maybe a
Nothing (String -> Eff r a) -> String -> Eff r a
forall a b. (a -> b) -> a -> b
$ String
"Expected Just, but got Left: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> e -> String
forall a. Show a => a -> String
show e
e

onLeftFailM :: forall e a r. ()
  => HasCallStack
  => Show e
  => r <: Hedgehog
  => Eff r (Either e a)
  -> Eff r a
onLeftFailM :: forall e a (r :: [Effect]).
(HasCallStack, Show e, r <: Hedgehog) =>
Eff r (Either e a) -> Eff r a
onLeftFailM Eff r (Either e a)
f =
  (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
$
    Eff r (Either e a)
f Eff r (Either e a) -> (Either e a -> Eff r a) -> Eff r a
forall a b. Eff r a -> (a -> Eff r b) -> Eff r b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Either e a -> Eff r a
forall e a (r :: [Effect]).
(HasCallStack, Show e, r <: Hedgehog) =>
Either e a -> Eff r a
onLeftFail