camfort-0.804: tests/Camfort/Analysis/CommentAnnotatorSpec.hs
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Camfort.Analysis.CommentAnnotatorSpec (spec) where
import Test.Hspec
import Data.Data
import Data.Generics.Uniplate.Data
import Control.Monad.Writer.Strict
import Language.Fortran.AST
import Language.Fortran.ParserMonad
import Language.Fortran.Util.Position
import Camfort.Analysis.CommentAnnotator
p = SrcSpan (Position 0 1 1) (Position 0 1 1)
spec =
describe "Comment annotator" $ do
it "annotates with no comment blocks" $
runWriter (annotateComments (\_ -> Right "") pf) `shouldBe` (pf, [])
it "links & annotates single comment block" $
runWriter (annotateComments (\_ -> Right "hello") pf2) `shouldBe` (pf2e, [])
it "link multiple comments to single statement" $
runWriter (annotateComments (\s -> Right $ "!!!" ++ s) pf3) `shouldBe` (pf3e, [])
it "link comments to separate targets" $
runWriter (annotateComments (\s -> Right $ "!!!" ++ s) pf4) `shouldBe` (pf4e, [])
it "generates warnings when there is a partial match" $ do
let parser _ = Left $ ProbablyAnnotation "This is a warning."
:: Either AnnotationParseError String
shouldBe (runWriter (annotateComments parser pf5))
(pf5e, [ "Error (1:1,1:1): This is a warning."
, "Error (1:1,1:1): This is a warning." ])
data A = A
{ annLink :: Maybe (Block A)
, annAST :: Maybe String }
deriving (Data, Eq, Show)
instance ASTEmbeddable A String where
annotateWithAST a str = a { annAST = Just str }
instance Linkable A where
link a block = a { annLink = Just block }
-- Some helper functions
varGen x = ExpValue ea p (ValVariable x)
intGen i = ExpValue ea p (ValInteger (show i))
wrapBlocks bs = ProgramFile (MetaInfo { miVersion = Fortran90 }) [ ([], pu) ] []
where
pu = PUModule ea p "my_module" bs Nothing
-- Test cases
ea = A Nothing Nothing
pf = wrapBlocks bs
bs = [ BlStatement ea p Nothing (StPause ea p Nothing) ]
pf2 = wrapBlocks bs2
bs2 =
[ BlComment ea p "something"
, BlStatement ea p Nothing (StPause ea p Nothing) ]
pf2e = wrapBlocks bs2e
bs2e =
[ BlComment (A (Just (bs2e !! 1)) (Just "hello")) p "something"
, BlStatement ea p Nothing (StPause ea p Nothing) ]
pf3 = wrapBlocks bs3
bs3 =
[ BlComment ea p "mistral"
, BlComment ea p "orhan"
, BlComment ea p "jean-pierre"
, BlComment ea p "contrastin"
, BlStatement ea p Nothing (StPause ea p Nothing) ]
pf3e = wrapBlocks bs3e
bs3e =
[ BlComment (A (Just (last bs3e)) (Just "!!!mistral")) p "mistral"
, BlComment (A (Just (last bs3e)) (Just "!!!orhan")) p "orhan"
, BlComment (A (Just (last bs3e)) (Just "!!!jean-pierre")) p "jean-pierre"
, BlComment (A (Just (last bs3e)) (Just "!!!contrastin")) p "contrastin"
, BlStatement ea p Nothing (StPause ea p Nothing) ]
pf4 = wrapBlocks bs4
bs4 =
[ BlComment ea p "mistral"
, BlComment ea p "contrastin"
, BlStatement ea p Nothing (StPause ea p Nothing)
, BlComment ea p "dominic"
, BlComment ea p "orchard"
, BlStatement ea p Nothing (StExpressionAssign ea p (varGen "x") (intGen 42)) ]
pf4e = wrapBlocks bs4e
bs4e =
[ BlComment (A (Just (bs4e !! 2)) (Just "!!!mistral")) p "mistral"
, BlComment (A (Just (bs4e !! 2)) (Just "!!!contrastin")) p "contrastin"
, BlStatement ea p Nothing (StPause ea p Nothing)
, BlComment (A (Just (last bs4e)) (Just "!!!dominic")) p "dominic"
, BlComment (A (Just (last bs4e)) (Just "!!!orchard")) p "orchard"
, BlStatement ea p Nothing (StExpressionAssign ea p (varGen "x") (intGen 42)) ]
pf5 = wrapBlocks bs5
bs5 =
[ BlComment ea p "comment 1"
, BlComment ea p "comment 2"
, BlStatement ea p Nothing (StPause ea p Nothing) ]
pf5e = wrapBlocks bs5e
bs5e =
[ BlComment (A (Just (last bs5e)) Nothing) p "comment 1"
, BlComment (A (Just (last bs5e)) Nothing) p "comment 2"
, BlStatement ea p Nothing (StPause ea p Nothing) ]