halberd-0.1.2: tests/Runner.hs
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE FlexibleInstances, OverloadedStrings #-}
import Control.Applicative
import Control.Monad
import Control.Monad.State
import Data.Char
import Data.Monoid
import Data.List.Split
import Data.Proxy
import Data.String
import Distribution.HaskellSuite
import Distribution.Simple.Compiler
import Language.Haskell.Exts.Annotated hiding (fileName)
import Language.Haskell.Names.Interfaces
import Test.Framework (defaultMain)
import Test.Framework.Providers.HUnit (testCase)
import Test.HUnit (assertEqual, Assertion)
import qualified Data.Map as Map
import qualified Distribution.ModuleName as Cabal
import Halberd.ChosenImports (ChosenImports (..))
import Halberd.Suggestions
main :: IO ()
main = do
pkgs <- concat <$> mapM (getInstalledPackages (Proxy :: Proxy NamesDB)) [UserPackageDB, GlobalPackageDB]
defaultMain [ testCase "Collect unbound" (collectUnbound pkgs)
, testCase "Resolve single option" (resolveSingleOption pkgs)
, testCase "Resolve multiple options" (resolveMultiple pkgs)
, testCase "Resolve multiple options (different order)" (resolveMultipleDifferentOrder pkgs)
]
collectUnbound :: Packages -> Assertion
collectUnbound pkgs = do
(ParseOk module_) <- parseFile "tests/input/Unbound.hs"
(unboundTypes, unboundValues) <- evalModuleT (findUnbound module_) pkgs "names" readInterface
assertEqual "Unbound types" (void <$> unboundTypes) ["M.Map", "Int8"]
assertEqual "Unbound values" (void <$> unboundValues) ["forM", "M.fromList"]
testResolution :: FilePath -> ChosenImports -> Packages -> Assertion
testResolution fileName expectedImports pkgs = do
(ParseOk module_) <- parseFile fileName
suggestions <- evalModuleT (suggestedImports module_) pkgs "names" readInterface
let (newSuggestions, imports) = runState (resolveSuggestions suggestions) mempty
assertEqual "resolved suggestions" [] newSuggestions
assertEqual "chosen imports" expectedImports imports
resolveSingleOption :: Packages -> Assertion
resolveSingleOption = testResolution "tests/input/ResolveSingle.hs"
ChosenImports { qualifieds = Map.fromList []
, unqualifieds = Map.fromList [("Control.Applicative", ["pure"])]
}
resolveMultiple :: Packages -> Assertion
resolveMultiple = testResolution "tests/input/ResolveMultiple.hs"
ChosenImports { qualifieds = Map.fromList []
, unqualifieds = Map.fromList [("Control.Applicative", ["<$>", "pure"])]
}
resolveMultipleDifferentOrder :: Packages -> Assertion
resolveMultipleDifferentOrder = testResolution "tests/input/ResolveMultipleDifferentOrder.hs"
ChosenImports { qualifieds = Map.fromList []
, unqualifieds = Map.fromList [("Control.Applicative", ["<$>", "pure"])]
}
-- Some instances to make it easier to write down expected values in
-- assertions.
instance IsString (QName ()) where
fromString str =
let parts = splitOn "." str
in case parts of
[nm] -> UnQual () (fromString nm)
[qual,nm] -> Qual () (fromString qual) (fromString nm)
_ -> error "Too many dots in IsString Name."
instance IsString (ModuleName ()) where
fromString = ModuleName ()
instance IsString (Name ()) where
fromString str =
if (isAlpha (head str) || head str == '_')
then Ident () str
else Symbol () str
instance IsString Cabal.ModuleName where
fromString = Cabal.fromString