{-# 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