foundation-0.0.2: tests/Test/Foundation/Number.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE CPP #-}
module Test.Foundation.Number
( testNumber
, testNumberRefs
) where
import Imports
import Foundation
import Foundation.Numerical -- hiding (Positive)
import qualified Prelude
#if !(MIN_VERSION_base(4,8,0))
instance Arbitrary Natural where
arbitrary = fromInteger <$> (arbitrary `suchThat` \i -> i >= 0)
#endif
testAddNullElementRight :: (Show a, Eq a, Additive a, Arbitrary a)
=> Proxy a -> a -> Property
testAddNullElementRight _ a = a + azero === a
testAddNullElementLeft :: (Show a, Eq a, Additive a, Arbitrary a)
=> Proxy a -> a -> Property
testAddNullElementLeft _ a = azero + a === a
testAddCommutatif :: (Show a, Eq a, Additive a, Arbitrary a)
=> Proxy a -> a -> a -> Property
testAddCommutatif _ a b = a + b === b + a
testMultiplyByIdentityRight :: (Show a, Eq a, Multiplicative a, Arbitrary a)
=> Proxy a -> a -> Property
testMultiplyByIdentityRight _ a = a * midentity === a
testMultiplyByIdentityLeft :: (Show a, Eq a, Multiplicative a, Arbitrary a)
=> Proxy a -> a -> Property
testMultiplyByIdentityLeft _ a = midentity * a === a
testDivMulPlusRest :: (Show a, Eq a, Integral a, IDivisible a, Arbitrary a)
=> Proxy a -> a -> (NonZero a) -> Property
testDivMulPlusRest _ a (NonZero b) =
a === (a `div` b) * b + (a `mod` b)
testAdditive :: (Show a, Eq a, Additive a, Arbitrary a)
=> Proxy a -> TestTree
testAdditive proxy = testGroup "Additive"
[ testProperty "a + azero == a" (testAddNullElementRight proxy)
, testProperty "azero + a == a" (testAddNullElementLeft proxy)
, testProperty "a + b == b + a" (testAddCommutatif proxy)
]
testMultiplicative :: (Show a, Eq a, Multiplicative a, Arbitrary a)
=> Proxy a -> TestTree
testMultiplicative proxy = testGroup "Multiplicative"
[ testProperty "a * midentity == a" (testMultiplyByIdentityRight proxy)
, testProperty "midentity * a == a" (testMultiplyByIdentityLeft proxy)
]
testDividible :: (Show a, Eq a, IsIntegral a, IDivisible a, Arbitrary a)
=> Proxy a -> TestTree
testDividible proxy = testGroup "Divisible"
[ testProperty "(x `div` y) * y + (x `mod` y) == x" (testDivMulPlusRest proxy)
]
withP3 :: (Show a, Eq a, IsIntegral a, Additive a, Multiplicative a, Subtractive a, Difference a ~ a, Arbitrary a)
=> Proxy a -> (a -> a -> a -> Property) -> (a -> a -> a -> Property)
withP3 _ f = f
withP3Pos2 :: (Show a, Eq a, IsIntegral a, Difference a ~ a, Arbitrary a)
=> Proxy a -> (a -> Natural -> a -> Property) -> (a -> Natural -> a -> Property)
withP3Pos2 _ f = f
testOperatorPrecedence :: (Show a, Eq a, Prelude.Num a, IsIntegral a, Additive a, Subtractive a, Multiplicative a, Difference a ~ a, Arbitrary a) => Proxy a -> TestTree
testOperatorPrecedence proxy = testGroup "Precedence"
[ testProperty "+ and - (1)" $ withP3 proxy $ \a b c -> (a + b - c) === ((a + b) - c)
, testProperty "+ and - (2)" $ withP3 proxy $ \a b c -> (a - b + c) === ((a - b) + c)
, testProperty "+ and * (1)" $ withP3 proxy $ \a b c -> (a + b * c) === (a + (b * c))
, testProperty "+ and * (2)" $ withP3 proxy $ \a b c -> (a * b + c) === ((a * b) + c)
, testProperty "- and * (1)" $ withP3 proxy $ \a b c -> (a - b * c) === (a - (b * c))
, testProperty "- and * (2)" $ withP3 proxy $ \a b c -> (a * b - c) === ((a * b) - c)
, testProperty "* and ^ (1)" $ withP3Pos2 proxy $ \a b c -> (a ^ b * c) === ((a ^ b) * c)
, testProperty "* and ^ (2)" $ withP3Pos2 proxy $ \a c b -> (a * b ^ c) === (a * (b ^ c))
]
testNumber :: (Show a, Eq a, Prelude.Num a, IsIntegral a, Additive a, Multiplicative a, Subtractive a, Difference a ~ a, IDivisible a, Arbitrary a)
=> String -> Proxy a -> TestTree
testNumber name proxy = testGroup name
[ testAdditive proxy
, testMultiplicative proxy
, testDividible proxy
, testOperatorPrecedence proxy
]
testNumberRefs :: [TestTree]
testNumberRefs =
[ testNumber "Int" (Proxy :: Proxy Int)
, testNumber "Int8" (Proxy :: Proxy Int8)
, testNumber "Int16" (Proxy :: Proxy Int16)
, testNumber "Int32" (Proxy :: Proxy Int32)
, testNumber "Int64" (Proxy :: Proxy Int64)
, testNumber "Integer" (Proxy :: Proxy Integer)
, testNumber "Word" (Proxy :: Proxy Word)
, testNumber "Word8" (Proxy :: Proxy Word8)
, testNumber "Word16" (Proxy :: Proxy Word16)
, testNumber "Word32" (Proxy :: Proxy Word32)
, testNumber "Word64" (Proxy :: Proxy Word64)
]