packages feed

primes-type-0.2.0.0: test/Spec.hs

{-# OPTIONS_GHC -F -pgmF htfpp #-}

module Main where

import Test.Framework
import Data.Numbers.Primes
import Data.Numbers.Primes.Type
import Data.Word

instance (Arbitrary a, Integral a) => Arbitrary (Prime a) where
    arbitrary = getPrime <$> arbitrarySizedNatural

main = htfMain htf_thisModulesTests

-- | Some basic sanity checks.

test_prime = do
    assertEqual (Just $ getPrime 0) (maybePrime 2)
    assertEqual (Just $ getPrime 5) (maybePrime 13)
    assertEqual (primeIndex 2) (Just 0)
    assertEqual (primeIndex 13) (Just 5)
    assertEqual (maybePrime 4) (Nothing)

-- | These two properties show that Prime and its value are
--   isomorphic if and only if the value is prime.
--   (n in N but not in P are mapped to Nothing with no inverse.)

-- prop_maybePrime :: Integral int => int -> Bool -- ^ This is too general to suit a prop.
prop_maybePrime_Int = withQCArgs (\prop -> prop { maxSize = 1024 } ) prop_maybePrime_Int'
  where prop_maybePrime_Int' :: Int -> Bool
        prop_maybePrime_Int' x = r == Just x || r == Nothing
          where r :: Maybe Int
                r = getValue <$> maybePrime x

prop_maybePrime_Integer = withQCArgs (\prop -> prop { maxSize = 1024 } ) prop_maybePrime_Integer'
  where prop_maybePrime_Integer' :: Integer -> Bool
        prop_maybePrime_Integer' x = r == Just x || r == Nothing
          where r :: Maybe Integer
                r = getValue <$> maybePrime x

prop_maybePrime_Word = withQCArgs (\prop -> prop { maxSize = 5 } ) prop_maybePrime_Word'
  where prop_maybePrime_Word' :: Word8 -> Bool
        prop_maybePrime_Word' x = r == Just x || r == Nothing
          where r :: Maybe Word8
                r = getValue <$> maybePrime x

prop_getValue_Int = withQCArgs (\prop -> prop { maxSize = 1024 } ) prop_getValue_Int'
  where
    prop_getValue_Int' :: Int -> Bool
    prop_getValue_Int' n = (maybePrime . getValue $ p) == Just p
      where
        p :: Prime Int
        p | n < 0 = getPrime . abs $ n -- I know it's not super bright.
          | otherwise = getPrime n

-- | These two properties show that Prime and its index are isomorphic.

prop_primeIndex :: Int -> Bool
prop_primeIndex n = m == (getIndex <$> getPrime) m
  where m = abs n

prop_getIndex :: Int -> Bool
prop_getIndex n = getPrime m == (getPrime . getIndex . getPrime) m
  where m = abs n

-- | This property verifies the correctness of `deconstruct`.

prop_deconstruct i = deconstruct p == (getValue p, getIndex p)
  where
    p = getPrime (abs i)

-- | These two properties show that the enumeration associated with Prime is isomorphic.

prop_fromEnum :: Prime Int -> Bool
prop_fromEnum p = p == (toEnum . fromEnum) p

prop_toEnum :: Int -> Bool
prop_toEnum n' = n == (fromEnum . (toEnum :: Int -> Prime Int)) n
  where
    n = abs n'

-- | Equality & ordering of primes is the same as the respective relations on their indices.

prop_Eq = withQCArgs (\prop -> prop { maxSize = 256 } ) prop_Eq'
  where
    prop_Eq' :: (Int, Int) -> Bool
    prop_Eq' (i', j') = (i == j) == (getPrime i == getPrime j)
      where
        i = abs i'
        j = abs j'

prop_compare = withQCArgs (\prop -> prop { maxSize = 256 } ) prop_compare'
  where
    prop_compare' :: (Int, Int) -> Bool
    prop_compare' (i', j') = i `compare` j == (getPrime i `compare` getPrime j)
      where
        i = abs i'
        j = abs j'

-- | The list of indexed primes corresponds to its unzips.
test_indexedPrimes = assertEqual
                        (deconstruct <$> take 100 indexedPrimes)
                        (take 100 $ zip primes [0..])