{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
-- | Use "runhaskell Setup.hs test" or "cabal test" to run these tests.
module Main where
-- import Language.Haskell.GHC.ExactPrint.Utils ( showGhc )
import Control.Monad
import System.Directory
import System.FilePath
import System.IO
import System.Exit
import Data.List
import qualified Data.Set as Set
import System.IO.Silently
import Test.Common
import Test.NoAnnotations
import Test.Transform
import Test.HUnit
-- import Debug.Trace
-- ---------------------------------------------------------------------
data GHCVersion = GHC710 | GHC80 | GHC82 | GHC84 | GHC86
deriving (Eq, Ord, Show)
ghcVersion :: GHCVersion
ghcVersion =
#if __GLASGOW_HASKELL__ > 804
GHC86
#elif __GLASGOW_HASKELL__ > 802
GHC84
#elif __GLASGOW_HASKELL__ > 800
GHC82
#elif __GLASGOW_HASKELL__ >= 711
GHC80
#else
GHC710
#endif
-- | Directories to automatically find roundtrip tests
testDirs :: [FilePath]
testDirs =
case ghcVersion of
GHC710 -> ["ghc710-only","ghc710", "vect"]
GHC80 -> [ "ghc710", "ghc80", "vect"]
GHC82 -> ["pre-ghc86", "ghc710", "ghc80", "ghc82", "vect"]
GHC84 -> ["pre-ghc86", "ghc710", "ghc80", "ghc82", "ghc84", "vect" ]
GHC86 -> [ "ghc710", "ghc80", "ghc82", "ghc84", "ghc86" ]
-- GHC86 -> [ "ghc710", "ghc80", "ghc82", "ghc84"]
-- GHC86 -> ["ghc86-copied"]
-- GHC86 -> ["ghc86"]
-- ---------------------------------------------------------------------
main :: IO ()
main = hSilence [stderr] $ do
print ghcVersion
tests <- mkTests
cnts <- fst <$> runTestText (putTextToHandle stdout True) tests
putStrLn $ show cnts
if errors cnts > 0 || failures cnts > 0
then exitFailure
else return () -- exitSuccess
transform :: IO ()
transform = hSilence [stderr] $ do
cnts <- fst <$> runTestText (putTextToHandle stdout True) transformTests
putStrLn $ show cnts
if errors cnts > 0 || failures cnts > 0
then exitFailure
else return () -- exitSuccess
-- ---------------------------------------------------------------------
findTests :: IO Test
findTests = testList "Round-trip tests" <$> mapM (findTestsDir id mkParserTest) testDirs
findPrettyTests :: IO Test
findPrettyTests =
testList "Default Annotations round-trip tests"
<$> mapM (findTestsDir filterPrettyRoundTrip mkPrettyRoundtrip) testDirs
-- | Filter out tests that are known to fail, for particular compilers
filterPrettyRoundTrip :: [FilePath] -> [FilePath]
filterPrettyRoundTrip fps = sort $ Set.toList $ Set.difference (Set.fromList fps) skipped
-- filterPrettyRoundTrip fps = error $ "filterPrettyRoundTrip:fps=" ++ show fps
where
#if __GLASGOW_HASKELL__ > 800
-- GHC 8.2
skipped = Set.empty
#elif __GLASGOW_HASKELL__ >= 711
-- GHC 8.0
skipped = Set.fromList
[
-- testPrefix </> "ghc80" </> "MultiQuote.hs"
"MultiQuote.hs"
, "TestUtils.hs"
, "T10689a.hs"
, "Zwaluw.hs"
, "determ004.hs"
]
#else
-- GHC 7.10
skipped = Set.empty
#endif
findTestsDir :: ([FilePath] -> [FilePath]) -> (FilePath -> FilePath -> Test) -> FilePath -> IO Test
findTestsDir filterFn mkTestFn dir = do
let fp = testPrefix </> dir
fs <- getDirectoryContents fp
let testFiles = sort $ filter (".hs" `isSuffixOf`) fs
return $ testList dir (map (\fn -> TestLabel fn (mkTestFn dir fn)) $ filterFn testFiles)
listTests :: IO ()
listTests = do
let
ftd dir = do
let fp = testPrefix </> dir
fs <- getDirectoryContents fp
let testFiles = sort $ filter (".hs" `isSuffixOf`) fs
return (zip [0::Integer ..] testFiles)
files <- mapM ftd testDirs
putStrLn $ "round trip tests:" ++ show (zip testDirs files)
mkTests :: IO Test
mkTests = do
-- listTests
roundTripTests <- findTests
prettyRoundTripTests <- findPrettyTests
return $ TestList [
internalTests,
roundTripTests
,
transformTests
, failingTests
, noAnnotationTests
,
prettyRoundTripTests
]
-- Tests that will fail until https://phabricator.haskell.org/D907 lands in a
-- future GHC
failingTests :: Test
failingTests = testList "Failing tests"
[
-- Tests requiring future GHC modifications
mkTestModBad "InfixOperator.hs"
#if __GLASGOW_HASKELL__ > 802
#elif __GLASGOW_HASKELL__ > 800
, mkTestModBad "overloadedlabelsrun04.hs"
#elif __GLASGOW_HASKELL__ > 710
, mkTestModBad "overloadedlabelsrun04.hs"
, mkTestModBad "TensorTests.hs" -- Should be fixed in GHC 8.2
, mkTestModBad "List2.hs" -- Should be fixed in GHC 8.2
#else
, mkTestModBad "CtorOp.hs" -- Should be fixed in GHC 8.4
, mkTestModBad "UnicodeSyntax.hs"
, mkTestModBad "UnicodeRules.hs"
, mkTestModBad "Deprecation.hs"
, mkTestModBad "MultiLineWarningPragma.hs"
#endif
]
mkParserTest :: FilePath -> FilePath -> Test
mkParserTest dir fp = mkParsingTest roundTripTest dir fp
-- ---------------------------------------------------------------------
formatTT :: ([([Char], Bool)], [([Char], Bool)]) -> IO ()
formatTT (ts, fs) = do
when (not . null $ tail ts) (do
putStrLn "Pass"
mapM_ (putStrLn . fst) (tail ts)
)
when (not . null $ fs) (do
putStrLn "Fail"
mapM_ (putStrLn . fst) fs)
tr :: IO (Counts,Int)
tr = hSilence [stderr] $ do
prettyRoundTripTests <- findPrettyTests
runTestText (putTextToHandle stdout True) prettyRoundTripTests
tt' :: IO (Counts,Int)
tt' = runTestText (putTextToHandle stdout True) $ TestList [
-- mkPrettyRoundtrip "ghc82" "TensorTests.hs"
mkParserTest "ghc710" "GADTContext.hs"
-- mkParserTest "ghc86" "deriving-via-compile.hs"
-- mkParserTest "pre-ghc86" "TensorTests.hs"
-- , mkParserTest "pre-ghc86" "Webhook.hs"
-- , mkParserTest "ghc710" "RdrNames.hs"
-- mkPrettyRoundtrip "ghc86" "BinDU.hs"
-- , mkPrettyRoundtrip "ghc86" "Dial.hs"
-- mkParserTest "ghc84" "Types.hs"
-- , mkPrettyRoundtrip "ghc80" "export-type.hs"
-- Needs GHC changes
-- mkParserTest "failing" "CtorOp.hs"
-- mkParserTest "failing" "InfixOperator.hs"
]
testsTT :: Test
testsTT = TestList
[
mkParserTest "ghc710" "Cpp.hs"
, mkParserTest "ghc710" "DroppedDoSpace.hs"
]
tt :: IO ()
-- tt = hSilence [stderr] $ do
tt = do
cnts <- fst <$> runTestText (putTextToHandle stdout True) testsTT
putStrLn $ show cnts
if errors cnts > 0 || failures cnts > 0
then exitFailure
else return () -- exitSuccess
-- ---------------------------------------------------------------------
ii :: IO ()
ii = do
cnts <- fst <$> runTestText (putTextToHandle stdout True) internalTests
putStrLn $ show cnts
if errors cnts > 0 || failures cnts > 0
then exitFailure
else return () -- exitSuccess
internalTests :: Test
internalTests = testList "Internal tests"
[
-- testCleanupOneLine
]
{-
testCleanupOneLine :: Test
testCleanupOneLine = do
let
makeCase n = (show n
,(T.replicate n " ") <> "\t|" <> T.replicate n " " <> "\t"
,(T.replicate 8 " " <> "|"))
mkTest n = TestCase $ assertEqual name outp (cleanupOneLine inp)
where (name,inp,outp) = makeCase n
testList "cleanupOneLine" $ map mkTest [1..7]
-}
-- ---------------------------------------------------------------------
pwd :: IO FilePath
pwd = getCurrentDirectory
cd :: FilePath -> IO ()
cd = setCurrentDirectory