    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE ScopedTypeVariables #-}

    module Hledger.Utils.Test (
       module Test.Tasty
      ,module Test.Tasty.HUnit
      -- ,module QC
      -- ,module SC
      ,assertLeft
      ,assertRight
      ,assertParse
      ,assertParseEq
      ,assertParseEqOn
      ,assertParseError
      ,assertParseE
      ,assertParseEqE
      ,assertParseErrorE
      ,assertParseStateOn
    )
    where

    import Control.Monad (unless)
    import Control.Monad.Except (ExceptT(..), liftEither, runExceptT, withExceptT)
    import Control.Monad.State.Strict (StateT, evalStateT, execStateT)
    import Data.Default (Default(..))
    import Data.List (isInfixOf)
    import qualified Data.Text as T
    import Test.Tasty hiding (defaultMain)
    import Test.Tasty.HUnit
    -- import Test.Tasty.QuickCheck as QC
    -- import Test.Tasty.SmallCheck as SC
    import Text.Megaparsec
    import Text.Megaparsec.Custom
      ( HledgerParseErrorData,
        FinalParseError,
        attachSource,
        customErrorBundlePretty,
        finalErrorBundlePretty,
      )

    import Hledger.Utils.IO (pshow)

    -- * tasty helpers

    -- TODO: pretty-print values in failure messages

    -- | Assert any Left value.
    assertLeft :: (HasCallStack, Eq b, Show b) => Either a b -> Assertion
    assertLeft :: forall b a. (HasCallStack, Eq b, Show b) => Either a b -> Assertion
    assertLeft (Left a
    _)  = () -> Assertion
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
    assertLeft (Right b
    b) = [Char] -> Assertion
    forall a. HasCallStack => [Char] -> IO a
    assertFailure ([Char] -> Assertion) -> [Char] -> Assertion
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "expected Left, got (Right " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ b -> [Char]
    forall a. Show a => a -> [Char]
    show b
    b [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ")"

    -- | Assert any Right value.
    assertRight :: (HasCallStack, Eq a, Show a) => Either a b -> Assertion
    assertRight :: forall a b. (HasCallStack, Eq a, Show a) => Either a b -> Assertion
    assertRight (Right b
    _) = () -> Assertion
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
    assertRight (Left a
    a)  = [Char] -> Assertion
    forall a. HasCallStack => [Char] -> IO a
    assertFailure ([Char] -> Assertion) -> [Char] -> Assertion
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "expected Right, got (Left " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ a -> [Char]
    forall a. Show a => a -> [Char]
    show a
    a [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ")"

    -- | Run a parser on the given text and display a helpful error.
    parseHelper :: (HasCallStack, Default st, Monad m) =>
      StateT st (ParsecT HledgerParseErrorData T.Text m) a -> T.Text -> ExceptT String m a
    parseHelper :: forall st (m :: * -> *) a.
    (HasCallStack, Default st, Monad m) =>
    StateT st (ParsecT HledgerParseErrorData Text m) a
    -> Text -> ExceptT [Char] m a
    parseHelper StateT st (ParsecT HledgerParseErrorData Text m) a
    parser Text
    input =
      (HledgerParseErrors -> [Char])
    -> ExceptT HledgerParseErrors m a -> ExceptT [Char] m a
    forall (m :: * -> *) e e' a.
    Functor m =>
    (e -> e') -> ExceptT e m a -> ExceptT e' m a
    withExceptT (\HledgerParseErrors
    e -> [Char]
    "\nparse error at " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ HledgerParseErrors -> [Char]
    customErrorBundlePretty HledgerParseErrors
    e [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "\n") (ExceptT HledgerParseErrors m a -> ExceptT [Char] m a)
    -> (m (Either HledgerParseErrors a)
        -> ExceptT HledgerParseErrors m a)
    -> m (Either HledgerParseErrors a)
    -> ExceptT [Char] m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . m (Either HledgerParseErrors a) -> ExceptT HledgerParseErrors m a
    forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT
      (m (Either HledgerParseErrors a) -> ExceptT [Char] m a)
    -> m (Either HledgerParseErrors a) -> ExceptT [Char] m a
    forall a b. (a -> b) -> a -> b
    $ ParsecT HledgerParseErrorData Text m a
    -> [Char] -> Text -> m (Either HledgerParseErrors a)
    forall (m :: * -> *) e s a.
    Monad m =>
    ParsecT e s m a
    -> [Char] -> s -> m (Either (ParseErrorBundle s e) a)
    runParserT (StateT st (ParsecT HledgerParseErrorData Text m) a
    -> st -> ParsecT HledgerParseErrorData Text m a
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
    evalStateT (StateT st (ParsecT HledgerParseErrorData Text m) a
    parser StateT st (ParsecT HledgerParseErrorData Text m) a
    -> StateT st (ParsecT HledgerParseErrorData Text m) ()
    -> StateT st (ParsecT HledgerParseErrorData Text m) a
    forall a b.
    StateT st (ParsecT HledgerParseErrorData Text m) a
    -> StateT st (ParsecT HledgerParseErrorData Text m) b
    -> StateT st (ParsecT HledgerParseErrorData Text m) a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* StateT st (ParsecT HledgerParseErrorData Text m) ()
    forall e s (m :: * -> *). MonadParsec e s m => m ()
    eof) st
    forall a. Default a => a
    def) [Char]
    "" Text
    input

    -- | Run a stateful parser in IO and process either a failure or success to
    -- produce an 'Assertion'. Suitable for hledger's JournalParser parsers.
    assertParseHelper :: (HasCallStack, Default st) =>
      (String -> Assertion) -> (a -> Assertion)
      -> StateT st (ParsecT HledgerParseErrorData T.Text IO) a -> T.Text
      -> Assertion
    assertParseHelper :: forall st a.
    (HasCallStack, Default st) =>
    ([Char] -> Assertion)
    -> (a -> Assertion)
    -> StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> Text
    -> Assertion
    assertParseHelper [Char] -> Assertion
    onFailure a -> Assertion
    onSuccess StateT st (ParsecT HledgerParseErrorData Text IO) a
    parser Text
    input =
      ([Char] -> Assertion)
    -> (a -> Assertion) -> Either [Char] a -> Assertion
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either [Char] -> Assertion
    onFailure a -> Assertion
    onSuccess (Either [Char] a -> Assertion) -> IO (Either [Char] a) -> Assertion
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< ExceptT [Char] IO a -> IO (Either [Char] a)
    forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    runExceptT (StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> Text -> ExceptT [Char] IO a
    forall st (m :: * -> *) a.
    (HasCallStack, Default st, Monad m) =>
    StateT st (ParsecT HledgerParseErrorData Text m) a
    -> Text -> ExceptT [Char] m a
    parseHelper StateT st (ParsecT HledgerParseErrorData Text IO) a
    parser Text
    input)

    -- | Assert that this stateful parser runnable in IO successfully parses
    -- all of the given input text, showing the parse error if it fails.
    -- Suitable for hledger's JournalParser parsers.
    assertParse :: (HasCallStack, Default st) =>
      StateT st (ParsecT HledgerParseErrorData T.Text IO) a -> T.Text -> Assertion
    assertParse :: forall st a.
    (HasCallStack, Default st) =>
    StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> Text -> Assertion
    assertParse = ([Char] -> Assertion)
    -> (a -> Assertion)
    -> StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> Text
    -> Assertion
    forall st a.
    (HasCallStack, Default st) =>
    ([Char] -> Assertion)
    -> (a -> Assertion)
    -> StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> Text
    -> Assertion
    assertParseHelper [Char] -> Assertion
    forall a. HasCallStack => [Char] -> IO a
    assertFailure (Assertion -> a -> Assertion
    forall a b. a -> b -> a
    const (Assertion -> a -> Assertion) -> Assertion -> a -> Assertion
    forall a b. (a -> b) -> a -> b
    $ () -> Assertion
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ())

    -- | Assert a parser produces an expected value.
    assertParseEq :: (HasCallStack, Eq a, Show a, Default st) =>
      StateT st (ParsecT HledgerParseErrorData T.Text IO) a -> T.Text -> a -> Assertion
    assertParseEq :: forall a st.
    (HasCallStack, Eq a, Show a, Default st) =>
    StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> Text -> a -> Assertion
    assertParseEq StateT st (ParsecT HledgerParseErrorData Text IO) a
    parser Text
    input = StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> Text -> (a -> a) -> a -> Assertion
    forall b st a.
    (HasCallStack, Eq b, Show b, Default st) =>
    StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> Text -> (a -> b) -> b -> Assertion
    assertParseEqOn StateT st (ParsecT HledgerParseErrorData Text IO) a
    parser Text
    input a -> a
    forall a. a -> a
    id

    -- | Like assertParseEq, but transform the parse result with the given function
    -- before comparing it.
    assertParseEqOn :: (HasCallStack, Eq b, Show b, Default st) =>
      StateT st (ParsecT HledgerParseErrorData T.Text IO) a -> T.Text -> (a -> b) -> b -> Assertion
    assertParseEqOn :: forall b st a.
    (HasCallStack, Eq b, Show b, Default st) =>
    StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> Text -> (a -> b) -> b -> Assertion
    assertParseEqOn StateT st (ParsecT HledgerParseErrorData Text IO) a
    parser Text
    input a -> b
    f b
    expected =
      ([Char] -> Assertion)
    -> (a -> Assertion)
    -> StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> Text
    -> Assertion
    forall st a.
    (HasCallStack, Default st) =>
    ([Char] -> Assertion)
    -> (a -> Assertion)
    -> StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> Text
    -> Assertion
    assertParseHelper [Char] -> Assertion
    forall a. HasCallStack => [Char] -> IO a
    assertFailure ([Char] -> b -> b -> Assertion
    forall a.
    (Eq a, Show a, HasCallStack) =>
    [Char] -> a -> a -> Assertion
    assertEqual [Char]
    "" b
    expected (b -> Assertion) -> (a -> b) -> a -> Assertion
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> b
    f) StateT st (ParsecT HledgerParseErrorData Text IO) a
    parser Text
    input

    -- | Assert that this stateful parser runnable in IO fails to parse
    -- the given input text, with a parse error containing the given string.
    assertParseError :: (HasCallStack, Eq a, Show a, Default st) =>
      StateT st (ParsecT HledgerParseErrorData T.Text IO) a -> T.Text -> String -> Assertion
    assertParseError :: forall a st.
    (HasCallStack, Eq a, Show a, Default st) =>
    StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> Text -> [Char] -> Assertion
    assertParseError StateT st (ParsecT HledgerParseErrorData Text IO) a
    parser Text
    input [Char]
    errstr = ([Char] -> Assertion)
    -> (a -> Assertion)
    -> StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> Text
    -> Assertion
    forall st a.
    (HasCallStack, Default st) =>
    ([Char] -> Assertion)
    -> (a -> Assertion)
    -> StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> Text
    -> Assertion
    assertParseHelper
      (\[Char]
    e -> Bool -> Assertion -> Assertion
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless ([Char]
    errstr [Char] -> [Char] -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isInfixOf` [Char]
    e) (Assertion -> Assertion) -> Assertion -> Assertion
    forall a b. (a -> b) -> a -> b
    $ [Char] -> Assertion
    forall a. HasCallStack => [Char] -> IO a
    assertFailure ([Char] -> Assertion) -> [Char] -> Assertion
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "\nparse error is not as expected:" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    e)
      (\a
    v -> [Char] -> Assertion
    forall a. HasCallStack => [Char] -> IO a
    assertFailure ([Char] -> Assertion) -> [Char] -> Assertion
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "\nparse succeeded unexpectedly, producing:\n" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ a -> [Char]
    forall a. Show a => a -> [Char]
    pshow a
    v [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "\n")
      StateT st (ParsecT HledgerParseErrorData Text IO) a
    parser Text
    input

    -- | Run a stateful parser in IO like assertParse, then assert that the
    -- final state (the wrapped state, not megaparsec's internal state),
    -- transformed by the given function, matches the given expected value.
    assertParseStateOn :: (HasCallStack, Eq b, Show b, Default st) =>
         StateT st (ParsecT HledgerParseErrorData T.Text IO) a -> T.Text -> (st -> b) -> b -> Assertion
    assertParseStateOn :: forall b st a.
    (HasCallStack, Eq b, Show b, Default st) =>
    StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> Text -> (st -> b) -> b -> Assertion
    assertParseStateOn StateT st (ParsecT HledgerParseErrorData Text IO) a
    parser Text
    input st -> b
    f b
    expected = do
      Either HledgerParseErrors st
    es <- ParsecT HledgerParseErrorData Text IO st
    -> [Char] -> Text -> IO (Either HledgerParseErrors st)
    forall (m :: * -> *) e s a.
    Monad m =>
    ParsecT e s m a
    -> [Char] -> s -> m (Either (ParseErrorBundle s e) a)
    runParserT (StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> st -> ParsecT HledgerParseErrorData Text IO st
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s
    execStateT (StateT st (ParsecT HledgerParseErrorData Text IO) a
    parser StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> StateT st (ParsecT HledgerParseErrorData Text IO) ()
    -> StateT st (ParsecT HledgerParseErrorData Text IO) a
    forall a b.
    StateT st (ParsecT HledgerParseErrorData Text IO) a
    -> StateT st (ParsecT HledgerParseErrorData Text IO) b
    -> StateT st (ParsecT HledgerParseErrorData Text IO) a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* StateT st (ParsecT HledgerParseErrorData Text IO) ()
    forall e s (m :: * -> *). MonadParsec e s m => m ()
    eof) st
    forall a. Default a => a
    def) [Char]
    "" Text
    input
      case Either HledgerParseErrors st
    es of
        Left HledgerParseErrors
    err -> [Char] -> Assertion
    forall a. HasCallStack => [Char] -> IO a
    assertFailure ([Char] -> Assertion) -> [Char] -> Assertion
    forall a b. (a -> b) -> a -> b
    $ ([Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++[Char]
    "\n") ([Char] -> [Char]) -> [Char] -> [Char]
    forall a b. (a -> b) -> a -> b
    $ ([Char]
    "\nparse error at "[Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++) ([Char] -> [Char]) -> [Char] -> [Char]
    forall a b. (a -> b) -> a -> b
    $ HledgerParseErrors -> [Char]
    customErrorBundlePretty HledgerParseErrors
    err
        Right st
    s  -> [Char] -> b -> b -> Assertion
    forall a.
    (Eq a, Show a, HasCallStack) =>
    [Char] -> a -> a -> Assertion
    assertEqual [Char]
    "" b
    expected (b -> Assertion) -> b -> Assertion
    forall a b. (a -> b) -> a -> b
    $ st -> b
    f st
    s

    -- | These "E" variants of the above are suitable for hledger's ErroringJournalParser parsers.
    parseHelperE :: (HasCallStack, Default st, Monad m) =>
      StateT st (ParsecT HledgerParseErrorData T.Text (ExceptT FinalParseError m)) a -> T.Text -> ExceptT String m a
    parseHelperE :: forall st (m :: * -> *) a.
    (HasCallStack, Default st, Monad m) =>
    StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError m))
      a
    -> Text -> ExceptT [Char] m a
    parseHelperE StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError m))
      a
    parser Text
    input = do
      (HledgerParseErrors -> [Char])
    -> ExceptT HledgerParseErrors m a -> ExceptT [Char] m a
    forall (m :: * -> *) e e' a.
    Functor m =>
    (e -> e') -> ExceptT e m a -> ExceptT e' m a
    withExceptT (\HledgerParseErrors
    e -> [Char]
    "\nparse error at " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ HledgerParseErrors -> [Char]
    customErrorBundlePretty HledgerParseErrors
    e [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "\n") (ExceptT HledgerParseErrors m a -> ExceptT [Char] m a)
    -> (Either HledgerParseErrors a -> ExceptT HledgerParseErrors m a)
    -> Either HledgerParseErrors a
    -> ExceptT [Char] m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Either HledgerParseErrors a -> ExceptT HledgerParseErrors m a
    forall e (m :: * -> *) a. MonadError e m => Either e a -> m a
    liftEither
      (Either HledgerParseErrors a -> ExceptT [Char] m a)
    -> ExceptT [Char] m (Either HledgerParseErrors a)
    -> ExceptT [Char] m a
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< (FinalParseError -> [Char])
    -> ExceptT FinalParseError m (Either HledgerParseErrors a)
    -> ExceptT [Char] m (Either HledgerParseErrors a)
    forall (m :: * -> *) e e' a.
    Functor m =>
    (e -> e') -> ExceptT e m a -> ExceptT e' m a
    withExceptT (\FinalParseError
    e -> [Char]
    "parse error at " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ FinalParseErrorBundle' HledgerParseErrorData -> [Char]
    finalErrorBundlePretty ([Char]
    -> Text
    -> FinalParseError
    -> FinalParseErrorBundle' HledgerParseErrorData
    forall e.
    [Char] -> Text -> FinalParseError' e -> FinalParseErrorBundle' e
    attachSource [Char]
    "" Text
    input FinalParseError
    e))
            (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError m) a
    -> [Char]
    -> Text
    -> ExceptT FinalParseError m (Either HledgerParseErrors a)
    forall (m :: * -> *) e s a.
    Monad m =>
    ParsecT e s m a
    -> [Char] -> s -> m (Either (ParseErrorBundle s e) a)
    runParserT (StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError m))
      a
    -> st
    -> ParsecT HledgerParseErrorData Text (ExceptT FinalParseError m) a
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
    evalStateT (StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError m))
      a
    parser StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError m))
      a
    -> StateT
         st
         (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError m))
         ()
    -> StateT
         st
         (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError m))
         a
    forall a b.
    StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError m))
      a
    -> StateT
         st
         (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError m))
         b
    -> StateT
         st
         (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError m))
         a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError m))
      ()
    forall e s (m :: * -> *). MonadParsec e s m => m ()
    eof) st
    forall a. Default a => a
    def) [Char]
    "" Text
    input)

    assertParseHelperE :: (HasCallStack, Default st) =>
      (String -> Assertion) -> (a -> Assertion)
      -> StateT st (ParsecT HledgerParseErrorData T.Text (ExceptT FinalParseError IO)) a -> T.Text
      -> Assertion
    assertParseHelperE :: forall st a.
    (HasCallStack, Default st) =>
    ([Char] -> Assertion)
    -> (a -> Assertion)
    -> StateT
         st
         (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
         a
    -> Text
    -> Assertion
    assertParseHelperE [Char] -> Assertion
    onFailure a -> Assertion
    onSuccess StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
      a
    parser Text
    input =
      ([Char] -> Assertion)
    -> (a -> Assertion) -> Either [Char] a -> Assertion
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either [Char] -> Assertion
    onFailure a -> Assertion
    onSuccess (Either [Char] a -> Assertion) -> IO (Either [Char] a) -> Assertion
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< ExceptT [Char] IO a -> IO (Either [Char] a)
    forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    runExceptT (StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
      a
    -> Text -> ExceptT [Char] IO a
    forall st (m :: * -> *) a.
    (HasCallStack, Default st, Monad m) =>
    StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError m))
      a
    -> Text -> ExceptT [Char] m a
    parseHelperE StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
      a
    parser Text
    input)

    assertParseE
      :: (HasCallStack, Eq a, Show a, Default st)
      => StateT st (ParsecT HledgerParseErrorData T.Text (ExceptT FinalParseError IO)) a -> T.Text -> Assertion
    assertParseE :: forall a st.
    (HasCallStack, Eq a, Show a, Default st) =>
    StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
      a
    -> Text -> Assertion
    assertParseE = ([Char] -> Assertion)
    -> (a -> Assertion)
    -> StateT
         st
         (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
         a
    -> Text
    -> Assertion
    forall st a.
    (HasCallStack, Default st) =>
    ([Char] -> Assertion)
    -> (a -> Assertion)
    -> StateT
         st
         (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
         a
    -> Text
    -> Assertion
    assertParseHelperE [Char] -> Assertion
    forall a. HasCallStack => [Char] -> IO a
    assertFailure (Assertion -> a -> Assertion
    forall a b. a -> b -> a
    const (Assertion -> a -> Assertion) -> Assertion -> a -> Assertion
    forall a b. (a -> b) -> a -> b
    $ () -> Assertion
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ())

    assertParseEqE
      :: (Default st, Eq a, Show a, HasCallStack)
      => StateT st (ParsecT HledgerParseErrorData T.Text (ExceptT FinalParseError IO)) a -> T.Text -> a -> Assertion
    assertParseEqE :: forall st a.
    (Default st, Eq a, Show a, HasCallStack) =>
    StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
      a
    -> Text -> a -> Assertion
    assertParseEqE StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
      a
    parser Text
    input = StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
      a
    -> Text -> (a -> a) -> a -> Assertion
    forall b st a.
    (HasCallStack, Eq b, Show b, Default st) =>
    StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
      a
    -> Text -> (a -> b) -> b -> Assertion
    assertParseEqOnE StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
      a
    parser Text
    input a -> a
    forall a. a -> a
    id

    assertParseEqOnE
      :: (HasCallStack, Eq b, Show b, Default st)
      => StateT st (ParsecT HledgerParseErrorData T.Text (ExceptT FinalParseError IO)) a -> T.Text -> (a -> b) -> b -> Assertion
    assertParseEqOnE :: forall b st a.
    (HasCallStack, Eq b, Show b, Default st) =>
    StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
      a
    -> Text -> (a -> b) -> b -> Assertion
    assertParseEqOnE StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
      a
    parser Text
    input a -> b
    f b
    expected =
      ([Char] -> Assertion)
    -> (a -> Assertion)
    -> StateT
         st
         (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
         a
    -> Text
    -> Assertion
    forall st a.
    (HasCallStack, Default st) =>
    ([Char] -> Assertion)
    -> (a -> Assertion)
    -> StateT
         st
         (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
         a
    -> Text
    -> Assertion
    assertParseHelperE [Char] -> Assertion
    forall a. HasCallStack => [Char] -> IO a
    assertFailure ([Char] -> b -> b -> Assertion
    forall a.
    (Eq a, Show a, HasCallStack) =>
    [Char] -> a -> a -> Assertion
    assertEqual [Char]
    "" b
    expected (b -> Assertion) -> (a -> b) -> a -> Assertion
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> b
    f) StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
      a
    parser Text
    input

    assertParseErrorE
      :: (Default st, Eq a, Show a, HasCallStack)
      => StateT st (ParsecT HledgerParseErrorData T.Text (ExceptT FinalParseError IO)) a -> T.Text -> String -> Assertion
    assertParseErrorE :: forall st a.
    (Default st, Eq a, Show a, HasCallStack) =>
    StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
      a
    -> Text -> [Char] -> Assertion
    assertParseErrorE StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
      a
    parser Text
    input [Char]
    errstr = ([Char] -> Assertion)
    -> (a -> Assertion)
    -> StateT
         st
         (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
         a
    -> Text
    -> Assertion
    forall st a.
    (HasCallStack, Default st) =>
    ([Char] -> Assertion)
    -> (a -> Assertion)
    -> StateT
         st
         (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
         a
    -> Text
    -> Assertion
    assertParseHelperE
      (\[Char]
    e -> Bool -> Assertion -> Assertion
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless ([Char]
    errstr [Char] -> [Char] -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isInfixOf` [Char]
    e) (Assertion -> Assertion) -> Assertion -> Assertion
    forall a b. (a -> b) -> a -> b
    $ [Char] -> Assertion
    forall a. HasCallStack => [Char] -> IO a
    assertFailure ([Char] -> Assertion) -> [Char] -> Assertion
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "\nparse error is not as expected:" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    e)
      (\a
    v -> [Char] -> Assertion
    forall a. HasCallStack => [Char] -> IO a
    assertFailure ([Char] -> Assertion) -> [Char] -> Assertion
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "\nparse succeeded unexpectedly, producing:\n" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ a -> [Char]
    forall a. Show a => a -> [Char]
    pshow a
    v [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "\n")
      StateT
      st
      (ParsecT HledgerParseErrorData Text (ExceptT FinalParseError IO))
      a
    parser Text
    input