fast-digits-0.2.0.0: tests/Tests.hs
{-# LANGUAGE ViewPatterns #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Main where
import Test.Tasty
import Test.Tasty.SmallCheck as SC
import Test.Tasty.QuickCheck as QC hiding (Positive, NonNegative)
import Test.SmallCheck.Series
import qualified Data.Digits as D
import Data.FastDigits
import Data.FastDigits.Internal
instance (Num a, Ord a, Arbitrary a) => Arbitrary (Positive a) where
arbitrary =
(Positive . abs) `fmap` (arbitrary `suchThat` (> 0))
instance (Num a, Ord a, Arbitrary a) => Arbitrary (NonNegative a) where
arbitrary =
(NonNegative . abs) `fmap` (arbitrary `suchThat` (>= 0))
digitsD :: Int -> Integer -> [Int]
digitsD base n = map fromInteger $ D.digitsRev (toInteger base) n
undigitsD :: Int -> [Int] -> Integer
undigitsD base ns = D.unDigits (toInteger base) (map toInteger ns)
digits10 :: Integer -> [Int]
digits10 = reverse . map (read . (:[])) . show
largeInteger :: [Positive Int] -> Integer
largeInteger ns = read $ take 1000 $ '0' : concatMap (\(Positive n) -> show n) ns
-- undigits base . digits base == id
qProperty1 :: Positive Int -> [Positive Int] -> QC.Property
qProperty1 (Positive base) (largeInteger -> n) = base > 1 QC.==>
undigits base (digits base n) == n
sProperty1 :: Int -> Integer -> Bool
sProperty1 base n = base <= 1 || n < 0 ||
undigits base (digits base n) == n
-- digits == digitsD
qProperty2 :: Positive Int -> [Positive Int] -> QC.Property
qProperty2 (Positive base) (largeInteger -> n) = base > 1 && n > 0QC.==>
digits base n == digitsD base n
sProperty2 :: Int -> Integer -> Bool
sProperty2 base n = base <= 1 || n < 0 ||
digits base n == digitsD base n
-- digits 10 == digits10
qProperty3 :: [Positive Int] -> QC.Property
qProperty3 (largeInteger -> n) = n > 0 QC.==>
digits 10 n == digits10 n
sProperty3 :: Integer -> Bool
sProperty3 n = n <= 0 ||
digits 10 n == digits10 n
-- All digits are between 0 and base - 1
qProperty4 :: Positive Int -> [Positive Int] -> QC.Property
qProperty4 (Positive base) (largeInteger -> n) = base > 1 QC.==>
all (\d -> d >= 0 && d < base) (digits base n)
sProperty4 :: Int -> Integer -> Bool
sProperty4 base n = base <= 1 || n < 0 ||
all (\d -> d >= 0 && d < base) (digits base n)
-- Last digit is not 0
qProperty5 :: Positive Int -> [Positive Int] -> QC.Property
qProperty5 (Positive base) (largeInteger -> n) = base > 1 && n > 0 QC.==>
((/= 0) $ last $ digits base n)
sProperty5 :: Int -> Integer -> Bool
sProperty5 base n = base <= 1 || n <= 0 ||
((/= 0) $ last $ digits base n)
-- digits 2 == digitsD 2
qProperty6 :: [Positive Int] -> Bool
qProperty6 (largeInteger -> n) =
digits 2 n == digitsD 2 n
sProperty6 :: Integer -> Bool
sProperty6 n = n < 0 ||
digits 2 n == digitsD 2 n
-- digits 2 == digitsD 2 on integers of special form
qProperty7 :: NonNegative Int -> NonNegative Int -> Bool
qProperty7 (NonNegative a) (NonNegative b) =
digits 2 n == digitsD 2 n
where
n = toInteger a * toInteger (maxBound :: Int) + toInteger b
sProperty7 :: Int -> Int -> Bool
sProperty7 a b = a < 0 || b < 0 ||
digits 2 n == digitsD 2 n
where
n = toInteger a * toInteger (maxBound :: Int) + toInteger b
qProperty8 :: Positive Int -> QC.Property
qProperty8 (Positive base') = base > 1 QC.==>
base ^ power == poweredBase && poweredBase > maxBound `div` base
where
base = fromIntegral $ toInteger base'
(power, poweredBase) = selectPower' base
sProperty8 :: Positive Int -> Bool
sProperty8 (Positive base') = base <= 1 ||
base ^ power == poweredBase && poweredBase > maxBound `div` base
where
base = fromIntegral $ toInteger base'
(power, poweredBase) = selectPower' base
testSuite :: TestTree
testSuite = testGroup "digits"
[ SC.testProperty "S undigits base . digits base == id" sProperty1
, QC.testProperty "Q undigits base . digits base == id" qProperty1
, SC.testProperty "S digits == digitsD" sProperty2
, QC.testProperty "Q digits == digitsD" qProperty2
, SC.testProperty "S digits 10 == digits10" sProperty3
, QC.testProperty "Q digits 10 == digits10" qProperty3
, SC.testProperty "S All digits are between 0 and base - 1" sProperty4
, QC.testProperty "Q All digits are between 0 and base - 1" qProperty4
, SC.testProperty "S Last digit is not 0" sProperty5
, QC.testProperty "Q Last digit is not 0" qProperty5
, SC.testProperty "S digits 2 == digitsD 2" sProperty6
, QC.testProperty "Q digits 2 == digitsD 2" qProperty6
, SC.testProperty "S digits 2 == digitsD 2 on integers of special form" sProperty7
, QC.testProperty "Q digits 2 == digitsD 2 on integers of special form" qProperty7
, SC.testProperty "S selectPower is correct" sProperty8
, QC.testProperty "Q selectPower is correct" qProperty8
]
main :: IO ()
main = defaultMain testSuite