{-# LANGUAGE RankNTypes #-}

module Heck where

import qualified Control.Monad as Monad
import qualified GHC.Stack as Stack

data Test m n = MkTest
  { forall (m :: * -> *) (n :: * -> *).
Test m n -> forall x. HasCallStack => String -> m x
assertFailure :: forall x. (Stack.HasCallStack) => String -> m x,
    forall (m :: * -> *) (n :: * -> *).
Test m n -> String -> n () -> n ()
describe :: String -> n () -> n (),
    forall (m :: * -> *) (n :: * -> *).
Test m n -> String -> m () -> n ()
it :: String -> m () -> n ()
  }

assertEq ::
  (Stack.HasCallStack, Applicative m, Eq a, Show a) =>
  Test m n ->
  -- | expected
  a ->
  -- | actual
  a ->
  m ()
assertEq :: forall (m :: * -> *) a (n :: * -> *).
(HasCallStack, Applicative m, Eq a, Show a) =>
Test m n -> a -> a -> m ()
assertEq Test m n
test a
expected a
actual =
  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
Monad.when (a
expected a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
actual)
    (m () -> m ()) -> (String -> m ()) -> String -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Test m n -> forall x. HasCallStack => String -> m x
forall (m :: * -> *) (n :: * -> *).
Test m n -> forall x. HasCallStack => String -> m x
assertFailure Test m n
test
    (String -> m ()) -> String -> m ()
forall a b. (a -> b) -> a -> b
$ String
"expected " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> a -> String
forall a. Show a => a -> String
show a
expected String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" but got " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> a -> String
forall a. Show a => a -> String
show a
actual