demangler-1.1.0.0: test/Test.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeApplications #-}
module Main (main) where
import Control.Monad.Trans.State
import Data.Text ( Text )
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
import qualified Prettyprinter as PP
import qualified Prettyprinter.Render.Text as PRT
import System.Process
import Test.Hspec
import Test.Tasty
import Test.Tasty.Hspec
import Text.Sayable
import Demangler ( demangle, demangle1, newDemangling )
-- n.b. Original conception was to use a Sandwich Context to retrieve the
-- contents of the input data files, but a Context can only be retrieved (via
-- getContext) inside an ExampleT, which is the body of an `it "something" body`
-- statement. Thus, there's no way to iterate over the individual lines of the
-- input file and create an ExampleT test for each one.
main :: IO ()
main = do inps <- mapM getInputData [ "test/initial-test-cases.txt"
, "test/full-test-cases.txt"
]
defaultMain =<< (testSpec "Demangle" $ demangleTests inps)
getInputData :: String -> IO (String, [(Text, Text)])
getInputData fname = do
inputs <- TIO.readFile fname
expects <- T.pack <$> readProcess "c++filt" [] (T.unpack inputs)
let pairs = zip (T.lines inputs) (T.lines expects)
return (fname, pairs)
demangleTests :: [(String, [(Text, Text)])] -> Spec
demangleTests testInputs = describe "Demangle tests" $
mapM_ demangleTestSet testInputs
demangleTestSet :: (String, [(Text, Text)]) -> Spec
demangleTestSet (inpFile, inpData) =
describe inpFile $
do describe "Individually" $ sequence_ (mkTest <$> inpData)
describe "Batched" $ batchTest inpData
mkTest :: (Text, Text) -> Spec
mkTest (sym, expected) = it ("demangles " <> T.unpack sym) $
(toText $ demangle1 sym) `shouldBe` expected
batchTest :: [(Text, Text)] -> Spec
batchTest symbols =
let r = runState (sequence (state . demangle . fst <$> symbols)) newDemangling
mkRes (dm, (inp, ex)) prs = (inp, toText (dm, snd r), ex) : prs
results = foldr mkRes [] $ zip (fst r) symbols
validate (i,rslt,e) = it ("demangles " <> T.unpack i) $ rslt `shouldBe` e
in sequence_ (validate <$> results)
toText :: Sayable "normal" a => a -> Text
toText = PRT.renderStrict
. PP.layoutPretty (PP.LayoutOptions PP.Unbounded)
. saying . sayable @"normal"