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