3-- Copyright : (c) 2019 Composewell Technologies
5-- License : BSD-3-Clause
6-- Maintainer : streamly@composewell.com
7-- Stability : experimental
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)
20import Streamly.Prelude (SerialT)
21import 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 qualified Streamly.Internal.Data.Array.Storable.Foreign as A
28import qualified Streamly.Internal.Data.Array.Storable.Foreign.Types as A
29import qualified Streamly.Internal.Data.Stream.IsStream as IP
31#elif defined(DATA_ARRAY_PRIM_PINNED)
32import qualified Streamly.Internal.Data.Array.Prim.Pinned as A
33import qualified Streamly.Internal.Data.Array.Prim.Pinned.Types as A
34import qualified Streamly.Internal.Data.Stream.IsStream as IP
36#elif defined(DATA_ARRAY_PRIM)
37import qualified Streamly.Internal.Data.Array.Prim as A
38import qualified Streamly.Internal.Data.Array.Prim.Types as A
39import qualified Streamly.Internal.Data.Stream.IsStream as IP
42import qualified Streamly.Internal.Data.Array as A
46-- Coverage build takes too long with default number of tests
55allocOverhead = 2 * sizeOf (undefined :: Int)
57-- XXX this should be in sync with the defaultChunkSize in Array code, or we
58-- should expose that and use that. For fast testing we could reduce the
59-- defaultChunkSize under CPP conditionals.
61defaultChunkSize :: Int
62defaultChunkSize = 32 * k - allocOverhead
66maxArrLen = defaultChunkSize * 8
69 (Int -> SerialT IO Int -> IO (Array Int))
71genericTestFrom arrFold =
72 forAll (choose (0, maxArrLen)) $ \len ->
73 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
75 arr <- run $ arrFold len $ S.fromList list
76 assert (A.length arr == len)
79testLength = genericTestFrom (\n -> S.fold (A.writeN n))
81testLengthFromStreamN :: Property
82testLengthFromStreamN = genericTestFrom A.fromStreamN
84#ifndef TEST_SMALL_ARRAY
85testLengthFromStream :: Property
86testLengthFromStream = genericTestFrom (const A.fromStream)
90 (Int -> SerialT IO Int -> IO (Array Int))
91 -> (Array Int -> SerialT IO Int)
92 -> ([Int] -> [Int] -> Bool)
94genericTestFromTo arrFold arrUnfold listEq =
95 forAll (choose (0, maxArrLen)) $ \len ->
96 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
98 arr <- run $ arrFold len $ S.fromList list
99 xs <- run $ S.toList $ arrUnfold arr
100 assert (listEq xs list)
102testFoldNUnfold :: Property
104 genericTestFromTo (\n -> S.fold (A.writeN n)) (S.unfold A.read) (==)
106testFoldNToStream :: Property
108 genericTestFromTo (\n -> S.fold (A.writeN n)) A.toStream (==)
110testFoldNToStreamRev :: Property
111testFoldNToStreamRev =
113 (\n -> S.fold (A.writeN n))
115 (\xs list -> xs == reverse list)
117testFromStreamNUnfold :: Property
118testFromStreamNUnfold = genericTestFromTo A.fromStreamN (S.unfold A.read) (==)
120testFromStreamNToStream :: Property
121testFromStreamNToStream = genericTestFromTo A.fromStreamN A.toStream (==)
123#ifndef TEST_SMALL_ARRAY
124testFromStreamToStream :: Property
125testFromStreamToStream = genericTestFromTo (const A.fromStream) A.toStream (==)
127testFoldUnfold :: Property
128testFoldUnfold = genericTestFromTo (const (S.fold A.write)) (S.unfold A.read) (==)
131#if defined(TEST_ARRAY) ||\
132 defined(DATA_ARRAY_PRIM) ||\
133 defined(DATA_ARRAY_PRIM_PINNED)
135testArraysOf :: Property
137 forAll (choose (0, maxArrLen)) $ \len ->
138 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
142 $ S.concatUnfold A.read
147 arraysOf n = IP.chunksOf n (A.writeNUnsafe n)
153lastN :: Int -> [a] -> [a]
154lastN n l = drop (length l - n) l
158 forAll (choose (0, maxArrLen)) $ \len ->
159 forAll (choose (0, len)) $ \n ->
160 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
166 assert (xs == lastN n list)
168testLastN_LN :: Int -> Int -> IO Bool
169testLastN_LN len n = do
171 l1 <- fmap A.toList $ S.fold (A.lastN n) $ S.fromList list
172 let l2 = lastN n list
180 modifyMaxSuccess (const maxTestCount) $ do
181 describe "Construction" $ do
182 prop "length . writeN n === n" testLength
183 prop "length . fromStreamN n === n" testLengthFromStreamN
184 prop "read . writeN === id " testFoldNUnfold
185 prop "toStream . writeN === id" testFoldNToStream
186 prop "toStreamRev . writeN === reverse" testFoldNToStreamRev
187 prop "read . fromStreamN === id" testFromStreamNUnfold
188 prop "toStream . fromStreamN === id" testFromStreamNToStream
189#ifndef TEST_SMALL_ARRAY
190 prop "length . fromStream === n" testLengthFromStream
191 prop "toStream . fromStream === id" testFromStreamToStream
192 prop "read . write === id" testFoldUnfold
195#if defined(TEST_ARRAY) ||\
196 defined(DATA_ARRAY_PRIM) ||\
197 defined(DATA_ARRAY_PRIM_PINNED)
198 prop "arraysOf concats to original" testArraysOf
203 prop "lastN : 0 <= n <= len" $ testLastN
204 describe "lastN boundary conditions" $ do
205 it "lastN -1" (testLastN_LN 10 (-1) `shouldReturn` True)
206 it "lastN 0" (testLastN_LN 10 0 `shouldReturn` True)
207 it "lastN length" (testLastN_LN 10 10 `shouldReturn` True)
208 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