packages feed

bytestring-read-0.2.0: tests/tasty.hs

{-# LANGUAGE OverloadedStrings #-}
import Numeric
import Control.Monad
import qualified Data.ByteString.Char8 as S
import Data.ByteString.Read
import Test.Tasty
import Test.Tasty.QuickCheck

(=~~) :: Double -> Double -> Bool
(=~~) a b = a == b || abs (a - b) <= max (abs a) (abs b) * 1e20

-- Word

newtype Word8 = Word8 String
    deriving Show

instance Arbitrary Word8 where
    arbitrary = do
        i <- choose (1, 50)
        n <- replicateM i $ choose ('0', '7')
        return $ Word8 $ "0o" ++ n

newtype Word10 = Word10 String
    deriving Show

instance Arbitrary Word10 where
    arbitrary = do
        i <- choose (1, 50)
        n <- replicateM i $ choose ('0', '9')
        return $ Word10 n

newtype Word16 = Word16 String
    deriving Show

instance Arbitrary Word16 where
    arbitrary = do
        i <- choose (1, 50)
        n <- replicateM i $ oneof [choose ('0', '9'), choose ('a', 'f'), choose ('A', 'F')]
        return $ Word16 $ "0x" ++ n

-- Int
newtype Int8 = Int8 String
    deriving Show

instance Arbitrary Int8 where
    arbitrary = do
        sign <- oneof $ map return ["", "-"]
        Word8 w <- arbitrary
        return . Int8 $ sign ++ w

newtype Int10 = Int10 String
    deriving Show

instance Arbitrary Int10 where
    arbitrary = do
        sign <- oneof $ map return ["", "-"]
        Word10 w <- arbitrary
        return . Int10 $ sign ++ w

newtype Int16 = Int16 String
    deriving Show

instance Arbitrary Int16 where
    arbitrary = do
        sign <- oneof $ map return ["", "-"]
        Word16 w <- arbitrary
        return . Int16 $ sign ++ w

-- Float
newtype Float10 = Float10 String
    deriving Show

instance Arbitrary Float10 where
    arbitrary = do
        Int10 q <- arbitrary
        Word10 r <- arbitrary
        return . Float10 $ q ++ '.': r

newtype SmallFloat10 = SmallFloat10 String
    deriving Show

instance Arbitrary SmallFloat10 where
    arbitrary = do
        sign <- oneof $ map return ["", "-"]
        i <- choose (0, 100)
        Word10 r <- arbitrary
        return . SmallFloat10 $ sign ++ "0." ++ replicate i '0' ++ r

newtype Float10Exp = Float10Exp String
    deriving Show

instance Arbitrary Float10Exp where
    arbitrary = do
        Float10 f <- arbitrary
        c <- oneof $ map return "eE"
        s <- oneof $ map return ["", "+", "-"]
        e <- choose (0, 10000 :: Int)
        return . Float10Exp $ f ++ c: s ++ show e 

main :: IO ()
main = defaultMain $ testGroup "read . show == id"
    [ testGroup "Integral"
        [ testProperty "Int" $ \i ->
            let Just (i', "") = signed integral . S.pack $ show i
            in (i :: Int) == i'
        ]
    , testGroup "Fractional"
        [ testProperty "showEFloat" $ \d ->
            let Just (d', "") = signed fractional . S.pack $ showEFloat Nothing d ""
            in (d :: Double) =~~ d'

        , testProperty "showFFloat" $ \d ->
            let Just (d', "") = signed fractional . S.pack $ showFFloat Nothing  d ""
            in (d :: Double) =~~ d'

        , testProperty "showGFloat" $ \d ->
            let Just (d', "") = signed fractional . S.pack $ showGFloat Nothing  d ""
            in (d :: Double) =~~ d'

        , testProperty "showHex" $ \i ->
            let Just (i', "") = signed fractional . (S.append "0x") . S.pack $ showHex (abs i) ""
            in fromIntegral (abs i :: Int) =~~ i'

        , testProperty "showOct" $ \i ->
            let Just (i', "") = signed fractional . (S.append "0o") . S.pack $ showOct (abs i) ""
            in fromIntegral (abs i :: Int) =~~ i'

        , testProperty "Word8" $ \(Word8 d) ->
            let Just (d', "") = signed fractional (S.pack d)
            in d' =~~ (read d :: Double)

        , testProperty "Word10" $ \(Word10 d) ->
            let Just (d', "") = signed fractional (S.pack d)
            in d' =~~ (read d :: Double)

        , testProperty "Word16" $ \(Word16 d) ->
            let Just (d', "") = signed fractional (S.pack d)
            in d' =~~ (read d :: Double)

        , testProperty "Int8" $ \(Int8 d) ->
            let Just (d', "") = signed fractional (S.pack d)
            in d' =~~ (read d :: Double)

        , testProperty "Int10" $ \(Int10 d) ->
            let Just (d', "") = signed fractional (S.pack d)
            in d' =~~ (read d :: Double)

        , testProperty "Int16" $ \(Int16 d) ->
            let Just (d', "") = signed fractional (S.pack d)
            in d' =~~ (read d :: Double)

        , testProperty "Float10" $ \(Float10 d) ->
            let Just (d', "") = signed fractional (S.pack d)
            in d' =~~ (read d :: Double)

        , testProperty "SmallFloat10" $ \(SmallFloat10 d) ->
            let Just (d', "") = signed fractional (S.pack d)
            in d' =~~ (read d :: Double)

        , testProperty "Float10Exp" $ \(Float10Exp d) ->
            let Just (d', "") = signed fractional (S.pack d)
            in d' =~~ (read d :: Double)
        ]
     ]