retrie-0.1.0.0: tests/GroundTerms.hs
-- Copyright (c) Facebook, Inc. and its affiliates.
--
-- This source code is licensed under the MIT license found in the
-- LICENSE file in the root directory of this source tree.
--
{-# LANGUAGE OverloadedStrings #-}
module GroundTerms
( getFocusTests
, groundTermsTest
) where
import Control.Monad
import Control.Monad.IO.Class
import Data.Default
import qualified Data.HashSet as HashSet
import Data.Text (Text)
import Retrie.CPP
import Retrie.ExactPrint
import Retrie.GroundTerms
import Retrie.Monad
import Retrie.Options
import Retrie.Rewrites
import Retrie.Types
import Retrie.Universe
import Test.HUnit
groundTermsTest :: Test
groundTermsTest = TestLabel "ground terms" $ TestList
[ gtTest "map"
""
[Adhoc "forall f g xs. map f (map g xs) = map (f . g) xs"]
[["map"]]
[("", "grep -R --include=\"*.hs\" -l 'map' ~/si_sigma")]
, gtTest "isSpace"
""
[Adhoc "forall xs. or (map isSpace xs) = any isSpace xs"]
[["or", "map isSpace"]]
[("", "grep -R --include=\"*.hs\" -l 'or' ~/si_sigma | xargs grep -l 'map[[:space:]]\\+isSpace'")]
, gtTest "MyType"
"type MyType a = MyOtherType a"
[TypeForward "Test.MyType"]
[["MyType"]]
[("", "grep -R --include=\"*.hs\" -l 'MyType' ~/si_sigma")]
]
gtTest
:: String
-> Text
-> [RewriteSpec]
-> [[String]]
-> [(String, String)]
-> Test
gtTest lbl contents specs expected expectedCmds =
TestLabel ("groundTerms: " ++ lbl) $ TestCase $ do
-- since we 'zip' below
assertEqual "length of specs and expected ground terms"
(length specs)
(length expected)
assertEqual "length of expected ground terms and expected commands"
(length expected)
(length expectedCmds)
rrs <-
parseRewriteSpecs
(\_ -> parseCPP (parseContent def "Test") contents)
def
specs
let gtss = map groundTerms rrs
assertEqual "groundTerms does not give expected term set"
(HashSet.fromList $ map HashSet.fromList expected)
(HashSet.fromList gtss) -- compare hashsets to avoid ordering issues
forM_ (zip gtss expectedCmds) $ \(gts, expectedCmd) ->
case buildGrepChain "~/si_sigma" gts [] of
Left _ -> assertFailure "gtTest: Left"
Right (i, c) ->
assertEqual "buildGrepChain did not give expected command"
expectedCmd
(i, unwords c)
getFocusTests :: IO [Test]
getFocusTests = do
rrs1 <- parseAdhocs def ["forall xs. or (map isSpace xs) = any isSpace xs"]
rrs2 <- parseAdhocs def ["forall f g xs. map f (map g xs) = map (f . g) xs"]
let
-- compare hashsets to avoid ordering issues
terms = HashSet.fromList $ map groundTerms rrs1
return
[ TestLabel caseName $ TestCase $
assertEqual caseName expected $
HashSet.fromList $ getGroundTerms retrie
| (caseName, retrie, expected) <-
[ ("apply", apply rrs1, terms)
, ("apply twice", apply rrs1 >> apply rrs2, terms)
, ("query", () <$ query rrs1, terms)
, ("focus", focus rrs1, terms)
, ("focus empty", focus ([] :: [Rewrite Universe]), HashSet.empty)
, ("focus empty next", focus ([] :: [Rewrite Universe]) >> apply rrs1, terms)
-- We should generate no ground terms if no iteration happens
, ("iterateR 0", iterateR 0 (apply rrs1), HashSet.empty)
, ("iterateR 0 then apply", iterateR 0 (apply rrs2) >> apply rrs1, terms)
, ("iterateR 5", iterateR 5 (apply rrs1), terms)
-- test that adding imports first (calling 'tell') doesn't block us
-- from finding ground terms
, ("addImports", addImports mempty >> apply rrs1, terms)
, ("ifChanged normal", ifChanged (apply rrs1) (apply rrs2), terms)
-- the pathological case: changed but no ground terms
, ("ifChanged weird", ifChanged (addImports mempty) (apply rrs1), terms)
, ("liftIO", liftIO (return ()) >> apply rrs1, HashSet.empty)
, ("liftIO after focus", focus rrs1 >> liftIO (return ()) >> apply rrs2, terms)
]
]