packages feed

zuramaru-0.1.0.0: test/tasty/Maru/Eval/FuncTest.hs

{-# LANGUAGE OverloadedStrings #-}

module Maru.Eval.FuncTest where

import Control.Exception.Safe (SomeException)
import Maru.Type (SExpr(..), MaruEnv, SimplificationSteps)
import MaruTest (shouldBeEvaluatedTo)
import System.IO.Silently (silence)
import Test.Tasty (TestTree)
import Test.Tasty.HUnit (testCase, (@?=), Assertion, assertFailure)
import qualified Maru.Eval as Eval

test_evaluator_calculates_pure_functions :: [TestTree]
test_evaluator_calculates_pure_functions =
  [ testCase "(+ 2 3) to 5" $
      Cons (AtomSymbol "+") (Cons (AtomInt 2) (Cons (AtomInt 3) Nil))
      !?= AtomInt 5
  , testCase "(+ 2 (* 3 4)) to 14" $
      Cons (AtomSymbol "+") (Cons (AtomInt 2) (Cons (Cons (AtomSymbol "*") (Cons (AtomInt 3) (Cons (AtomInt 4) Nil))) Nil))
      !?= AtomInt 14
  , testCase "(+ 1 2 3) to 6" $
      Cons (AtomSymbol "+") (Cons (AtomInt 1)
                            (Cons (AtomInt 2)
                            (Cons (AtomInt 3)
                            Nil)))
      !?= AtomInt 6
  ]


test_evaluator_evaluates_four_arith_operations :: [TestTree]
test_evaluator_evaluates_four_arith_operations =
  [ testCase "`+` adds the tail numeric elements to the head numeric element" $ do
      "(+ 1 2 3)" `shouldBeEvaluatedTo` "6"
      "(+ 1)" `shouldBeEvaluatedTo` "1"
  , testCase "`-` substracts the tail numeric elements from the head numeric element" $ do
      "(- 10 2 3)" `shouldBeEvaluatedTo` "5"
      "(- 0 2 3)" `shouldBeEvaluatedTo` "-5"
      "(- 10)" `shouldBeEvaluatedTo` "-10"
  , testCase "`*` adds the numeric element to itself the {element} times foldly" $
      "(* 2 3 4)" `shouldBeEvaluatedTo` "24"
  , testCase "`/` gets the inverse value of the integral element foldly" $ do
      "(/ 4 2 2)" `shouldBeEvaluatedTo` "1"
  ]


(!?=) :: SExpr -> SExpr -> Assertion
origin !?= expected = do
  result <- evalInitSilently origin
  case result of
    Left e -> assertFailure $ "An error is caught: " ++ show e
    Right (actual, _, _) -> actual @?= expected
  where
    evalInitSilently :: SExpr -> IO (Either SomeException (SExpr, MaruEnv, SimplificationSteps))
    evalInitSilently = silence . Eval.eval Eval.initialEnv