codec-0.2: test/Data/Binary/Codec/Test.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
module Data.Binary.Codec.Test
( binaryTests
) where
import Control.Monad
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import Data.Binary.Get (runGetOrFail)
import Data.Binary.Put (runPutM)
import Data.Int
import Data.Word
import GHC.Generics (Generic)
import Test.Tasty
import Test.Tasty.QuickCheck
import Test.QuickCheck.Arbitrary.Generic
import Control.Monad.Codec
import Data.Binary.Codec
data RecordA = RecordA
{ recordAInt64 :: Int64
, recordAWord8 :: Word8
, recordANestedB :: RecordB
} deriving (Eq, Ord, Show, Generic)
instance Arbitrary RecordA where
arbitrary = genericArbitrary
shrink = genericShrink
data RecordB = RecordB
{ recordBWord16 :: Word16
, recordBByteString64 :: BS.ByteString
} deriving (Eq, Ord, Show, Generic)
instance Arbitrary RecordB where
arbitrary =
RecordB
<$> arbitrary
<*> (BS.pack <$> (replicateM 64 arbitrary))
shrink (RecordB word bs) =
RecordB <$> shrink word <*> pure bs
recordACodec :: BinaryCodec RecordA
recordACodec =
RecordA
<$> recordAInt64 =. int64le
<*> recordAWord8 =. word8
<*> recordANestedB =. recordBCodec
recordBCodec :: BinaryCodec RecordB
recordBCodec =
RecordB
<$> recordBWord16 =. word16host
<*> recordBByteString64 =. byteString 64
binaryRoundTrip :: (Eq a, Show a) => BinaryCodec a -> a -> Property
binaryRoundTrip codec x = Right x === roundTripValue
where
roundTripValue = do
let ( _, encoded ) = runPutM (codecOut codec x)
( leftover, _, val ) <- runGetOrFail (codecIn codec) encoded
unless (LBS.null leftover) $ fail "Codec produced leftover bytes."
return val
binaryTests :: TestTree
binaryTests = testGroup "Data.Aeson.Codec"
[ testProperty "Simple" $ binaryRoundTrip recordBCodec
, testProperty "Nested" $ binaryRoundTrip recordACodec
]