120 lines
3.5 KiB
Haskell
120 lines
3.5 KiB
Haskell
module APL.Eval_Tests (tests) where
|
|
|
|
import APL.AST (Exp (..))
|
|
import APL.Eval (Error, Val (..), eval, runEval)
|
|
import Test.Tasty (TestTree, testGroup)
|
|
import Test.Tasty.HUnit (testCase, (@?=))
|
|
|
|
eval' :: Exp -> ([String], Either Error Val)
|
|
eval' = runEval . eval
|
|
|
|
evalTests :: TestTree
|
|
evalTests =
|
|
testGroup
|
|
"EValuation"
|
|
[ testCase "Add" $
|
|
eval' (Add (CstInt 2) (CstInt 5))
|
|
@?= ([], Right (ValInt 7)),
|
|
--
|
|
testCase "Add (wrong type)" $
|
|
eval' (Add (CstInt 2) (CstBool True))
|
|
@?= ([], Left "Non-integer operand"),
|
|
--
|
|
testCase "Sub" $
|
|
eval' (Sub (CstInt 2) (CstInt 5))
|
|
@?= ([], Right (ValInt (-3))),
|
|
--
|
|
testCase "Div" $
|
|
eval' (Div (CstInt 7) (CstInt 3))
|
|
@?= ([], Right (ValInt 2)),
|
|
--
|
|
testCase "Div0" $
|
|
eval' (Div (CstInt 7) (CstInt 0))
|
|
@?= ([], Left "Division by zero"),
|
|
--
|
|
testCase "Pow" $
|
|
eval' (Pow (CstInt 2) (CstInt 3))
|
|
@?= ([], Right (ValInt 8)),
|
|
--
|
|
testCase "Pow0" $
|
|
eval' (Pow (CstInt 2) (CstInt 0))
|
|
@?= ([], Right (ValInt 1)),
|
|
--
|
|
testCase "Pow negative" $
|
|
eval' (Pow (CstInt 2) (CstInt (-1)))
|
|
@?= ([], Left "Negative exponent"),
|
|
--
|
|
testCase "Eql (false)" $
|
|
eval' (Eql (CstInt 2) (CstInt 3))
|
|
@?= ([], Right (ValBool False)),
|
|
--
|
|
testCase "Eql (true)" $
|
|
eval' (Eql (CstInt 2) (CstInt 2))
|
|
@?= ([], Right (ValBool True)),
|
|
--
|
|
testCase "If" $
|
|
eval' (If (CstBool True) (CstInt 2) (Div (CstInt 7) (CstInt 0)))
|
|
@?= ([], Right (ValInt 2)),
|
|
--
|
|
testCase "Let" $
|
|
eval' (Let "x" (Add (CstInt 2) (CstInt 3)) (Var "x"))
|
|
@?= ([], Right (ValInt 5)),
|
|
--
|
|
testCase "Let (shadowing)" $
|
|
eval'
|
|
( Let
|
|
"x"
|
|
(Add (CstInt 2) (CstInt 3))
|
|
(Let "x" (CstBool True) (Var "x"))
|
|
)
|
|
@?= ([], Right (ValBool True)),
|
|
--
|
|
testCase "Lambda/Apply" $
|
|
eval'
|
|
(Apply (Lambda "x" (Mul (Var "x") (Var "x"))) (CstInt 4))
|
|
@?= ([], Right (ValInt 16)),
|
|
--
|
|
testCase "TryCatch" $
|
|
eval'
|
|
(TryCatch (Div (CstInt 7) (CstInt 0)) (CstBool True))
|
|
@?= ([], Right (ValBool True)),
|
|
--
|
|
testCase "PrintInt" $
|
|
eval'
|
|
(Print "Test" (CstInt 3))
|
|
@?= (["Test: 3"], Right (ValInt 3)),
|
|
--
|
|
testCase "PrintBool" $
|
|
eval'
|
|
(Print "Test" (CstBool True))
|
|
@?= (["Test: True"], Right (ValBool True)),
|
|
--
|
|
testCase "PrintFun" $
|
|
eval'
|
|
(Print "Test" (Lambda "x" (Mul (Var "x") (Var "x"))))
|
|
@?= (["Test: #<fun>"], Right (ValFun [] "x" (Mul (Var "x") (Var "x")))),
|
|
--
|
|
testCase "Print (Multiple)" $
|
|
eval'
|
|
(Let "x" (Print "Test1" $ CstInt 2) (Print "Test2" $ CstInt 3))
|
|
@?= (["Test1: 2", "Test2: 3"], Right (ValInt 3)),
|
|
--
|
|
testCase "KvPut" $
|
|
eval'
|
|
(KvPut (CstInt 1) (CstInt 2))
|
|
@?= ([], Right (ValInt 2)),
|
|
--
|
|
testCase "KvGet" $
|
|
eval'
|
|
(Let "x" (KvPut (CstInt 0) (CstBool True)) (Let "y" (KvPut (CstInt 0) (CstBool False)) (KvGet (CstInt 0))))
|
|
@?= ([], Right (ValBool False)),
|
|
--
|
|
testCase "TryCatch (key-value)" $
|
|
eval'
|
|
(TryCatch (Let "x" (KvPut (CstInt 5) (CstInt 1)) (Var "y")) (KvGet (CstInt 5)))
|
|
@?= ([], Right (ValInt 1))
|
|
]
|
|
|
|
tests :: TestTree
|
|
tests = testGroup "APL" [evalTests]
|