{-# LANGUAGE LambdaCase #-}
module Convex.MockChain.Utils(
  mockchainSucceeds,
  mockchainSucceedsWith,
  mockchainFails,
  mockchainFailsWith
  ) where

import           Convex.MockChain          (MockchainError, MockchainIO,
                                            runMockchain0IOWith)
import qualified Convex.MockChain.Defaults as Defaults
import           Convex.NodeParams         (NodeParams)
import qualified Convex.Wallet.MockWallet  as Wallet
import           Test.HUnit                (Assertion)

{-| Run the 'Mockchain' action and fail if there is an error
-}
mockchainSucceeds :: MockchainIO a -> Assertion
mockchainSucceeds :: forall a. MockchainIO a -> Assertion
mockchainSucceeds = forall a. NodeParams -> MockchainIO a -> Assertion
mockchainSucceedsWith NodeParams
Defaults.nodeParams

{-| Run the 'Mockchain' action with the given node parameters and fail if there is an error
-}
mockchainSucceedsWith :: NodeParams -> MockchainIO a -> Assertion
mockchainSucceedsWith :: forall a. NodeParams -> MockchainIO a -> Assertion
mockchainSucceedsWith NodeParams
params MockchainIO a
action =
   forall a.
InitialUTXOs
-> NodeParams
-> MockchainIO a
-> IO (Either MockchainError (a, MockChainState))
runMockchain0IOWith InitialUTXOs
Wallet.initialUTxOs NodeParams
params MockchainIO a
action forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Right{}  -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    Left MockchainError
err -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail (forall a. Show a => a -> String
show MockchainError
err)

{-| Run the 'Mockchain' action, fail if it succeeds, and handle the error
  appropriately.
-}
mockchainFails :: MockchainIO a -> (MockchainError -> Assertion) -> Assertion
mockchainFails :: forall a.
MockchainIO a -> (MockchainError -> Assertion) -> Assertion
mockchainFails MockchainIO a
action =
  forall a.
NodeParams
-> MockchainIO a -> (MockchainError -> Assertion) -> Assertion
mockchainFailsWith NodeParams
Defaults.nodeParams MockchainIO a
action

{-| Run the 'Mockchain' action with the given node parameters, fail if it
    succeeds, and handle the error appropriately.
-}
mockchainFailsWith :: NodeParams -> MockchainIO a -> (MockchainError -> Assertion) -> Assertion
mockchainFailsWith :: forall a.
NodeParams
-> MockchainIO a -> (MockchainError -> Assertion) -> Assertion
mockchainFailsWith NodeParams
params MockchainIO a
action MockchainError -> Assertion
handleError =
  forall a.
InitialUTXOs
-> NodeParams
-> MockchainIO a
-> IO (Either MockchainError (a, MockChainState))
runMockchain0IOWith InitialUTXOs
Wallet.initialUTxOs NodeParams
params MockchainIO a
action forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Right (a, MockChainState)
_  -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"mockchainFailsWith: Did not fail")
    Left MockchainError
err -> MockchainError -> Assertion
handleError MockchainError
err