@@ -0,0 +1,145 @@
1+{-# LANGUAGE TemplateHaskell #-}
2+
3+-- |
4+-- Module : Streamly.Test.Data.Unbox.TH
5+-- Copyright : (c) 2022 Composewell technologies
6+-- License : BSD-3-Clause
7+-- Maintainer : streamly@composewell.com
8+-- Stability : experimental
9+-- Portability : GHC
10+
11+module Streamly.Test.Data.Unbox.TH (main) where
12+
13+--------------------------------------------------------------------------------
14+-- Imports
15+--------------------------------------------------------------------------------
16+
17+import Data.Proxy (Proxy(..))
18+import Streamly.Internal.Data.Unbox.TH
19+import Streamly.Internal.Data.Unbox (Unbox(..), newBytes, pokeByteIndex)
20+
21+import Test.Hspec as H
22+
23+--------------------------------------------------------------------------------
24+-- Test helpers
25+--------------------------------------------------------------------------------
26+
27+testSerialization ::
28+ forall a. (Eq a, Show a, Unbox a)
29+ => a
30+ -> IO ()
31+testSerialization val = do
32+ arr <- newBytes (sizeOf (Proxy :: Proxy a))
33+ pokeByteIndex 0 arr val
34+ peekByteIndex 0 arr `shouldReturn` val
35+
36+-- Size is also implicitly tested while serializing and deserializing.
37+checkSizeOf :: forall a. Unbox a => Proxy a -> Int -> IO ()
38+checkSizeOf _ size = sizeOf (Proxy :: Proxy a) `shouldBe` size
39+
40+checkSizeOfNew :: forall a. Unbox a => String -> Proxy a -> Int -> Spec
41+checkSizeOfNew tag proxy expectation =
42+ it ("checkSizeOf " ++ tag) $ checkSizeOf proxy expectation
43+
44+data CustomDataType1 =
45+ CustomDataType1
46+ deriving (Show, Eq)
47+
48+data CustomDataType2
49+ = CDT2Constructor1
50+ | CDT2Constructor2
51+ | CDT2Constructor3
52+ deriving (Show, Eq)
53+
54+data CustomDataType3 a b c
55+ = CDT3Constructor1 a
56+ | CDT3Constructor2 a b
57+ | CDT3Constructor3 a b c
58+ deriving (Show, Eq)
59+
60+data CustomDataType4 a b
61+ = CDT4Constructor1
62+ | CDT4Constructor2 Bool
63+ | CDT4Constructor3 Bool b
64+ deriving (Show, Eq)
65+
66+$(deriveUnbox ''CustomDataType1)
67+$(deriveUnbox ''CustomDataType2)
68+$(deriveUnbox ''CustomDataType3)
69+$(deriveUnboxWith ["b"] ''CustomDataType4)
70+
71+--------------------------------------------------------------------------------
72+-- CPP helpers
73+--------------------------------------------------------------------------------
74+
75+#define CHECK_SIZE(type, expectation) \
76+ it "checkSizeOf type" $ checkSizeOf (Proxy :: Proxy type) expectation
77+
78+--------------------------------------------------------------------------------
79+-- Tests
80+--------------------------------------------------------------------------------
81+
82+testCustomDatatype1TH :: Spec
83+testCustomDatatype1TH = do
84+ it "CustomDataType1" $ testSerialization CustomDataType1
85+
86+ CHECK_SIZE(CustomDataType1, 1)
87+
88+testCustomDatatype2TH :: Spec
89+testCustomDatatype2TH = do
90+ it "CustomDataType2 1" $ testSerialization CDT2Constructor1
91+ it "CustomDataType2 2" $ testSerialization CDT2Constructor2
92+ it "CustomDataType2 3" $ testSerialization CDT2Constructor3
93+
94+ CHECK_SIZE(CustomDataType2, 1)
95+
96+testCustomDatatype3TH :: Spec
97+testCustomDatatype3TH = do
98+ it "CustomDataType3 1"
99+ $ testSerialization
100+ (CDT3Constructor1 3 :: CustomDataType3 Int Bool Double)
101+ it "CustomDataType3 2"
102+ $ testSerialization
103+ (CDT3Constructor2 3 False :: CustomDataType3 Int Bool Double)
104+ it "CustomDataType3 3"
105+ $ testSerialization (CDT3Constructor3 (3 :: Int) False (5 :: Double))
106+
107+ checkSizeOfNew
108+ "CustomDataType3"
109+ (Proxy :: Proxy (CustomDataType3 Int Bool Double))
110+ (1 + sizeOf (Proxy :: Proxy Int)
111+ + sizeOf (Proxy :: Proxy Bool)
112+ + sizeOf (Proxy :: Proxy Double))
113+
114+testCustomDatatype4TH :: Spec
115+testCustomDatatype4TH = do
116+ it "CustomDataType4 1"
117+ $ testSerialization (CDT4Constructor1 :: CustomDataType4 a Int)
118+ it "CustomDataType4 2"
119+ $ testSerialization
120+ (CDT4Constructor2 True :: CustomDataType4 a Int)
121+ it "CustomDataType4 3"
122+ $ testSerialization (CDT4Constructor3 False (5 :: Int))
123+
124+ checkSizeOfNew
125+ "CustomDataType4"
126+ (Proxy :: Proxy (CustomDataType4 a Int))
127+ (1 + sizeOf (Proxy :: Proxy Bool) + sizeOf (Proxy :: Proxy Int))
128+
129+testCases :: Spec
130+testCases = do
131+
132+ testCustomDatatype1TH
133+ testCustomDatatype2TH
134+ testCustomDatatype3TH
135+ testCustomDatatype4TH
136+
137+--------------------------------------------------------------------------------
138+-- Main function
139+--------------------------------------------------------------------------------
140+
141+moduleName :: String
142+moduleName = "Data.Unboxed.TH"
143+
144+main :: IO ()
145+main = hspec $ H.parallel $ describe moduleName testCases