on master help sign in
Plug in common array test code cleanly in Data.Array.Foreign
commita2f7e570ab9a71a541bbe27a218cd35864590cd5 authoradithyaov <adithya@composewell.com> dateSat 27 Nov 2021, 02:34 (5 years ago) parentdb254e1
2 files changed+112−84
test/Streamly/Test/Common/Array.hs+2−82 test/Streamly/Test/Data/Array/Foreign.hs+110−2
test/Streamly/Test/Common/Array.hs+2−82
@@ -31,8 +31,7 @@ import Streamly.Test.Common (listEquals)
3131
3232import qualified Streamly.Prelude as S
3333
34−#if defined(TEST_ARRAY) ||\
35− defined(DATA_ARRAY_PRIM) ||\
34+#if defined(DATA_ARRAY_PRIM) ||\
3635 defined(DATA_ARRAY_PRIM_PINNED)
3736import qualified Streamly.Internal.Data.Fold as Fold
3837#endif
@@ -40,14 +39,6 @@ import qualified Streamly.Internal.Data.Fold as Fold
4039#ifdef TEST_SMALL_ARRAY
4140import qualified Streamly.Internal.Data.SmallArray as A
4241type Array = A.SmallArray
43−#elif defined(TEST_ARRAY)
44−import Data.Word(Word8)
45−
46−import qualified Streamly.Internal.Data.Array.Foreign as A
47−import qualified Streamly.Internal.Data.Array.Foreign.Type as A
48−import qualified Streamly.Internal.Data.Array.Foreign.Mut.Type as MA
49−import qualified Streamly.Internal.Data.Array.Stream.Foreign as AS
50−type Array = A.Array
5142#elif defined(DATA_ARRAY_PRIM_PINNED)
5243import qualified Streamly.Internal.Data.Array.Prim.Pinned as A
5344import qualified Streamly.Internal.Data.Array.Prim.Pinned.Type as A
@@ -61,8 +52,6 @@ type Array = A.Array
6152moduleName :: String
6253#ifdef TEST_SMALL_ARRAY
6354moduleName = "Data.SmallArray"
64−#elif defined(TEST_ARRAY)
65−moduleName = "Data.Array.Foreign"
6655#elif defined(DATA_ARRAY_PRIM_PINNED)
6756moduleName = "Data.Array.Prim.Pinned"
6857#elif defined(DATA_ARRAY_PRIM)
@@ -185,55 +174,6 @@ foldManyWith f =
185174 $ S.fromList list
186175 assert (xs == list)
187176
188−#ifdef TEST_ARRAY
189−
190−unsafeWriteIndex :: [Int] -> Int -> Int -> IO Bool
191−unsafeWriteIndex xs i x = do
192− arr <- MA.fromList xs
193− MA.putIndexUnsafe arr i x
194− x1 <- MA.getIndexUnsafe arr i
195− return $ x1 == x
196−
197−lastN :: Int -> [a] -> [a]
198−lastN n l = drop (length l - n) l
199−
200−testLastN :: Property
201−testLastN =
202− forAll (choose (0, maxArrLen)) $ \len ->
203− forAll (choose (0, len)) $ \n ->
204− forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
205− monadicIO $ do
206− xs <- run
207− $ fmap A.toList
208− $ S.fold (A.writeLastN n)
209− $ S.fromList list
210− assert (xs == lastN n list)
211−
212−testLastN_LN :: Int -> Int -> IO Bool
213−testLastN_LN len n = do
214− let list = [1..len]
215− l1 <- fmap A.toList $ S.fold (A.writeLastN n) $ S.fromList list
216− let l2 = lastN n list
217− return $ l1 == l2
218−
219−-- Instead of hard coding 10000 here we can have maxStreamLength for operations
220−-- that use stream of arrays.
221−concatArrayW8 :: Property
222−concatArrayW8 =
223− forAll (vectorOf 10000 (arbitrary :: Gen Word8))
224− $ \w8List -> do
225− let w8ArrList = A.fromList . (: []) <$> w8List
226− f2 <- S.toList $ AS.concat $ S.fromList w8ArrList
227− w8List `shouldBe` f2
228−
229−unsafeSlice :: Int -> Int -> [Int] -> Bool
230−unsafeSlice i n list =
231− let lst = take n $ drop i $ list
232− arr = A.toList $ A.getSliceUnsafe i n $ A.fromList list
233− in arr == lst
234−
235−#endif
236−
237177main :: IO ()
238178main =
239179 hspec $
@@ -257,30 +197,10 @@ main =
257197 prop "fromList" testFromList
258198#endif
259199
260−#if defined(TEST_ARRAY) ||\
261− defined(DATA_ARRAY_PRIM) ||\
200+#if defined(DATA_ARRAY_PRIM) ||\
262201 defined(DATA_ARRAY_PRIM_PINNED)
263202 prop "foldMany with writeNUnsafe concats to original"
264203 (foldManyWith (\n -> Fold.take n (A.writeNUnsafe n)))
265204#endif
266205 prop "foldMany with writeN concats to original"
267206 (foldManyWith A.writeN)
268−
269−#ifdef TEST_ARRAY
270− prop "AS.concat . (A.fromList . (:[]) <$>) === id" $ concatArrayW8
271− describe "unsafeSlice" $ do
272− it "partial" $ unsafeSlice 2 4 [1..10]
273− it "none" $ unsafeSlice 10 0 [1..10]
274− it "full" $ unsafeSlice 0 10 [1..10]
275− describe "Mut.unsafeWriteIndex" $ do
276− it "first" (unsafeWriteIndex [1..10] 0 0 `shouldReturn` True)
277− it "middle" (unsafeWriteIndex [1..10] 5 0 `shouldReturn` True)
278− it "last" (unsafeWriteIndex [1..10] 9 0 `shouldReturn` True)
279− describe "Fold" $ do
280− prop "writeLastN : 0 <= n <= len" $ testLastN
281− describe "writeLastN boundary conditions" $ do
282− it "writeLastN -1" (testLastN_LN 10 (-1) `shouldReturn` True)
283− it "writeLastN 0" (testLastN_LN 10 0 `shouldReturn` True)
284− it "writeLastN length" (testLastN_LN 10 10 `shouldReturn` True)
285− it "writeLastN (length + 1)" (testLastN_LN 10 11 `shouldReturn` True)
286−#endif
test/Streamly/Test/Data/Array/Foreign.hs+110−2
@@ -8,5 +8,113 @@
88
99module Streamly.Test.Data.Array.Foreign (main) where
1010
11−#define TEST_ARRAY
12−#include "Streamly/Test/Common/Array.hs"
11+#include "Streamly/Test/Data/Array/CommonImports.hs"
12+
13+import Data.Word(Word8)
14+
15+import qualified Streamly.Internal.Data.Fold as Fold
16+import qualified Streamly.Internal.Data.Array.Foreign as A
17+import qualified Streamly.Internal.Data.Array.Foreign.Type as A
18+import qualified Streamly.Internal.Data.Array.Foreign.Mut.Type as MA
19+import qualified Streamly.Internal.Data.Array.Stream.Foreign as AS
20+type Array = A.Array
21+
22+moduleName :: String
23+moduleName = "Data.Array.Foreign"
24+
25+#include "Streamly/Test/Data/Array/Common.hs"
26+
27+testFromStreamToStream :: Property
28+testFromStreamToStream = genericTestFromTo (const A.fromStream) A.toStream (==)
29+
30+testFoldUnfold :: Property
31+testFoldUnfold = genericTestFromTo (const (S.fold A.write)) (S.unfold A.read) (==)
32+
33+testFromList :: Property
34+testFromList =
35+ forAll (choose (0, maxArrLen)) $ \len ->
36+ forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
37+ monadicIO $ do
38+ let arr = A.fromList list
39+ xs <- run $ S.toList $ (S.unfold A.read) arr
40+ assert (xs == list)
41+
42+testLengthFromStream :: Property
43+testLengthFromStream = genericTestFrom (const A.fromStream)
44+
45+
46+unsafeWriteIndex :: [Int] -> Int -> Int -> IO Bool
47+unsafeWriteIndex xs i x = do
48+ arr <- MA.fromList xs
49+ MA.putIndexUnsafe arr i x
50+ x1 <- MA.getIndexUnsafe arr i
51+ return $ x1 == x
52+
53+lastN :: Int -> [a] -> [a]
54+lastN n l = drop (length l - n) l
55+
56+testLastN :: Property
57+testLastN =
58+ forAll (choose (0, maxArrLen)) $ \len ->
59+ forAll (choose (0, len)) $ \n ->
60+ forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
61+ monadicIO $ do
62+ xs <- run
63+ $ fmap A.toList
64+ $ S.fold (A.writeLastN n)
65+ $ S.fromList list
66+ assert (xs == lastN n list)
67+
68+testLastN_LN :: Int -> Int -> IO Bool
69+testLastN_LN len n = do
70+ let list = [1..len]
71+ l1 <- fmap A.toList $ S.fold (A.writeLastN n) $ S.fromList list
72+ let l2 = lastN n list
73+ return $ l1 == l2
74+
75+-- Instead of hard coding 10000 here we can have maxStreamLength for operations
76+-- that use stream of arrays.
77+concatArrayW8 :: Property
78+concatArrayW8 =
79+ forAll (vectorOf 10000 (arbitrary :: Gen Word8))
80+ $ \w8List -> do
81+ let w8ArrList = A.fromList . (: []) <$> w8List
82+ f2 <- S.toList $ AS.concat $ S.fromList w8ArrList
83+ w8List `shouldBe` f2
84+
85+unsafeSlice :: Int -> Int -> [Int] -> Bool
86+unsafeSlice i n list =
87+ let lst = take n $ drop i $ list
88+ arr = A.toList $ A.getSliceUnsafe i n $ A.fromList list
89+ in arr == lst
90+
91+main :: IO ()
92+main =
93+ hspec $
94+ H.parallel $
95+ modifyMaxSuccess (const maxTestCount) $ do
96+ describe moduleName $ do
97+ commonMain
98+ describe "Construction" $ do
99+ prop "length . fromStream === n" testLengthFromStream
100+ prop "toStream . fromStream === id" testFromStreamToStream
101+ prop "read . write === id" testFoldUnfold
102+ prop "fromList" testFromList
103+ prop "foldMany with writeNUnsafe concats to original"
104+ (foldManyWith (\n -> Fold.take n (A.writeNUnsafe n)))
105+ prop "AS.concat . (A.fromList . (:[]) <$>) === id" $ concatArrayW8
106+ describe "unsafeSlice" $ do
107+ it "partial" $ unsafeSlice 2 4 [1..10]
108+ it "none" $ unsafeSlice 10 0 [1..10]
109+ it "full" $ unsafeSlice 0 10 [1..10]
110+ describe "Mut.unsafeWriteIndex" $ do
111+ it "first" (unsafeWriteIndex [1..10] 0 0 `shouldReturn` True)
112+ it "middle" (unsafeWriteIndex [1..10] 5 0 `shouldReturn` True)
113+ it "last" (unsafeWriteIndex [1..10] 9 0 `shouldReturn` True)
114+ describe "Fold" $ do
115+ prop "writeLastN : 0 <= n <= len" $ testLastN
116+ describe "writeLastN boundary conditions" $ do
117+ it "writeLastN -1" (testLastN_LN 10 (-1) `shouldReturn` True)
118+ it "writeLastN 0" (testLastN_LN 10 0 `shouldReturn` True)
119+ it "writeLastN length" (testLastN_LN 10 10 `shouldReturn` True)
120+ it "writeLastN (length + 1)" (testLastN_LN 10 11 `shouldReturn` True)