packages feed

bytestring-from-0.2: test/Properties.hs

{-# LANGUAGE OverloadedStrings #-}

module Properties (tests) where

import Control.Applicative
import Data.ByteString.Char8 (pack)
import Data.ByteString.From
import Data.ByteString.From.Hex
import Data.Int
import Data.List (intercalate)
import Data.Maybe (fromMaybe)
import Data.Word
import Test.QuickCheck
import Test.Tasty
import Test.Tasty.QuickCheck
import Text.Printf

tests :: TestTree
tests = testGroup "Properties"
    [ testGroup "Decimals"
        [ testProperty "Int"    (\a -> Just (a :: Int)    == readBack a)
        , testProperty "Int8"   (\a -> Just (a :: Int8)   == readBack a)
        , testProperty "Int16"  (\a -> Just (a :: Int16)  == readBack a)
        , testProperty "Int32"  (\a -> Just (a :: Int32)  == readBack a)
        , testProperty "Int64"  (\a -> Just (a :: Int64)  == readBack a)
        , testProperty "Word"   (\a -> Just (a :: Word)   == readBack a)
        , testProperty "Word8 " (\a -> Just (a :: Word8)  == readBack a)
        , testProperty "Word16" (\a -> Just (a :: Word16) == readBack a)
        , testProperty "Word32" (\a -> Just (a :: Word32) == readBack a)
        , testProperty "Word64" (\a -> Just (a :: Word64) == readBack a)
        ]
    , testGroup "Hexadecimals"
        [ testProperty "Int"    (\a -> Just (a :: Hex Int)    == readBackHex a)
        , testProperty "Int8"   (\a -> Just (a :: Hex Int8)   == readBackHex a)
        , testProperty "Int16"  (\a -> Just (a :: Hex Int16)  == readBackHex a)
        , testProperty "Int32"  (\a -> Just (a :: Hex Int32)  == readBackHex a)
        , testProperty "Int64"  (\a -> Just (a :: Hex Int64)  == readBackHex a)
        , testProperty "Word"   (\a -> Just (a :: Hex Word)   == readBackHex a)
        , testProperty "Word8 " (\a -> Just (a :: Hex Word8)  == readBackHex a)
        , testProperty "Word16" (\a -> Just (a :: Hex Word16) == readBackHex a)
        , testProperty "Word32" (\a -> Just (a :: Hex Word32) == readBackHex a)
        , testProperty "Word64" (\a -> Just (a :: Hex Word64) == readBackHex a)
        ]
    , testGroup "Bool"
        [ testProperty "True"  readBackTrue
        , testProperty "False" readBackFalse
        ]
    , testGroup "Double"
        [ testProperty "Double" readBackDouble
        ]
    , testGroup "List"
        [ testProperty "[Int]"     (readCSV :: [Int]  -> Bool)
        , testProperty "[Word]"    (readCSV :: [Word] -> Bool)
        , testProperty "[Double]"  (readCSV :: [Double] -> Bool)
        , testProperty "[Bool]"    (readCSV :: [Bool] -> Bool)
        , testProperty "[Hex]"     readHexCSV
        , testProperty "Error"     readDoubleCSVAsInt
        ]
    ]

readBack :: (Show a, FromByteString a) => a -> Maybe a
readBack = fromByteString . pack . show

readBackDouble :: Double -> Bool
readBackDouble d = Just d == (fromByteString . pack . show $ d)

readBackHex :: (PrintfArg i, Show i, FromByteString i, Integral i) => i -> Maybe i
readBackHex = fromByteString . pack . printf "+0x%x"

readBackTrue :: Property
readBackTrue = forAll (elements ["True", "true"]) $
    fromMaybe False . fromByteString

readBackFalse :: Property
readBackFalse = forAll (elements ["False", "false"]) $
    fromMaybe False . fmap not . fromByteString

readCSV :: (Eq a, Show a, FromByteString a) => [a] -> Bool
readCSV lst = Just lst == fromByteString (pack (csv lst))
  where
    csv = intercalate "," . map show

readHexCSV :: [HexStr] -> Bool
readHexCSV lst = Just (map (snd . hex) lst) == fromByteString (pack (csv lst))
  where
    csv = intercalate "," . map (fst . hex)

readDoubleCSVAsInt :: [Double] -> Bool
readDoubleCSVAsInt []  = True
readDoubleCSVAsInt lst = Nothing == (fromByteString (pack (csv lst)) :: Maybe [Int])
  where
    csv = intercalate "," . map show

newtype HexStr = HexStr
    { hex :: (String, Hex Int)
    } deriving (Show)

instance Arbitrary HexStr where
    arbitrary = do
        i <- arbitrary
        x <- elements ['x', 'X']
        return $ HexStr (printf ('+':'0':x:"%x") i, i)

instance Arbitrary a => Arbitrary (Hex a) where
    arbitrary = Hex <$> arbitrary