module Test.Looksee.Trip
  ( Cmp
  , cmpEq
  , ExpectP
  , expectParse
  , expectParsePretty
  , expectParseT
  , expectParseTPretty
  , expectRendered
  )
where

import Data.Text (Text)
import Looksee (Err, Parser, ParserT, parse, parseT)
import Prettyprinter (Pretty (..), defaultLayoutOptions, layoutPretty)
import Prettyprinter.Render.Text (renderStrict)
import Test.Daytripper (Expect, MonadExpect (..), expectDuring, mkExpect)

prettyText :: (Pretty a) => a -> Text
prettyText :: forall a. Pretty a => a -> Text
prettyText = SimpleDocStream Any -> Text
forall ann. SimpleDocStream ann -> Text
renderStrict (SimpleDocStream Any -> Text)
-> (a -> SimpleDocStream Any) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LayoutOptions -> Doc Any -> SimpleDocStream Any
forall ann. LayoutOptions -> Doc ann -> SimpleDocStream ann
layoutPretty LayoutOptions
defaultLayoutOptions (Doc Any -> SimpleDocStream Any)
-> (a -> Doc Any) -> a -> SimpleDocStream Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Doc Any
forall ann. a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

type Cmp e m a = Maybe a -> Either (Err e) a -> m ()

cmpEq :: (MonadExpect m, Eq e, Show e, Eq a, Show a) => Cmp e m a
cmpEq :: forall (m :: * -> *) e a.
(MonadExpect m, Eq e, Show e, Eq a, Show a) =>
Cmp e m a
cmpEq Maybe a
ma Either (Err e) a
ea = Either (Maybe (Err e)) a -> Either (Maybe (Err e)) a -> m ()
forall a. (Eq a, Show a) => a -> a -> m ()
forall (m :: * -> *) a.
(MonadExpect m, Eq a, Show a) =>
a -> a -> m ()
expectAssertEq (Either (Maybe (Err e)) a
-> (a -> Either (Maybe (Err e)) a)
-> Maybe a
-> Either (Maybe (Err e)) a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Maybe (Err e) -> Either (Maybe (Err e)) a
forall a b. a -> Either a b
Left Maybe (Err e)
forall a. Maybe a
Nothing) a -> Either (Maybe (Err e)) a
forall a b. b -> Either a b
Right Maybe a
ma) ((Err e -> Either (Maybe (Err e)) a)
-> (a -> Either (Maybe (Err e)) a)
-> Either (Err e) a
-> Either (Maybe (Err e)) a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe (Err e) -> Either (Maybe (Err e)) a
forall a b. a -> Either a b
Left (Maybe (Err e) -> Either (Maybe (Err e)) a)
-> (Err e -> Maybe (Err e)) -> Err e -> Either (Maybe (Err e)) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Err e -> Maybe (Err e)
forall a. a -> Maybe a
Just) a -> Either (Maybe (Err e)) a
forall a b. b -> Either a b
Right Either (Err e) a
ea)

type ExpectP e m a = Expect m a Text (Either (Err e) a)

expectParse :: (MonadExpect m) => (a -> Text) -> Parser e a -> Cmp e m a -> ExpectP e m a
expectParse :: forall (m :: * -> *) a e.
MonadExpect m =>
(a -> Text) -> Parser e a -> Cmp e m a -> ExpectP e m a
expectParse a -> Text
printer Parser e a
parser = (a -> m Text)
-> (Text -> m (Either (Err e) a))
-> (Maybe a -> Either (Err e) a -> m ())
-> Expect m a Text (Either (Err e) a)
forall (m :: * -> *) a b c.
MonadExpect m =>
(a -> m b)
-> (b -> m c) -> (Maybe a -> c -> m ()) -> Expect m a b c
mkExpect a -> m Text
enc Text -> m (Either (Err e) a)
dec
 where
  enc :: a -> m Text
enc = Text -> m Text
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> m Text) -> (a -> Text) -> a -> m Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Text
printer
  dec :: Text -> m (Either (Err e) a)
dec = Either (Err e) a -> m (Either (Err e) a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either (Err e) a -> m (Either (Err e) a))
-> (Text -> Either (Err e) a) -> Text -> m (Either (Err e) a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser e a -> Text -> Either (Err e) a
forall e a. Parser e a -> Text -> Either (Err e) a
parse Parser e a
parser

expectParsePretty :: (MonadExpect m, Pretty a) => Parser e a -> Cmp e m a -> ExpectP e m a
expectParsePretty :: forall (m :: * -> *) a e.
(MonadExpect m, Pretty a) =>
Parser e a -> Cmp e m a -> ExpectP e m a
expectParsePretty = (a -> Text) -> Parser e a -> Cmp e m a -> ExpectP e m a
forall (m :: * -> *) a e.
MonadExpect m =>
(a -> Text) -> Parser e a -> Cmp e m a -> ExpectP e m a
expectParse a -> Text
forall a. Pretty a => a -> Text
prettyText

expectParseT :: (MonadExpect m) => (a -> Text) -> ParserT e m a -> Cmp e m a -> ExpectP e m a
expectParseT :: forall (m :: * -> *) a e.
MonadExpect m =>
(a -> Text) -> ParserT e m a -> Cmp e m a -> ExpectP e m a
expectParseT a -> Text
printer ParserT e m a
parser = (a -> m Text)
-> (Text -> m (Either (Err e) a))
-> (Maybe a -> Either (Err e) a -> m ())
-> Expect m a Text (Either (Err e) a)
forall (m :: * -> *) a b c.
MonadExpect m =>
(a -> m b)
-> (b -> m c) -> (Maybe a -> c -> m ()) -> Expect m a b c
mkExpect a -> m Text
enc Text -> m (Either (Err e) a)
dec
 where
  enc :: a -> m Text
enc = Text -> m Text
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> m Text) -> (a -> Text) -> a -> m Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Text
printer
  dec :: Text -> m (Either (Err e) a)
dec = ParserT e m a -> Text -> m (Either (Err e) a)
forall (m :: * -> *) e a.
Monad m =>
ParserT e m a -> Text -> m (Either (Err e) a)
parseT ParserT e m a
parser

expectParseTPretty :: (MonadExpect m, Pretty a) => ParserT e m a -> Cmp e m a -> ExpectP e m a
expectParseTPretty :: forall (m :: * -> *) a e.
(MonadExpect m, Pretty a) =>
ParserT e m a -> Cmp e m a -> ExpectP e m a
expectParseTPretty = (a -> Text) -> ParserT e m a -> Cmp e m a -> ExpectP e m a
forall (m :: * -> *) a e.
MonadExpect m =>
(a -> Text) -> ParserT e m a -> Cmp e m a -> ExpectP e m a
expectParseT a -> Text
forall a. Pretty a => a -> Text
prettyText

expectRendered :: (MonadExpect m) => Text -> ExpectP e m a -> ExpectP e m a
expectRendered :: forall (m :: * -> *) e a.
MonadExpect m =>
Text -> ExpectP e m a -> ExpectP e m a
expectRendered = (Maybe a -> Text -> m ())
-> Expect m a Text (Either (Err e) a)
-> Expect m a Text (Either (Err e) a)
forall (m :: * -> *) a b c.
Monad m =>
(Maybe a -> b -> m ()) -> Expect m a b c -> Expect m a b c
expectDuring ((Maybe a -> Text -> m ())
 -> Expect m a Text (Either (Err e) a)
 -> Expect m a Text (Either (Err e) a))
-> (Text -> Maybe a -> Text -> m ())
-> Text
-> Expect m a Text (Either (Err e) a)
-> Expect m a Text (Either (Err e) a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> m ()) -> Maybe a -> Text -> m ()
forall a b. a -> b -> a
const ((Text -> m ()) -> Maybe a -> Text -> m ())
-> (Text -> Text -> m ()) -> Text -> Maybe a -> Text -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Text -> m ()) -> Text -> Text -> m ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Text -> Text -> m ()
forall a. (Eq a, Show a) => a -> a -> m ()
forall (m :: * -> *) a.
(MonadExpect m, Eq a, Show a) =>
a -> a -> m ()
expectAssertEq