on master help sign in
Add tests for Streamly.Data.Array and read operator.
commit175b0b6d1068fab0d6cf411c6bbdbb956465970a authorPranay Sashank <pranaysashank@gmail.com> dateSat 30 Nov 2019, 06:34 (7 years ago) parent94bd0fa
3 files changed+167−1
src/Streamly/Data/Array.hs+19−1 streamly.cabal+16 test/Streamly/Test/Data/Array.hs+132
src/Streamly/Data/Array.hs+19−1
@@ -1,7 +1,9 @@
11{-# LANGUAGE CPP #-}
2+{-# LANGUAGE MagicHash #-}
23{-# LANGUAGE RankNTypes #-}
34{-# LANGUAGE RecordWildCards #-}
45{-# LANGUAGE ScopedTypeVariables #-}
6+{-# LANGUAGE UnboxedTuples #-}
57
68#include "inline.hs"
79
@@ -29,6 +31,7 @@ module Streamly.Data.Array
2931
3032 , toStream
3133 , toStreamRev
34+ , read
3235
3336 -- * Random Access
3437 , length
@@ -39,13 +42,16 @@ module Streamly.Data.Array
3942 )
4043where
4144
42−import Prelude hiding (length)
45+import Prelude hiding (length, read)
4346import Control.Monad (when)
4447import Control.Monad.IO.Class (MonadIO)
48+import GHC.Base (Int(..))
49+import qualified GHC.Exts as Exts
4550
4651import Streamly.Streams.Serial (SerialT)
4752import Streamly.Streams.StreamK.Type (IsStream)
4853import Streamly.Internal.Data.Fold.Types (Fold(..))
54+import Streamly.Internal.Data.Unfold.Types (Unfold(..))
4955import Streamly.Internal.Data.Array (Array(..))
5056
5157import qualified Streamly.Internal.Data.Array as A
@@ -77,3 +83,15 @@ fold f arr = P.runFold f (toStream arr :: SerialT m a)
7783{-# INLINE streamFold #-}
7884streamFold :: Monad m => (SerialT m a -> m b) -> Array a -> m b
7985streamFold f arr = f (toStream arr)
86+
87+{-# INLINE_NORMAL read #-}
88+read :: Monad m => Unfold m (Array a) a
89+read = Unfold step inject
90+ where
91+ inject arr = return (arr, 0)
92+ step (Array {..}, i)
93+ | i == aLen = return D.Stop
94+ step (arr, (I# i)) =
95+ return $
96+ case Exts.indexArray# (aA arr) i of
97+ (# x #) -> D.Yield x (arr, I# i + 1)
streamly.cabal+16
@@ -459,6 +459,22 @@ test-suite array-test
459459 transformers >= 0.4 && < 0.6
460460 default-language: Haskell2010
461461
462+test-suite unpinned-array-test
463+ import: test-options
464+ type: exitcode-stdio-1.0
465+ main-is: Streamly/Test/Data/Array.hs
466+ js-sources: jsbits/clock.js
467+ hs-source-dirs: test
468+ build-depends:
469+ streamly
470+ , base >= 4.8 && < 5
471+ , QuickCheck >= 2.10 && < 2.14
472+ , hspec >= 2.0 && < 3
473+ if impl(ghc < 8.0)
474+ build-depends:
475+ transformers >= 0.4 && < 0.6
476+ default-language: Haskell2010
477+
462478test-suite string-test
463479 import: test-options
464480 type: exitcode-stdio-1.0
test/Streamly/Test/Data/Array.hsnew file+132
@@ -0,0 +1,132 @@
1+{-# LANGUAGE CPP #-}
2+
3+-- |
4+-- Module : Main
5+-- Copyright : (c) 2019 Composewell Technologies
6+--
7+-- License : BSD-3-Clause
8+-- Maintainer : streamly@composewell.com
9+-- Stability : experimental
10+-- Portability : GHC
11+--
12+module Main (main) where
13+
14+import Foreign.Storable (Storable(..))
15+
16+import Test.Hspec.QuickCheck
17+import Test.QuickCheck (Property, forAll, Gen, vectorOf, arbitrary, choose)
18+import Test.QuickCheck.Monadic (monadicIO, assert)
19+
20+import Test.Hspec as H
21+
22+import qualified Streamly.Data.Array as A
23+import qualified Streamly.Prelude as S
24+
25+-- Coverage build takes too long with default number of tests
26+maxTestCount :: Int
27+#ifdef DEVBUILD
28+maxTestCount = 100
29+#else
30+maxTestCount = 10
31+#endif
32+
33+allocOverhead :: Int
34+allocOverhead = 2 * sizeOf (undefined :: Int)
35+
36+-- XXX this should be in sync with the defaultChunkSize in Array code, or we
37+-- should expose that and use that. For fast testing we could reduce the
38+-- defaultChunkSize under CPP conditionals.
39+--
40+defaultChunkSize :: Int
41+defaultChunkSize = 32 * k - allocOverhead
42+ where k = 1024
43+
44+maxArrLen :: Int
45+maxArrLen = defaultChunkSize * 8
46+
47+testLength :: Property
48+testLength =
49+ forAll (choose (0, maxArrLen)) $ \len ->
50+ forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
51+ monadicIO $ do
52+ arr <- S.fold (A.writeN len)
53+ $ S.fromList list
54+ assert (A.length arr == len)
55+
56+testLengthFromStreamN :: Property
57+testLengthFromStreamN =
58+ forAll (choose (0, maxArrLen)) $ \len ->
59+ forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
60+ monadicIO $ do
61+ arr <- A.fromStreamN len
62+ $ S.fromList list
63+ assert (A.length arr == len)
64+
65+testFoldUnfold :: Property
66+testFoldUnfold =
67+ forAll (choose (0, maxArrLen)) $ \len ->
68+ forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
69+ monadicIO $ do
70+ arr <- S.fold (A.writeN len)
71+ $ S.fromList list
72+ xs <- S.toList
73+ $ S.unfold A.read arr
74+ assert (xs == list)
75+
76+testFoldToStream :: Property
77+testFoldToStream =
78+ forAll (choose (0, maxArrLen)) $ \len ->
79+ forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
80+ monadicIO $ do
81+ arr <- S.fold (A.writeN len)
82+ $ S.fromList list
83+ xs <- S.toList
84+ $ A.toStream arr
85+ assert (xs == list)
86+
87+testFoldToStreamRev :: Property
88+testFoldToStreamRev =
89+ forAll (choose (0, maxArrLen)) $ \len ->
90+ forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
91+ monadicIO $ do
92+ arr <- S.fold (A.writeN len)
93+ $ S.fromList list
94+ xs <- S.toList
95+ $ A.toStreamRev arr
96+ assert (xs == reverse list)
97+
98+testFromStreamUnfold :: Property
99+testFromStreamUnfold =
100+ forAll (choose (0, maxArrLen)) $ \len ->
101+ forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
102+ monadicIO $ do
103+ arr <- A.fromStreamN len
104+ $ S.fromList list
105+ xs <- S.toList
106+ $ S.unfold A.read arr
107+ assert (xs == list)
108+
109+testFromStreamToStream :: Property
110+testFromStreamToStream =
111+ forAll (choose (0, maxArrLen)) $ \len ->
112+ forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
113+ monadicIO $ do
114+ arr <- A.fromStreamN len
115+ $ S.fromList list
116+ xs <- S.toList
117+ $ A.toStream arr
118+ assert (xs == list)
119+
120+main :: IO ()
121+main =
122+ hspec $
123+ H.parallel $
124+ modifyMaxSuccess (const maxTestCount) $
125+ describe "Construction" $ do
126+ prop "length . writeN n === n" testLength
127+ prop "length . fromStreamN n === n" testLengthFromStreamN
128+ prop "read . writeN === id " testFoldUnfold
129+ prop "toStream . writeN === id" testFoldToStream
130+ prop "toStreamRev . writeN === reverse" testFoldToStreamRev
131+ prop "read . fromStreamN === id" testFromStreamUnfold
132+ prop "toStream . fromStreamN === reverse" testFromStreamToStream