streamly-0.10.0: test/Streamly/Test/Data/Unbox/TH.hs
{-# LANGUAGE TemplateHaskell #-}
-- |
-- Module : Streamly.Test.Data.Unbox.TH
-- Copyright : (c) 2022 Composewell technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
-- Stability : experimental
-- Portability : GHC
module Streamly.Test.Data.Unbox.TH (main) where
--------------------------------------------------------------------------------
-- Imports
--------------------------------------------------------------------------------
import Data.Proxy (Proxy(..))
import Streamly.Internal.Data.MutByteArray
import qualified Streamly.Internal.Data.MutByteArray as MBA
import Test.Hspec as H
--------------------------------------------------------------------------------
-- Test helpers
--------------------------------------------------------------------------------
testSerialization ::
forall a. (Eq a, Show a, Unbox a)
=> a
-> IO ()
testSerialization val = do
arr <- MBA.new (sizeOf (Proxy :: Proxy a))
pokeAt 0 arr val
peekAt 0 arr `shouldReturn` val
-- Size is also implicitly tested while serializing and deserializing.
checkSizeOf :: forall a. Unbox a => Proxy a -> Int -> IO ()
checkSizeOf _ sz = sizeOf (Proxy :: Proxy a) `shouldBe` sz
checkSizeOfNew :: forall a. Unbox a => String -> Proxy a -> Int -> Spec
checkSizeOfNew tag proxy expectation =
it ("checkSizeOf " ++ tag) $ checkSizeOf proxy expectation
data CustomDataType1 =
CustomDataType1
deriving (Show, Eq)
data CustomDataType2
= CDT2Constructor1
| CDT2Constructor2
| CDT2Constructor3
deriving (Show, Eq)
data CustomDataType3 a b c
= CDT3Constructor1 a
| CDT3Constructor2 a b
| CDT3Constructor3 a b c
deriving (Show, Eq)
data CustomDataType4 a b
= CDT4Constructor1
| CDT4Constructor2 Bool
| CDT4Constructor3 Bool b
deriving (Show, Eq)
$(deriveUnbox [d|instance Unbox CustomDataType1|])
$(deriveUnbox [d|instance Unbox CustomDataType2|])
$(deriveUnbox
[d|instance (Unbox a, Unbox b, Unbox c) => Unbox (CustomDataType3 a b c)|])
$(deriveUnbox [d|instance Unbox b => Unbox (CustomDataType4 a b)|])
--------------------------------------------------------------------------------
-- CPP helpers
--------------------------------------------------------------------------------
#define CHECK_SIZE(type, expectation) \
it "checkSizeOf type" $ checkSizeOf (Proxy :: Proxy type) expectation
--------------------------------------------------------------------------------
-- Tests
--------------------------------------------------------------------------------
testCustomDatatype1TH :: Spec
testCustomDatatype1TH = do
it "CustomDataType1" $ testSerialization CustomDataType1
CHECK_SIZE(CustomDataType1, 1)
testCustomDatatype2TH :: Spec
testCustomDatatype2TH = do
it "CustomDataType2 1" $ testSerialization CDT2Constructor1
it "CustomDataType2 2" $ testSerialization CDT2Constructor2
it "CustomDataType2 3" $ testSerialization CDT2Constructor3
CHECK_SIZE(CustomDataType2, 1)
testCustomDatatype3TH :: Spec
testCustomDatatype3TH = do
it "CustomDataType3 1"
$ testSerialization
(CDT3Constructor1 3 :: CustomDataType3 Int Bool Double)
it "CustomDataType3 2"
$ testSerialization
(CDT3Constructor2 3 False :: CustomDataType3 Int Bool Double)
it "CustomDataType3 3"
$ testSerialization (CDT3Constructor3 (3 :: Int) False (5 :: Double))
checkSizeOfNew
"CustomDataType3"
(Proxy :: Proxy (CustomDataType3 Int Bool Double))
(1 + sizeOf (Proxy :: Proxy Int)
+ sizeOf (Proxy :: Proxy Bool)
+ sizeOf (Proxy :: Proxy Double))
testCustomDatatype4TH :: Spec
testCustomDatatype4TH = do
it "CustomDataType4 1"
$ testSerialization (CDT4Constructor1 :: CustomDataType4 a Int)
it "CustomDataType4 2"
$ testSerialization
(CDT4Constructor2 True :: CustomDataType4 a Int)
it "CustomDataType4 3"
$ testSerialization (CDT4Constructor3 False (5 :: Int))
checkSizeOfNew
"CustomDataType4"
(Proxy :: Proxy (CustomDataType4 a Int))
(1 + sizeOf (Proxy :: Proxy Bool) + sizeOf (Proxy :: Proxy Int))
testCases :: Spec
testCases = do
testCustomDatatype1TH
testCustomDatatype2TH
testCustomDatatype3TH
testCustomDatatype4TH
--------------------------------------------------------------------------------
-- Main function
--------------------------------------------------------------------------------
moduleName :: String
moduleName = "Data.Unboxed.TH"
main :: IO ()
main = hspec $ H.parallel $ describe moduleName testCases