fnotation-0.2.0.0: test/Test/FNotation/Golden.hs
module Test.FNotation.Golden (goldenTests) where
import Control.Exception
import Data.ByteString.Lazy qualified as LBS
import Data.Functor.Contravariant (contramap)
import Data.Map (Map)
import Data.Map qualified as Map
import Data.Text.IO.Utf8 qualified as T
import Data.Text.Lazy qualified as TL
import Data.Text.Lazy.Encoding qualified as TLE
import Data.Vector qualified as V
import Diagnostician
import FNotation
import Prettyprinter
import Prettyprinter.Render.Text
import System.FilePath (replaceExtension, takeBaseName)
import System.IO
import System.IO.Temp (withSystemTempFile)
import Test.FNotation.Common
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.Golden (findByExtension, goldenVsString)
import Prelude hiding (lex)
render :: DDoc -> LBS.ByteString
render = TLE.encodeUtf8 . renderLazy . layoutPretty defaultLayoutOptions
data TestCode = LexerCode LexerCode | ParserCode ParserCode
deriving (Eq, Ord)
codeTable :: Map TestCode CodeMeta
codeTable =
mconcat
[ promoteCodeTable lexerCodeTable LexerCode 0
, promoteCodeTable parserCodeTable ParserCode 100
]
instance Code TestCode where
codeMeta c = case Map.lookup c codeTable of
Just m -> m
Nothing -> error "unregistered code"
parseToPretty :: FilePath -> IO LBS.ByteString
parseToPretty fp = do
src <- T.readFile fp
let f = newFile fp src
withSystemTempFile "reporter-output" $ \path h -> do
let r = fileReporter h
try @SomeException (lex lexConfig (contramap LexerCode r) f) >>= \case
Left err -> pure $ TLE.encodeUtf8 $ "lex error:\n" <> TL.show err
Right tokens -> do
try @SomeException (parse parseConfig (contramap ParserCode r) f tokens) >>= \case
Left err -> pure $ TLE.encodeUtf8 $ "parse error:\n" <> TL.show err
Right ns -> do
hFlush h
hClose h
msgs <- T.readFile path
pure $
render $
vsep
[ "-- tokens"
, vsep $ dpretty <$> V.toList tokens
, ""
, "-- notation"
, vsep $ dpretty <$> ns
, ""
, "-- pretty"
, vsep $ dprettyWithConfigs parseConfig lexConfig <$> ns
, ""
, "-- messages"
, pretty $ msgs
]
goldenTests :: IO TestTree
goldenTests = do
ntnFiles <- findByExtension [".ntn"] "."
return $
testGroup
"Golden tests"
[ goldenVsString (takeBaseName ntnFile) outputFile (parseToPretty ntnFile)
| ntnFile <- ntnFiles
, let outputFile = replaceExtension ntnFile ".output"
]