language-ocaml-0.2.0: test/Language/OCaml/PrettyPrinter/TestUtils.hs
module Language.OCaml.PrettyPrinter.TestUtils
( DebugPrettyPrinter(..)
, debugPrettyPrinter
, mkPrettyPrinterTest
, parseAndPrettyPrint
, parseMaybe
, pretty
, roundtrip
) where
import Data.Text.Prettyprint.Doc
import Text.Megaparsec
import Test.Tasty
import Test.Tasty.HUnit
-- import Language.OCaml.
import Language.OCaml.Parser
mkPrettyPrinterTest :: (Eq a) => TestName -> Parser a -> (a -> Doc b) -> String -> TestTree
mkPrettyPrinterTest name parser printer input =
testCase name $ condition @? message
where
condition =
case parser input of
Left _ -> False
Right r ->
case parser (show $ printer r) of
Left _ -> False
Right r' -> r == r'
message = "Failed to roundtrip:\n" ++ prefix ++ if length input > 20 then "..." else ""
prefix = take 20 input
data DebugPrettyPrinter a b
= NoParse1
| NoParse2 a (Doc b)
| ParseDiff a a
| ParseEq a
instance (Pretty a, Show a) => Show (DebugPrettyPrinter a b) where
show NoParse1 = "The input did not parse correctly"
show (NoParse2 a d) =
"The input parsed correctly, but its pretty-printed version did not parse\n"
++ show a ++ "\n"
++ show d ++ "\n"
show (ParseDiff a b) =
"The input parsed correctly, but its re-parse differs from it\n"
++ show a ++ "\n"
++ show b ++ "\n"
++ show (pretty a) ++ "\n"
++ show (pretty b) ++ "\n"
show (ParseEq a) =
"The input parsed correctly, and its re-parse matches\n"
++ show a ++ "\n"
++ show (pretty a) ++ "\n"
debugPrettyPrinter ::
(Eq a) => Parser a -> (a -> Doc b) -> String -> DebugPrettyPrinter a b
debugPrettyPrinter parser printer input =
case parser input of
Left _ -> NoParse1
Right r ->
case parser (show $ printer r) of
Left _ -> NoParse2 r (printer r)
Right r' -> if r == r' then ParseEq r' else ParseDiff r r'
parseAndPrettyPrint :: Parser a -> (a -> Doc b) -> String -> Either String (Doc b)
parseAndPrettyPrint parser printer input = printer <$> parser input
roundtrip :: Parser a -> (a -> Doc b) -> String -> Either String String
roundtrip p pp s = (show . pp) <$> p s