{-# LANGUAGE OverloadedStrings #-}
module Main (main) where
import Control.Exception (throw)
import qualified Data.ByteString.Lazy as BSL
import Data.Either (isRight)
import Data.List.NonEmpty (NonEmpty (..))
import Data.Maybe (isJust, isNothing)
import Eval
import Golden
import Language.Dickinson.Check
import Language.Dickinson.DuplicateCheck
import Language.Dickinson.Import
import Language.Dickinson.Lexer
import Language.Dickinson.Name
import Language.Dickinson.Parser
import Language.Dickinson.Rename
import Language.Dickinson.ScopeCheck
import Language.Dickinson.Type
import Language.Dickinson.Unique
import Test.Tasty
import Test.Tasty.HUnit
import TypeCheck
main :: IO ()
main =
defaultMain $
testGroup "All tests"
[ goldenTests
, parserTests
, evalTests
, tcTests
]
parserTests :: TestTree
parserTests =
testGroup "Parser tests"
[ lexNoError "test/data/let.dck"
, parseNoError "test/data/const.dck"
, parseNoError "test/data/let.dck"
, parseNoError "test/data/nestLet.dck"
, parseNoError "lib/color.dck"
, parseNoError "lib/birds.dck"
, lexNoError "test/data/import.dck"
, lexNoError "test/data/lexDollarSign.dck"
, parseNoError "test/data/import.dck"
, detectDuplicate "test/data/multiple.dck"
, detectDuplicate "test/error/double.dck"
, detectDuplicate "test/error/tyDouble.dck"
, detectDuplicate "test/error/tyConsDouble.dck"
, lexNoError "examples/shakespeare.dck"
, lexNoError "test/data/multiStr.dck"
, parseNoError "test/data/multiStr.dck"
, parseNoError "examples/shakespeare.dck"
, detectScopeError "test/demo/improbableScope.dck"
, detectBadBranch "test/demo/sillyOption.dck"
, noScopeError "test/demo/circular.dck"
, noScopeError "test/data/adt.dck"
, detectScopeError "test/error/tyScope.dck"
, detectScopeError "test/error/constructorScope.dck"
, findPath
]
findPath :: TestTree
findPath = testCase "Finds import at correct path" $ do
res <- resolveImport ["lib", "."] (Name ("color" :| []) dummyUnique undefined)
res @?= Just "lib/color.dck"
readNoFail :: FilePath -> IO (Dickinson AlexPosn)
readNoFail = fmap (either throw id . parse) . BSL.readFile
detectBadBranch :: FilePath -> TestTree
detectBadBranch fp = testCase "Detects suspicious branch" $ do
(Dickinson _ parsed) <- readNoFail fp
assertBool fp $ isJust (checkDuplicates parsed)
detectDuplicate :: FilePath -> TestTree
detectDuplicate fp = testCase ("Detects duplicate name (" ++ fp ++ ")") $ do
(Dickinson _ parsed) <- readNoFail fp
assertBool fp $ isJust (checkMultiple parsed)
detectScopeError :: FilePath -> TestTree
detectScopeError fp = testCase "Finds scoping error" $ do
(Dickinson _ renamed) <- parseRename fp
assertBool fp $ isJust (checkScope renamed)
noScopeError :: FilePath -> TestTree
noScopeError fp = testCase "Reports valid scoping" $ do
(Dickinson _ renamed) <- parseRename fp
assertBool fp $ isNothing (checkScope renamed)
parseNoError :: FilePath -> TestTree
parseNoError fp = testCase ("Parsing doesn't fail (" ++ fp ++ ")") $ do
contents <- BSL.readFile fp
assertBool "Doesn't fail parsing" $ isRight (parse contents)
lexNoError :: FilePath -> TestTree
lexNoError fp = testCase ("Lexing doesn't fail (" ++ fp ++ ")") $ do
contents <- BSL.readFile fp
assertBool "Doesn't fail lexing" $ isRight (lexDickinson contents)
parseRename :: FilePath -> IO (Dickinson AlexPosn)
parseRename = fmap (fst . uncurry renameDickinson . either throw id . parseWithMax) . BSL.readFile