{-# LANGUAGE GADTs #-} module Tests_03(runTests, boolTests) where import Template_03(prodList, squareSecond, List(..), eval, convert, normalize, listToExpr, Expr(..)) import Test.LeanCheck import Data.List ( sort ) -- Generic Setup data Test = forall a. Testable a => Test String a testGen f1 f2 f3 g1 g2 g3 x = (f3 . f2 . f1) x == (g3 . g2 . g1) x runTests = flip mapM_ tests (\ (Test name t) -> putStrLn ("running " ++ name ++ "-tests") >> checkFor 1000 t) -- Tests for this week instance Listable List where tiers = cons0 Empty \/ cons2 Cons toList Empty = [] toList (Cons x xs) = x : toList xs prodTest :: List -> Bool prodTest = testGen toList (foldr (*) 1) id id prodList id squareTest :: List -> Bool squareTest l = let xs = toList l ys = toList (squareSecond l) requests = id : (^2) : requests in length xs == length ys && and (zipWith3 ( \ x y f -> f x == y) xs ys requests) instance Listable Expr where tiers = cons1 Number \/ cons1 Negate \/ cons2 Plus convertTestEval :: Expr -> Bool convertTestEval e = eval (convert e) == eval e noNegIntegers :: Expr -> Bool noNegIntegers (Number x) = x >= 0 noNegIntegers (Negate e) = noNegIntegers e noNegIntegers (Plus e1 e2) = noNegIntegers e1 && noNegIntegers e2 convertTestNoNegNumbers :: Expr -> Bool convertTestNoNegNumbers e = noNegIntegers (convert e) normalizeTestEval :: Expr -> Bool normalizeTestEval e = eval (normalize e) == eval e normalizeTestNoNegNumbers :: Expr -> Bool normalizeTestNoNegNumbers e = noNegIntegers (normalize e) negateOnlyAboveLeafNodes :: Expr -> Bool negateOnlyAboveLeafNodes (Negate (Number x)) = True negateOnlyAboveLeafNodes (Number x) = True negateOnlyAboveLeafNodes (Plus e1 e2) = negateOnlyAboveLeafNodes e1 && negateOnlyAboveLeafNodes e2 negateOnlyAboveLeafNodes (Negate _) = False normalizeTestNegateOnlyAboveLeafNodes :: Expr -> Bool normalizeTestNegateOnlyAboveLeafNodes e = negateOnlyAboveLeafNodes (normalize e) listToExprTestEval :: List -> Bool listToExprTestEval xs = eval (listToExpr xs) == sum (toList xs) extractNumbers :: Expr -> [Integer] extractNumbers (Negate (Number x)) = [-x] extractNumbers (Number x) = [x] extractNumbers (Plus e1 e2) = extractNumbers e1 ++ extractNumbers e2 listToExprTestExprContainsListNumbers :: List -> Bool listToExprTestExprContainsListNumbers Empty = extractNumbers (listToExpr Empty) == [0] listToExprTestExprContainsListNumbers xs = sort (extractNumbers (listToExpr xs)) == sort (toList xs) listToExprTestNoNegNumbers :: List -> Bool listToExprTestNoNegNumbers xs = noNegIntegers (listToExpr xs) tests :: [Test] tests = [ Test "prodList" prodTest, Test "squareSecond" squareTest, Test "convertEval" convertTestEval, Test "convertNoNegNumbers" convertTestNoNegNumbers, Test "normalizeEval" normalizeTestEval, Test "normalizeNoNegNumbers" normalizeTestNoNegNumbers, Test "normalizeNegateOnlyAboveLeafNodes" normalizeTestNegateOnlyAboveLeafNodes, Test "listToExprEval" listToExprTestEval, Test "listToExprExprContainsListNumbers" listToExprTestExprContainsListNumbers, Test "listToExprNoNegNumbers" listToExprTestNoNegNumbers ] boolTests :: [(String, Bool)] boolTests = map (\ (Test n t) -> (n, holds 1000 t)) tests