on f2011df help sign in
190 lines 6.0 kB history raw
1{-# LANGUAGE CPP #-}
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--
12module Main (main) where
14import Foreign.Storable (Storable(..))
16import Test.Hspec.QuickCheck
17import Test.QuickCheck (Property, forAll, Gen, vectorOf, arbitrary, choose)
18import Test.QuickCheck.Monadic (monadicIO, assert, run)
20import Test.Hspec as H
22import Streamly (SerialT)
24import qualified Streamly.Prelude as S
26#ifdef TEST_SMALL_ARRAY
27import qualified Streamly.Internal.Data.SmallArray as A
28type Array = A.SmallArray
29#elif defined(TEST_ARRAY)
30import qualified Streamly.Memory.Array as A
31import qualified Streamly.Internal.Memory.Array as A
32import qualified Streamly.Internal.Prelude as IP
33type Array = A.Array
34#elif defined(TEST_PRIM_ARRAY)
35import qualified Streamly.Internal.Data.Prim.Array as A
36type Array = A.PrimArray
37#else
38import qualified Streamly.Internal.Data.Array as A
39type Array = A.Array
40#endif
42-- Coverage build takes too long with default number of tests
43maxTestCount :: Int
44#ifdef DEVBUILD
45maxTestCount = 100
46#else
47maxTestCount = 10
48#endif
50allocOverhead :: Int
51allocOverhead = 2 * sizeOf (undefined :: Int)
53-- XXX this should be in sync with the defaultChunkSize in Array code, or we
54-- should expose that and use that. For fast testing we could reduce the
55-- defaultChunkSize under CPP conditionals.
56--
57defaultChunkSize :: Int
58defaultChunkSize = 32 * k - allocOverhead
59 where k = 1024
61maxArrLen :: Int
62maxArrLen = defaultChunkSize * 8
64genericTestFrom ::
65 (Int -> SerialT IO Int -> IO (Array Int))
66 -> Property
67genericTestFrom arrFold =
68 forAll (choose (0, maxArrLen)) $ \len ->
69 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
70 monadicIO $ do
71 arr <- run $ arrFold len $ S.fromList list
72 assert (A.length arr == len)
74testLength :: Property
75testLength = genericTestFrom (\n -> S.fold (A.writeN n))
77testLengthFromStreamN :: Property
78testLengthFromStreamN = genericTestFrom A.fromStreamN
80#ifndef TEST_SMALL_ARRAY
81testLengthFromStream :: Property
82testLengthFromStream = genericTestFrom (const A.fromStream)
83#endif
85genericTestFromTo ::
86 (Int -> SerialT IO Int -> IO (Array Int))
87 -> (Array Int -> SerialT IO Int)
88 -> ([Int] -> [Int] -> Bool)
89 -> Property
90genericTestFromTo arrFold arrUnfold listEq =
91 forAll (choose (0, maxArrLen)) $ \len ->
92 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
93 monadicIO $ do
94 arr <- run $ arrFold len $ S.fromList list
95 xs <- run $ S.toList $ arrUnfold arr
96 assert (listEq xs list)
98testFoldNUnfold :: Property
99testFoldNUnfold =
100 genericTestFromTo (\n -> S.fold (A.writeN n)) (S.unfold A.read) (==)
102testFoldNToStream :: Property
103testFoldNToStream =
104 genericTestFromTo (\n -> S.fold (A.writeN n)) A.toStream (==)
106testFoldNToStreamRev :: Property
107testFoldNToStreamRev =
108 genericTestFromTo
109 (\n -> S.fold (A.writeN n))
110 A.toStreamRev
111 (\xs list -> xs == reverse list)
113testFromStreamNUnfold :: Property
114testFromStreamNUnfold = genericTestFromTo A.fromStreamN (S.unfold A.read) (==)
116testFromStreamNToStream :: Property
117testFromStreamNToStream = genericTestFromTo A.fromStreamN A.toStream (==)
119#ifndef TEST_SMALL_ARRAY
120testFromStreamToStream :: Property
121testFromStreamToStream = genericTestFromTo (const A.fromStream) A.toStream (==)
123testFoldUnfold :: Property
124testFoldUnfold = genericTestFromTo (const (S.fold A.write)) (S.unfold A.read) (==)
125#endif
127#ifdef TEST_ARRAY
128testArraysOf :: Property
129testArraysOf =
130 forAll (choose (0, maxArrLen)) $ \len ->
131 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
132 monadicIO $ do
133 xs <- S.toList
134 $ S.concatUnfold A.read
135 $ IP.arraysOf 240
136 $ S.fromList list
137 assert (xs == list)
139lastN :: Int -> [a] -> [a]
140lastN n l = drop (length l - n) l
142testLastN :: Property
143testLastN =
144 forAll (choose (0, maxArrLen)) $ \len ->
145 forAll (choose (0, len)) $ \n ->
146 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
147 monadicIO $ do
148 xs <- fmap A.toList
149 $ S.fold (A.lastN n)
150 $ S.fromList list
151 assert (xs == lastN n list)
153testLastN_LN :: Int -> Int -> IO Bool
154testLastN_LN len n = do
155 let list = [1..len]
156 l1 <- fmap A.toList $ S.fold (A.lastN n) $ S.fromList list
157 let l2 = lastN n list
158 return $ l1 == l2
159#endif
161main :: IO ()
162main =
163 hspec $
164 H.parallel $
165 modifyMaxSuccess (const maxTestCount) $ do
166 describe "Construction" $ do
167 prop "length . writeN n === n" testLength
168 prop "length . fromStreamN n === n" testLengthFromStreamN
169 prop "read . writeN === id " testFoldNUnfold
170 prop "toStream . writeN === id" testFoldNToStream
171 prop "toStreamRev . writeN === reverse" testFoldNToStreamRev
172 prop "read . fromStreamN === id" testFromStreamNUnfold
173 prop "toStream . fromStreamN === id" testFromStreamNToStream
174#ifndef TEST_SMALL_ARRAY
175 prop "length . fromStream === n" testLengthFromStream
176 prop "toStream . fromStream === id" testFromStreamToStream
177 prop "read . write === id" testFoldUnfold
178#endif
179#ifdef TEST_ARRAY
180 prop "arraysOf concats to original" testArraysOf
181#endif
182#ifdef TEST_ARRAY
183 describe "Fold" $ do
184 prop "lastN : 0 <= n <= len" $ testLastN
185 describe "lastN boundary conditions" $ do
186 it "lastN -1" (testLastN_LN 10 (-1) `shouldReturn` True)
187 it "lastN 0" (testLastN_LN 10 0 `shouldReturn` True)
188 it "lastN length" (testLastN_LN 10 10 `shouldReturn` True)
189 it "lastN (length + 1)" (testLastN_LN 10 11 `shouldReturn` True)
190#endif