{-# LANGUAGE PatternGuards, ScopedTypeVariables, RecordWildCards, ViewPatterns #-}
module Test.Annotations(testAnnotations) where
import Control.Arrow
import Data.Char
import Data.List
import Data.Maybe
import Data.Function
import Settings
import Util
import Idea
import Apply
import HSE.All
import Test.Util
data Test = Test SrcLoc String (Maybe String)
testAnnotations :: [Setting] -> FilePath -> IO ()
testAnnotations setting file = do
tests <- parseTestFile file
mapM_ f tests
where
f (Test loc inp out) = do
ideas <- applyHintFile defaultParseFlags setting file $ Just inp
let good = case out of
Nothing -> null ideas
Just x -> length ideas == 1 &&
seq (length (show ideas)) True &&
isJust (ideaTo $ head ideas) &&
match x (head ideas)
let bad =
[failed $
["TEST FAILURE (" ++ show (length ideas) ++ " hints generated)"
,"SRC: " ++ showSrcLoc loc
,"INPUT: " ++ inp] ++
map ((++) "OUTPUT: " . show) ideas ++
["WANTED: " ++ fromMaybe "<failure>" out]
| not good] ++
[failed
["TEST FAILURE (BAD LOCATION)"
,"SRC: " ++ showSrcLoc loc
,"INPUT: " ++ inp
,"OUTPUT: " ++ show i]
| i@Idea{..} <- ideas, let SrcLoc{..} = getPointLoc ideaSpan, srcFilename == "" || srcLine == 0 || srcColumn == 0]
if null bad then passed else sequence_ bad
match "???" _ = True
match x y | "@" `isPrefixOf` x = a == show (ideaSeverity y) && match (ltrim b) y
where (a,b) = break isSpace $ tail x
match x y = on (==) norm (fromMaybe "" $ ideaTo y) x
norm = filter $ \x -> not (isSpace x) && x /= ';'
parseTestFile :: FilePath -> IO [Test]
parseTestFile file = do
src <- readFile file
return $ f False $ zip [1..] $ lines src
where
open = isPrefixOf "<TEST>"
shut = isPrefixOf "</TEST>"
f False ((i,x):xs) = f (open x) xs
f True ((i,x):xs)
| shut x = f False xs
| null x || "-- " `isPrefixOf` x = f True xs
| "\\" `isSuffixOf` x, (_,y):ys <- xs = f True $ (i,init x++"\n"++y):ys
| otherwise = parseTest file i x : f True xs
f _ [] = []
parseTest file i x = uncurry (Test (SrcLoc file i 0)) $ f x
where
f x | Just x <- stripPrefix "<COMMENT>" x = first ("--"++) $ f x
f (' ':'-':'-':xs) | null xs || " " `isPrefixOf` xs = ("", Just $ dropWhile isSpace xs)
f (x:xs) = first (x:) $ f xs
f [] = ([], Nothing)