express-1.0.14: test/Test.hs
-- |
-- Module : Test
-- Copyright : (c) 2019-2024 Rudy Matela
-- License : 3-Clause BSD (see the file LICENSE)
-- Maintainer : Rudy Matela <rudy@matela.com.br>
--
-- This module defines utilities used to test "Data.Express".
--
-- It should never be exported in @ express.cabal @.
module Test
( module Test.LeanCheck
, module Test.LeanCheck.Derive
, module Test.LeanCheck.Utils
, module Data.Express.Fixtures
, module Data.Express.Utils.List
, module Data.Express.Utils.Typeable
, module Test.ListableExpr
, module Data.Maybe
, module Data.Either
, module Data.Monoid
, mainTest
, tyBool
, tyInt
, tyChar
, tyInts
, tyIntToInt
, allRules
, boolRules
, intRules
, listRules
)
where
import System.Environment (getArgs, getProgName)
import System.Exit (exitFailure)
import Data.List (elemIndices)
import Data.Typeable (TypeRep, typeOf)
import Data.Maybe
import Data.Either
import Data.Monoid
import Test.LeanCheck
import Test.LeanCheck.Utils
import Test.LeanCheck.Derive
import Test.ListableExpr
import Data.Express.Fixtures
import Data.Express.Utils.List
import Data.Express.Utils.Typeable
reportTests :: String -> [Bool] -> IO ()
reportTests s tests =
case elemIndices False tests of
[] -> putStrLn $ s ++ ": tests passed"
is -> do putStrLn (s ++ ": failed tests:" ++ show is)
exitFailure
getMaxTestsFromArgs :: Int -> IO Int
getMaxTestsFromArgs n = do
as <- getArgs
return $ case as of
(s:_) -> read s
_ -> n
mainTest :: (Int -> [Bool]) -> Int -> IO ()
mainTest tests n' = do
pn <- getProgName
n <- getMaxTestsFromArgs n'
reportTests pn (tests n)
tyBool :: TypeRep
tyBool = typeOf (undefined :: Bool)
tyInt :: TypeRep
tyInt = typeOf (undefined :: Int)
tyChar :: TypeRep
tyChar = typeOf (undefined :: Char)
tyInts :: TypeRep
tyInts = typeOf (undefined :: [Int])
tyIntToInt :: TypeRep
tyIntToInt = typeOf (undefined :: Int -> Int)
-- |
-- To be used when testing or benchmarking 'Triexpr'
allRules :: [(Expr,Expr)]
allRules = boolRules ++ intRules ++ listRules ++ boolintRules ++ funRules
boolRules :: [(Expr,Expr)]
boolRules =
[ id' pp -=- pp
, pp -&&- pp -=- pp
, pp -||- pp -=- pp
, pp -&&- qq -=- qq -&&- pp
, pp -||- qq -=- qq -||- pp
, not' (not' pp) -=- pp
, pp -&&- true -=- pp
, true -&&- pp -=- pp
, pp -&&- false -=- false
, false -&&- pp -=- false
, pp -||- true -=- true
, true -||- pp -=- true
, pp -||- false -=- pp
, false -||- pp -=- pp
, pp -&&- not' pp -=- false
, pp -||- not' pp -=- true
, not' pp -&&- pp -=- false
, not' pp -||- pp -=- true
, (pp -&&- qq) -&&- rr -=- pp -&&- (qq -&&- rr)
, (pp -||- qq) -||- rr -=- pp -||- (qq -||- rr)
, not' (pp -&&- qq) -=- not' pp -||- not' qq
, not' (pp -||- qq) -=- not' pp -&&- not' qq
, not' false -=- true
, not' true -=- false
, not' (not' pp -&&- not' qq) -=- (pp -||- qq)
, not' (not' pp -||- not' qq) -=- (pp -&&- qq)
, pp -&&- not' (pp -&&- qq) -=- pp -&&- not' qq
--, pp -=- pp
]
intRules :: [(Expr,Expr)]
intRules =
[ id' xx -=- xx
, abs' (abs' xx) -=- abs' xx
, xx -+- zero -=- xx
, zero -+- xx -=- xx
, xx -*- one -=- xx
, one -*- xx -=- xx
, xx -*- zero -=- zero
, zero -*- xx -=- zero
, xx -+- yy -=- yy -+- xx
, xx -*- yy -=- yy -*- xx
, (xx -+- yy) -+- zz -=- xx -+- (yy -+- zz)
, (xx -*- yy) -*- zz -=- xx -*- (yy -*- zz)
, (xx -+- xx) -*- yy -=- xx -*- (yy -+- yy)
, xx -*- (yy -+- one) -=- xx -+- xx -*- yy
, (xx -+- one) -*- yy -=- xx -+- xx -*- yy
, xx -*- (yy -+- zz) -=- xx -*- yy -+- xx -*- zz
, (xx -+- yy) -*- zz -=- xx -*- zz -+- yy -*- zz
, negate' (negate' xx) -=- xx
, xx -+- negate' xx -=- zero
, negate' xx -+- xx -=- zero
, abs' (negate' xx) -=- abs' xx
, two -*- xx -=- xx -+- xx
, xx -*- two -=- xx -+- xx
, three -*- xx -=- xx -+- (xx -+- xx)
, xx -*- three -=- xx -+- (xx -+- xx)
, four -*- xx -=- xx -+- (xx -+- (xx -+- xx))
, xx -*- four -=- xx -+- (xx -+- (xx -+- xx))
, abs' (xx -*- xx) -=- xx -*- xx
, abs' xx -*- abs' yy -=- abs' (xx -*- yy)
, abs' xx -*- abs' xx -=- abs' (xx -+- xx)
, abs' (abs' xx -+- abs' yy) -=- abs' xx -+- abs' yy
, abs' (xx -+- xx) -*- yy -=- abs' xx -*- yy -+- abs' xx -*- yy
, abs' xx -*- signum' xx -=- xx
, signum' xx -*- abs' xx -=- xx
--, xx -=- xx
]
listRules :: [(Expr,Expr)]
listRules =
[ id' xxs -=- xxs
, head' (xx -:- xxs) -=- xx
, tail' (xx -:- xxs) -=- xxs
, xxs -++- nil -=- xxs
, nil -++- xxs -=- xxs
, unit xx -++- xxs -=- xx -:- xxs
, (xx -:- xxs) -++- yys -=- xx -:- (xxs -++- yys)
, (xxs -++- yys) -++- zzs -=- xxs -++- (yys -++- zzs)
-- insertsort stuff
, elem' xx (sort' xxs) -=- elem' xx xxs
, elem' xx (insert' yy xxs) -=- elem' xx (yy -:- xxs)
, sort' (sort' xxs) -=- sort' xxs
, insert' xx nil -=- unit xx
, sort' (xxs -++- yys) -=- sort' (yys -++- xxs)
, sort' (insert' xx xxs) -=- insert' xx (sort' xxs)
, sort' (xx -:- xxs) -=- insert' xx (sort' xxs)
, sort' (xxs -++- sort' yys) -=- sort' (xxs -++- yys)
, sort' (sort' xxs -++- yys) -=- sort' (xxs -++- yys)
, insert' xx (insert' yy xxs) -=- insert' yy (insert' xx xxs)
, insert' xx (xx -:- xxs) -=- xx -:- xx -:- xxs
, insert' xx (unit yy) -=- insert' yy (unit xx)
-- length stuff
, length' (xx -:- xxs) -=- length' (yy -:- xxs)
, length' (xxs -++- yys) -=- length' (yys -++- xxs)
, length' (xx -:- yy -:- xxs) -=- length' (zz -:- xx' -:- xxs)
, length' (xx -:- (xxs -++- yys)) -=- length' (yy -:- (yys -++- xxs))
, length' (xxs -++- (yys -++- zzs)) -=- length' (xxs -++- (zzs -++- yys))
]
boolintRules :: [(Expr,Expr)]
boolintRules =
[ not' (odd' xx) -=- even' xx
, not' (even' xx) -=- odd' xx
, (xx -==- xx) -=- true
, (xx -/=- xx) -=- false
, (pp -==- pp) -=- true
, (pp -/=- pp) -=- false
]
funRules :: [(Expr,Expr)]
funRules =
[ ff (gg xx) -=- (ffE -.- ggE) :$ xx
, map' idE xxs -=- xxs
, map' (ffE -.- ggE) xxs -=- map' ffE (map' ggE xxs)
, ffE -.- idE -=- ffE
, idE -.- ffE -=- ffE
, (ffE -.- ggE) -.- hhE -=- ffE -.- (ggE -.- hhE)
, notE -.- notE -=- idBool
]
(-=-) :: Expr -> Expr -> (Expr,Expr)
e1 -=- e2 = (e1, e2)
infix 0 -=-