Carp/test/Spec.hs
2017-06-26 11:15:03 +02:00

195 lines
6.3 KiB
Haskell

import Test.HUnit
import qualified Data.Map as Map
import qualified Data.Set as Set
import Constraints
import Types
import Obj
import Parsing
import Infer
import Eval
main :: IO ()
main = do _ <- runTestTT (groupTests "Constraints" testConstraints)
_ <- runTestTT (groupTests "Memory Management" testMemoryManagement)
return ()
groupTests :: String -> [Test] -> Test
groupTests label testCases =
TestList (zipWith TestLabel (map ((\s -> label ++ " Test " ++ s) . show) [1..]) testCases)
-- | Helper functions for testing unification of Constraints
isUnificationFailure :: Either UnificationFailure TypeMappings -> Bool
isUnificationFailure (Left _) = True
isUnificationFailure (Right _) = False
assertUnificationFailure :: [Constraint] -> Test
assertUnificationFailure constraints = TestCase $
assertBool "Failure" (isUnificationFailure (solve constraints))
assertSolution :: [Constraint] -> [(String, Ty)] -> Test
assertSolution constraints solution = TestCase $
assertEqual "Solution" (Right (Map.fromList solution)) (solve constraints)
-- | A dummy XObj
x = XObj External Nothing Nothing
-- | Some type variables
t0 = VarTy "t0"
t1 = VarTy "t1"
t2 = VarTy "t2"
t3 = VarTy "t3"
-- | Test constraints
testConstraints = [testConstr1, testConstr2, testConstr3, testConstr4, testConstr5
,testConstr6, testConstr7, testConstr8, testConstr9, testConstr10
,testConstr11, testConstr12, testConstr13
,testConstr20, testConstr21, testConstr22, testConstr23, testConstr24
,testConstr30, testConstr31, testConstr32, testConstr33
]
testConstr1 = assertUnificationFailure
[Constraint FloatTy IntTy x x]
testConstr2 = assertSolution
[Constraint IntTy t0 x x]
[("t0", IntTy)]
testConstr3 = assertSolution
[Constraint t0 IntTy x x]
[("t0", IntTy)]
testConstr4 = assertSolution
[Constraint t0 t1 x x, Constraint t0 IntTy x x]
[("t0", IntTy), ("t1", IntTy)]
testConstr5 = assertSolution
[Constraint t0 t1 x x, Constraint t1 IntTy x x]
[("t0", IntTy), ("t1", IntTy)]
testConstr6 = assertSolution
[Constraint t0 t1 x x, Constraint t1 t3 x x, Constraint t2 IntTy x x, Constraint t3 IntTy x x]
[("t0", IntTy), ("t1", IntTy), ("t2", IntTy), ("t3", IntTy)]
testConstr7 = assertUnificationFailure
[Constraint t0 IntTy x x, Constraint t0 FloatTy x x]
testConstr8 = assertSolution
[Constraint t0 IntTy x x, Constraint t0 t0 x x]
[("t0", IntTy)]
testConstr9 = assertSolution
[Constraint t0 IntTy x x, Constraint t0 t1 x x]
[("t0", IntTy), ("t1", IntTy)]
testConstr10 = assertSolution
[Constraint (PointerTy (VarTy "a")) (PointerTy (VarTy "b")) x x]
[("a", (VarTy "a")), ("b", (VarTy "a"))]
testConstr11 = assertSolution
[Constraint (PointerTy (VarTy "a")) (PointerTy (StructTy "Monkey" [])) x x]
[("a", (StructTy "Monkey" []))]
testConstr12 = assertSolution
[Constraint t1 (PointerTy (StructTy "Array" [IntTy])) x x
,Constraint t1 (PointerTy t2) x x]
[("t1", (PointerTy (StructTy "Array" [IntTy])))
,("t2", (StructTy "Array" [IntTy]))]
testConstr13 = assertSolution
[Constraint t1 CharTy x x
,Constraint t1 CharTy x x]
[("t1", CharTy)]
-- -- Should collapse type variables into minimal set:
-- testConstr10 = assertSolution
-- [Constraint t0 t1 x x, Constraint t1 t2 x x, Constraint t2 t3 x x]
-- [("t0", VarTy "t0"), ("t1", VarTy "t0"), ("t2", VarTy "t0")]
-- m7 = solve ([Constraint t1 t2 x x, Constraint t0 t1 x x])
-- Struct types
testConstr20 = assertSolution
[Constraint t0 (StructTy "Vector" [t1]) x x
,Constraint t0 (StructTy "Vector" [IntTy]) x x]
[("t0", (StructTy "Vector" [IntTy])), ("t1", IntTy)]
testConstr21 = assertSolution
[Constraint t1 (StructTy "Array" [t2]) x x
,Constraint t1 (StructTy "Array" [t3]) x x
,Constraint t3 BoolTy x x]
[("t1", (StructTy "Array" [BoolTy]))
,("t2", BoolTy)
,("t3", BoolTy)]
testConstr22 = assertSolution
[Constraint t1 (StructTy "Array" [t2]) x x
,Constraint t2 (StructTy "Array" [t3]) x x
,Constraint t3 FloatTy x x]
[("t1", (StructTy "Array" [(StructTy "Array" [FloatTy])]))
,("t2", (StructTy "Array" [FloatTy]))
,("t3", FloatTy)]
testConstr23 = assertUnificationFailure
[Constraint (StructTy "Array" [t1]) (StructTy "Array" [t2]) x x
,Constraint t1 IntTy x x
,Constraint t2 FloatTy x x]
testConstr24 = assertUnificationFailure
[Constraint t2 FloatTy x x
,Constraint t1 IntTy x x
,Constraint (StructTy "Array" [t1]) (StructTy "Array" [t2]) x x]
-- m9 = solve [Constraint (StructTy "Vector" [IntTy]) (StructTy "Vector" [t1]) x x]
-- m10 = solve [Constraint (StructTy "Vector" [t1]) (StructTy "Vector" [t2]) x x]
-- Func types
testConstr30 = assertSolution
[Constraint t2 (FuncTy [t0] t1) x x
,Constraint t2 (FuncTy [IntTy] BoolTy) x x]
[("t0", IntTy), ("t1", BoolTy), ("t2", (FuncTy [IntTy] BoolTy))]
testConstr31 = assertSolution
[Constraint (FuncTy [t0] t1) (FuncTy [IntTy] BoolTy) x x]
[("t0", IntTy), ("t1", BoolTy)]
testConstr32 = assertSolution
[Constraint t0 (FuncTy [IntTy] BoolTy) x x]
[("t0", (FuncTy [IntTy] BoolTy))]
testConstr33 = assertSolution
[Constraint t1 (FuncTy [t2] IntTy) x x
,Constraint t1 (FuncTy [t3] IntTy) x x
,Constraint t3 BoolTy x x]
[("t1", (FuncTy [BoolTy] IntTy))
,("t2", BoolTy)
,("t3", BoolTy)]
-- | Test memory management
testMemoryManagement = [testMem1]
testEnv :: Env
testEnv = Env { envBindings = bs, envParent = Nothing, envModuleName = Nothing, envImports = [], envMode = ExternalEnv }
where bs = Map.fromList []
assertMem :: String -> [Deleter] -> Test
assertMem code deleters =
let Right [parsed] = parse code
Right expanded = expandAll testEnv parsed
xobjFullSymbols = setFullyQualifiedSymbols testEnv expanded
Right (ann : _) = annotate testEnv xobjFullSymbols
Just i = info ann
in TestCase $ assertEqual "Memory" (infoDelete i) (Set.fromList deleters)
testMem1 = assertMem "(defn f [] (let [s \"HELLO\"] 12345))" []
-- case expandAll env xobj of
-- Left err -> executeCommand ctx (ReplMacroError (show err))
-- Right expanded ->
-- let xobjFullPath = setFullyQualifiedDefn expanded (SymPath pathStrings (getName xobj))
-- xobjFullSymbols = setFullyQualifiedSymbols innerEnv xobjFullPath
-- in case annotate env xobjFullSymbols of