egison-5.0.0: test/Test.hs
module Main where
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans.Class (lift)
import System.Environment (getArgs)
import System.IO (hFlush, stdout)
import Test.Framework (defaultMainWithArgs)
import Test.Framework.Providers.HUnit (hUnitTestToTests)
import Test.HUnit
import Language.Egison
import Language.Egison.AST (TopExpr(..))
import Language.Egison.MathOutput
main :: IO ()
main = do
-- t <- evalRuntimeT defaultOption mathOutputTest
args <- getArgs
flip defaultMainWithArgs args . hUnitTestToTests . test $
-- Skip mathOutputTest for now due to infinite loop
map runTestCase testCases
testCases :: [FilePath]
testCases =
[ "test/syntax.egi"
, "test/primitive.egi"
, "test/lib/core/assoc.egi"
, "test/lib/core/base.egi"
, "test/lib/core/collection.egi"
, "test/lib/core/maybe.egi"
, "test/lib/core/number.egi"
, "test/lib/core/order.egi"
, "test/lib/core/random.egi"
, "test/lib/core/sort.egi"
, "test/lib/core/string.egi"
, "test/lib/math/algebra.egi"
-- , "test/lib/math/analysis.egi" -- Skipped due to infinite loop
-- , "test/lib/math/arithmetic.egi" -- Skipped due to infinite loop
-- , "test/lib/math/tensor.egi" -- Skipped due to infinite loop
-- , "sample/mahjong.egi" -- for testing pattern functions
, "sample/primes.egi" -- for testing pattern matching with infinitely many results
, "sample/sat/cdcl.egi" -- for testing a practical program using pattern matching
, "sample/poker-hands.egi"
, "sample/poker-hands-with-joker.egi"
, "sample/math/geometry/riemann-curvature-tensor-of-S2.egi" -- for testing tensor index notation
, "sample/math/geometry/riemann-curvature-tensor-of-T2.egi" -- for testing tensor index notation and math quote
, "sample/math/geometry/curvature-form.egi" -- for testing differential form
, "sample/math/number/17th-root-of-unity.egi" -- for testing rewriting of mathematical expressions
, "sample/math/geometry/hodge-laplacian-polar.egi" -- for testing "..." in tensor indices
]
runTestCase :: FilePath -> Test
runTestCase file = TestLabel file . TestCase . assertEvalM $ do
-- Print the test file name before starting
liftIO $ do
putStrLn $ "\n=== Testing: " ++ file ++ " ==="
hFlush stdout
env <- initialEnv
-- Load core libraries and math normalization library
let coreLibExprs = map Load coreLibraries
mathLibExpr = [Load "lib/math/normalize.egi"]
allLibExprs = coreLibExprs ++ mathLibExpr
env' <- evalTopExprsNoPrint env allLibExprs
-- Then load the test file
exprs <- loadFile file
evalTopExprsNoPrint env' exprs
where
assertEvalM :: EvalM a -> Assertion
assertEvalM m = fromEvalM defaultOption m >>= assertString . either show (const "")
mathOutputTest :: RuntimeM Test
mathOutputTest = do
envResult <- fromEvalT $ do
env <- initialEnv
-- Load core libraries and math normalization library
let coreLibExprs = map Load coreLibraries
mathLibExpr = [Load "lib/math/normalize.egi"]
allLibExprs = coreLibExprs ++ mathLibExpr
evalTopExprsNoPrint env allLibExprs
env <- case envResult of
Left err -> error $ "Failed to initialize environment: " ++ show err
Right e -> return e
latexTest <- mathOutputTestLatex env
return $ TestList [latexTest]
mathOutputTestLatex :: Env -> RuntimeM Test
mathOutputTestLatex env = do
TestLabel "math output: latex" . TestList <$>
mapM (\(x, y, z) -> makeTest x y z)
[ ("div", "x / y", "\\frac{x}{y}")
]
where
makeTest = makeMathOutputTest env "latex"
makeMathOutputTest :: Env -> String -> String -> String -> String -> RuntimeM Test
makeMathOutputTest env lang label expr expectedOutput = do
res <- fromEvalT (runExpr env expr)
case res of
Left _ -> return . TestCase $ assertFailure "Failed to evaluate the expression"
Right res -> return . TestCase $ assertEqual label ("#" ++ lang ++ "|" ++ expectedOutput ++ "|#") (prettyMath lang res)