3-- Copyright : (c) 2019 Composewell Technologies
5-- License : BSD-3-Clause
6-- Maintainer : streamly@composewell.com
7-- Stability : experimental
11-- This is a common array test module that gets included in different
12-- Array test modules with the corresponding macro defined.
14import Foreign.Storable (Storable(..))
16import Test.Hspec.QuickCheck
17import Test.QuickCheck (Property, forAll, Gen, vectorOf, arbitrary, choose)
18import Test.QuickCheck.Monadic (monadicIO, assert, run)
21import Streamly.Prelude (SerialT)
22import qualified Streamly.Prelude as S
23#ifdef TEST_SMALL_ARRAY
24import qualified Streamly.Internal.Data.SmallArray as A
25type Array = A.SmallArray
26#elif defined(TEST_ARRAY)
27import Data.Word(Word8)
29import qualified Streamly.Internal.Data.Array.Storable.Foreign as A
30import qualified Streamly.Internal.Data.Array.Storable.Foreign.Types as A
31import qualified Streamly.Internal.Data.Stream.IsStream as IP
32import qualified Streamly.Internal.Memory.ArrayStream as AS
34#elif defined(DATA_ARRAY_PRIM_PINNED)
35import qualified Streamly.Internal.Data.Array.Prim.Pinned as A
36import qualified Streamly.Internal.Data.Array.Prim.Pinned.Types as A
37import qualified Streamly.Internal.Data.Stream.IsStream as IP
39#elif defined(DATA_ARRAY_PRIM)
40import qualified Streamly.Internal.Data.Array.Prim as A
41import qualified Streamly.Internal.Data.Array.Prim.Types as A
42import qualified Streamly.Internal.Data.Stream.IsStream as IP
45import qualified Streamly.Internal.Data.Array as A
49-- Coverage build takes too long with default number of tests
58allocOverhead = 2 * sizeOf (undefined :: Int)
60-- XXX this should be in sync with the defaultChunkSize in Array code, or we
61-- should expose that and use that. For fast testing we could reduce the
62-- defaultChunkSize under CPP conditionals.
64defaultChunkSize :: Int
65defaultChunkSize = 32 * k - allocOverhead
69maxArrLen = defaultChunkSize * 8
72 (Int -> SerialT IO Int -> IO (Array Int))
74genericTestFrom arrFold =
75 forAll (choose (0, maxArrLen)) $ \len ->
76 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
78 arr <- run $ arrFold len $ S.fromList list
79 assert (A.length arr == len)
82testLength = genericTestFrom (\n -> S.fold (A.writeN n))
84testLengthFromStreamN :: Property
85testLengthFromStreamN = genericTestFrom A.fromStreamN
87#ifndef TEST_SMALL_ARRAY
88testLengthFromStream :: Property
89testLengthFromStream = genericTestFrom (const A.fromStream)
93 (Int -> SerialT IO Int -> IO (Array Int))
94 -> (Array Int -> SerialT IO Int)
95 -> ([Int] -> [Int] -> Bool)
97genericTestFromTo arrFold arrUnfold listEq =
98 forAll (choose (0, maxArrLen)) $ \len ->
99 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
101 arr <- run $ arrFold len $ S.fromList list
102 xs <- run $ S.toList $ arrUnfold arr
103 assert (listEq xs list)
105testFoldNUnfold :: Property
107 genericTestFromTo (\n -> S.fold (A.writeN n)) (S.unfold A.read) (==)
109testFoldNToStream :: Property
111 genericTestFromTo (\n -> S.fold (A.writeN n)) A.toStream (==)
113testFoldNToStreamRev :: Property
114testFoldNToStreamRev =
116 (\n -> S.fold (A.writeN n))
118 (\xs list -> xs == reverse list)
120testFromStreamNUnfold :: Property
121testFromStreamNUnfold = genericTestFromTo A.fromStreamN (S.unfold A.read) (==)
123testFromStreamNToStream :: Property
124testFromStreamNToStream = genericTestFromTo A.fromStreamN A.toStream (==)
126testFromListN :: Property
128 forAll (choose (0, maxArrLen)) $ \len ->
129 forAll (choose (0, len)) $ \n ->
130 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
132 let arr = A.fromListN n list
133 xs <- run $ S.toList $ (S.unfold A.read) arr
134 assert (xs == take n list)
136#ifndef TEST_SMALL_ARRAY
137testFromStreamToStream :: Property
138testFromStreamToStream = genericTestFromTo (const A.fromStream) A.toStream (==)
140testFoldUnfold :: Property
141testFoldUnfold = genericTestFromTo (const (S.fold A.write)) (S.unfold A.read) (==)
143testFromList :: Property
145 forAll (choose (0, maxArrLen)) $ \len ->
146 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
148 let arr = A.fromList list
149 xs <- run $ S.toList $ (S.unfold A.read) arr
153#if defined(TEST_ARRAY) ||\
154 defined(DATA_ARRAY_PRIM) ||\
155 defined(DATA_ARRAY_PRIM_PINNED)
157testArraysOf :: Property
159 forAll (choose (0, maxArrLen)) $ \len ->
160 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
164 $ S.concatUnfold A.read
169 arraysOf n = IP.chunksOf n (A.writeNUnsafe n)
175lastN :: Int -> [a] -> [a]
176lastN n l = drop (length l - n) l
180 forAll (choose (0, maxArrLen)) $ \len ->
181 forAll (choose (0, len)) $ \n ->
182 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
188 assert (xs == lastN n list)
190testLastN_LN :: Int -> Int -> IO Bool
191testLastN_LN len n = do
193 l1 <- fmap A.toList $ S.fold (A.lastN n) $ S.fromList list
194 let l2 = lastN n list
197-- Instead of hard coding 10000 here we can have maxStreamLength for operations
198-- that use stream of arrays.
199concatArrayW8 :: Property
201 forAll (vectorOf 10000 (arbitrary :: Gen Word8))
203 let w8ArrList = A.fromList . (: []) <$> w8List
204 f2 <- S.toList $ AS.concat $ S.fromList w8ArrList
213 modifyMaxSuccess (const maxTestCount) $ do
214 describe "Construction" $ do
215 prop "length . writeN n === n" testLength
216 prop "length . fromStreamN n === n" testLengthFromStreamN
217 prop "read . writeN === id " testFoldNUnfold
218 prop "toStream . writeN === id" testFoldNToStream
219 prop "toStreamRev . writeN === reverse" testFoldNToStreamRev
220 prop "read . fromStreamN === id" testFromStreamNUnfold
221 prop "toStream . fromStreamN === id" testFromStreamNToStream
222 prop "fromListN" testFromListN
224#ifndef TEST_SMALL_ARRAY
225 prop "length . fromStream === n" testLengthFromStream
226 prop "toStream . fromStream === id" testFromStreamToStream
227 prop "read . write === id" testFoldUnfold
228 prop "fromList" testFromList
231#if defined(TEST_ARRAY) ||\
232 defined(DATA_ARRAY_PRIM) ||\
233 defined(DATA_ARRAY_PRIM_PINNED)
234 prop "arraysOf concats to original" testArraysOf
238 prop "AS.concat . (A.fromList . (:[]) <$>) === id" $ concatArrayW8
240 prop "lastN : 0 <= n <= len" $ testLastN
241 describe "lastN boundary conditions" $ do
242 it "lastN -1" (testLastN_LN 10 (-1) `shouldReturn` True)
243 it "lastN 0" (testLastN_LN 10 0 `shouldReturn` True)
244 it "lastN length" (testLastN_LN 10 10 `shouldReturn` True)
245 it "lastN (length + 1)" (testLastN_LN 10 11 `shouldReturn` True)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list