extended-reals-0.2.3.0: test/TestExtendedReal.hs
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE TemplateHaskell, ScopedTypeVariables #-}
import Prelude hiding (isInfinite)
import Control.DeepSeq
import Control.Exception (SomeException, evaluate, try)
import Control.Monad
import Data.Maybe
import System.IO.Unsafe (unsafePerformIO)
import Test.QuickCheck.Function
import Test.Tasty.QuickCheck
import Test.Tasty.HUnit
import Test.Tasty.TH
import Data.ExtendedReal
-- ----------------------------------------------------------------------
instance Arbitrary r => Arbitrary (Extended r) where
arbitrary =
oneof
[ return NegInf
, return PosInf
, liftM Finite arbitrary
]
eval :: a -> Maybe a
eval a = unsafePerformIO $ do
ret <- try (evaluate a)
case ret of
Left (_::SomeException) -> return Nothing
Right b -> return $ Just b
isDefined :: a -> Bool
isDefined = isJust . eval
-- ----------------------------------------------------------------------
prop_add_comm :: Property
prop_add_comm =
forAll arbitrary $ \(a :: Extended Rational) ->
forAll arbitrary $ \b ->
eval (a + b) == eval (b + a)
prop_add_assoc :: Property
prop_add_assoc =
forAll arbitrary $ \(a :: Extended Rational) ->
forAll arbitrary $ \b ->
forAll arbitrary $ \c ->
eval (a + (b + c)) == eval ((a + b) + c)
prop_add_unit :: Property
prop_add_unit =
forAll arbitrary $ \(a :: Extended Rational) ->
0 + a == a
prop_add_monotone :: Property
prop_add_monotone =
forAll arbitrary $ \(a :: Extended Rational) ->
forAll arbitrary $ \b ->
forAll arbitrary $ \c ->
a <= b && isDefined (a+c) && isDefined (b+c)
==> a+c <= b+c
prop_mult_comm :: Property
prop_mult_comm =
forAll arbitrary $ \(a :: Extended Rational) ->
forAll arbitrary $ \b ->
a * b == b * a
-- PosInf + NegInf is left undefined
case_add_PosInf_NegInf :: IO ()
case_add_PosInf_NegInf =
eval (inf + (- inf) :: Extended Rational) @?= Nothing
prop_mult_assoc :: Property
prop_mult_assoc =
forAll arbitrary $ \(a :: Extended Rational) ->
forAll arbitrary $ \b ->
forAll arbitrary $ \c ->
a * (b * c) == (a * b) * c
prop_mult_unit :: Property
prop_mult_unit =
forAll arbitrary $ \(a :: Extended Rational) ->
1 * a == a
prop_mult_dist :: Property
prop_mult_dist =
forAll arbitrary $ \(a :: Extended Rational) ->
forAll arbitrary $ \b ->
forAll arbitrary $ \c ->
isDefined (a * (b + c)) && isDefined (a * b + a * c)
==> eval (a * (b + c)) == eval (a * b + a * c)
prop_mult_zero :: Property
prop_mult_zero =
forAll arbitrary $ \(a :: Extended Rational) ->
0 * a == 0
prop_mult_monotone :: Property
prop_mult_monotone =
forAll arbitrary $ \(a :: Extended Rational) ->
forAll arbitrary $ \b ->
forAll arbitrary $ \c ->
a <= b && c > 0 && isDefined (a*c) && isDefined (b*c)
==> a*c <= b*c
-- We define 0 * PosInf = 0
case_mult_zero_PosInf :: IO ()
case_mult_zero_PosInf =
0 * inf @?= (0 :: Extended Rational)
-- We define 0 * NegInf = 0
case_mult_zero_NegInf :: IO ()
case_mult_zero_NegInf =
0 * (- inf) @?= (0 :: Extended Rational)
prop_negate_inverse :: Property
prop_negate_inverse =
forAll arbitrary $ \(a :: Extended Rational) ->
negate (negate a) == a
prop_signum_abs :: Property
prop_signum_abs =
forAll arbitrary $ \(a :: Extended Rational) ->
signum a * abs a == a
prop_recip_inverse :: Property
prop_recip_inverse =
forAll arbitrary $ \(a :: Extended Rational) ->
isFinite a && a /= 0 ==> recip (recip a) == a
case_recip_PosInf :: IO ()
case_recip_PosInf = recip inf @?= (0 :: Extended Rational)
case_recip_NegInf :: IO ()
case_recip_NegInf = recip (- inf) @?= (0 :: Extended Rational)
prop_minBound_smallest :: Property
prop_minBound_smallest =
forAll arbitrary $ \(a :: Extended Rational) ->
minBound <= a
prop_maxBound_largest :: Property
prop_maxBound_largest =
forAll arbitrary $ \(a :: Extended Rational) ->
a <= maxBound
prop_isFinite_fromRational :: Property
prop_isFinite_fromRational =
forAll arbitrary $ \a -> isFinite (fromRational a :: Extended Rational)
prop_isInfinite_PosInf :: Property
prop_isInfinite_PosInf = property $ isInfinite PosInf
prop_isInfinite_NegInf :: Property
prop_isInfinite_NegInf = property $ isInfinite NegInf
-- ----------------------------------------------------------------------
-- Functor
prop_Functor_id :: Property
prop_Functor_id =
forAll arbitrary $ \(a :: Extended Integer) ->
fmap id a == a
prop_Functor_comp :: Property
prop_Functor_comp =
forAll arbitrary $ \(f :: Fun Integer Integer) ->
forAll arbitrary $ \(g :: Fun Integer Integer) ->
forAll arbitrary $ \(a :: Extended Integer) ->
fmap (apply f . apply g) a == fmap (apply f) (fmap (apply g) a)
-- ----------------------------------------------------------------------
-- Show / Read
prop_read_show :: Property
prop_read_show =
forAll arbitrary $ \(a :: Extended Rational) ->
read (show a) == a
-- ----------------------------------------------------------------------
-- deepseq
prop_deepseq :: Property
prop_deepseq =
forAll arbitrary $ \(a :: Extended Rational) ->
a `deepseq` () == ()
-- ----------------------------------------------------------------------
-- Test harness
main :: IO ()
main = $(defaultMainGenerator)