stgi-1: test/Testsuite/Test/Prelude/Number.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Test.Prelude.Number (tests) where
import Data.Monoid
import Data.Text (Text)
import Stg.Language
import Stg.Marshal
import Stg.Parser.QuasiQuoter
import qualified Stg.Prelude as Stg
import Test.Machine.Evaluate.TestTemplates.MarshalledValue
import Test.Orphans ()
import Test.QuickCheck.Modifiers
import Test.Tasty
tests :: TestTree
tests = testGroup "Number"
[ testGroup "Comparison"
[ testEq
, testLt
, testLeq
, testGt
, testGeq
, testNeq ]
, testGroup "Arithmetic"
[ testAdd
, testSub
, testMul
, testDiv
, testMod ]
, testMin
, testMax ]
testEq, testLt, testLeq, testGt, testGeq, testNeq :: TestTree
testEq = testComparison "==" (==) (Stg.eq_Int <> [stg| stgFunc = \ -> eq_Int |])
testLt = testComparison "<" (<) (Stg.lt_Int <> [stg| stgFunc = \ -> lt_Int |])
testLeq = testComparison "<=" (<=) (Stg.leq_Int <> [stg| stgFunc = \ -> leq_Int |])
testGt = testComparison ">" (>) (Stg.gt_Int <> [stg| stgFunc = \ -> gt_Int |])
testGeq = testComparison ">=" (>=) (Stg.geq_Int <> [stg| stgFunc = \ -> geq_Int |])
testNeq = testComparison "/=" (/=) (Stg.neq_Int <> [stg| stgFunc = \ -> neq_Int |])
-- | Test an Integer comparison operator
testComparison
:: Text -- ^ Test name
-> (Integer -> Integer -> Bool) -- ^ Comparison operator
-> Program -- ^ STG definition of the comparison function, named "stgFunc"
-> TestTree
testComparison name haskellRef stgFuncDef = marshalledValueTest defSpec
{ testName = name
, sourceSpec = \(x, y) -> MarshalSourceSpec
{ resultVar = "main"
, expectedValue = haskellRef x y
, source = mconcat
[ toStg "x" x
, toStg "y" y
, stgFuncDef
, [stg| main = \ => stgFunc x y |] ]}}
testAdd, testSub, testMul, testDiv, testMod :: TestTree
testAdd = testArithmetic "+" (+) (Stg.add <> [stg| stgFunc = \ -> add |])
testSub = testArithmetic "-" (-) (Stg.sub <> [stg| stgFunc = \ -> sub |])
testMul = testArithmetic "*" (*) (Stg.mul <> [stg| stgFunc = \ -> mul |])
testDiv = testArithmetic "div" div (Stg.div <> [stg| stgFunc = \ -> div |])
testMod = testArithmetic "mod" mod (Stg.mod <> [stg| stgFunc = \ -> mod |])
-- | Test an arithmetic operator
testArithmetic
:: Text -- ^ Test name
-> (Integer -> Integer -> Integer) -- ^ Arithmetic operator
-> Program -- ^ STG definition of the comparison function, named "stgFunc"
-> TestTree
testArithmetic name haskellRef stgFuncDef = marshalledValueTest defSpec
{ testName = name
, sourceSpec = \(x, NonZero y) -> MarshalSourceSpec
{ resultVar = "main"
, expectedValue = haskellRef x y
, source = mconcat
[ toStg "x" x
, toStg "y" y
, stgFuncDef
, [stg| main = \ => stgFunc x y |] ]}}
testMin :: TestTree
testMin = marshalledValueTest defSpec
{ testName = "min"
, sourceSpec = \(x, y :: Integer) -> MarshalSourceSpec
{ resultVar = "main"
, expectedValue = min x y
, source = mconcat
[ toStg "x" x
, toStg "y" y
, Stg.min
, [stg| main = \ => min x y |] ]}}
testMax :: TestTree
testMax = marshalledValueTest defSpec
{ testName = "max"
, sourceSpec = \(x, y :: Integer) -> MarshalSourceSpec
{ resultVar = "main"
, expectedValue = max x y
, source = mconcat
[ toStg "x" x
, toStg "y" y
, Stg.max
, [stg| main = \ => max x y |] ]}}