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)
22import Streamly.Prelude (SerialT)
23import qualified Streamly.Prelude as S
25#ifdef TEST_SMALL_ARRAY
26import qualified Streamly.Internal.Data.SmallArray as A
27type Array = A.SmallArray
28#elif defined(TEST_ARRAY)
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
33#elif defined(DATA_ARRAY_PRIM_PINNED)
34import qualified Streamly.Internal.Data.Array.Prim.Pinned as A
35import qualified Streamly.Internal.Data.Array.Prim.Pinned.Types as A
36import qualified Streamly.Internal.Data.Stream.IsStream as IP
38#elif defined(DATA_ARRAY_PRIM)
39import qualified Streamly.Internal.Data.Array.Prim as A
40import qualified Streamly.Internal.Data.Array.Prim.Types as A
41import qualified Streamly.Internal.Data.Stream.IsStream as IP
44import qualified Streamly.Internal.Data.Array as A
48-- Coverage build takes too long with default number of tests
57allocOverhead = 2 * sizeOf (undefined :: Int)
59-- XXX this should be in sync with the defaultChunkSize in Array code, or we
60-- should expose that and use that. For fast testing we could reduce the
61-- defaultChunkSize under CPP conditionals.
63defaultChunkSize :: Int
64defaultChunkSize = 32 * k - allocOverhead
68maxArrLen = defaultChunkSize * 8
71 (Int -> SerialT IO Int -> IO (Array Int))
73genericTestFrom arrFold =
74 forAll (choose (0, maxArrLen)) $ \len ->
75 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
77 arr <- run $ arrFold len $ S.fromList list
78 assert (A.length arr == len)
81testLength = genericTestFrom (\n -> S.fold (A.writeN n))
83testLengthFromStreamN :: Property
84testLengthFromStreamN = genericTestFrom A.fromStreamN
86#ifndef TEST_SMALL_ARRAY
87testLengthFromStream :: Property
88testLengthFromStream = genericTestFrom (const A.fromStream)
92 (Int -> SerialT IO Int -> IO (Array Int))
93 -> (Array Int -> SerialT IO Int)
94 -> ([Int] -> [Int] -> Bool)
96genericTestFromTo arrFold arrUnfold listEq =
97 forAll (choose (0, maxArrLen)) $ \len ->
98 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
100 arr <- run $ arrFold len $ S.fromList list
101 xs <- run $ S.toList $ arrUnfold arr
102 assert (listEq xs list)
104testFoldNUnfold :: Property
106 genericTestFromTo (\n -> S.fold (A.writeN n)) (S.unfold A.read) (==)
108testFoldNToStream :: Property
110 genericTestFromTo (\n -> S.fold (A.writeN n)) A.toStream (==)
112testFoldNToStreamRev :: Property
113testFoldNToStreamRev =
115 (\n -> S.fold (A.writeN n))
117 (\xs list -> xs == reverse list)
119testFromStreamNUnfold :: Property
120testFromStreamNUnfold = genericTestFromTo A.fromStreamN (S.unfold A.read) (==)
122testFromStreamNToStream :: Property
123testFromStreamNToStream = genericTestFromTo A.fromStreamN A.toStream (==)
125#ifndef TEST_SMALL_ARRAY
126testFromStreamToStream :: Property
127testFromStreamToStream = genericTestFromTo (const A.fromStream) A.toStream (==)
129testFoldUnfold :: Property
130testFoldUnfold = genericTestFromTo (const (S.fold A.write)) (S.unfold A.read) (==)
133#if defined(TEST_ARRAY) ||\
134 defined(DATA_ARRAY_PRIM) ||\
135 defined(DATA_ARRAY_PRIM_PINNED)
137testArraysOf :: Property
139 forAll (choose (0, maxArrLen)) $ \len ->
140 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
144 $ S.concatUnfold A.read
149 arraysOf n = IP.chunksOf n (A.writeNUnsafe n)
155lastN :: Int -> [a] -> [a]
156lastN n l = drop (length l - n) l
160 forAll (choose (0, maxArrLen)) $ \len ->
161 forAll (choose (0, len)) $ \n ->
162 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
168 assert (xs == lastN n list)
170testLastN_LN :: Int -> Int -> IO Bool
171testLastN_LN len n = do
173 l1 <- fmap A.toList $ S.fold (A.lastN n) $ S.fromList list
174 let l2 = lastN n list
182 modifyMaxSuccess (const maxTestCount) $ do
183 describe "Construction" $ do
184 prop "length . writeN n === n" testLength
185 prop "length . fromStreamN n === n" testLengthFromStreamN
186 prop "read . writeN === id " testFoldNUnfold
187 prop "toStream . writeN === id" testFoldNToStream
188 prop "toStreamRev . writeN === reverse" testFoldNToStreamRev
189 prop "read . fromStreamN === id" testFromStreamNUnfold
190 prop "toStream . fromStreamN === id" testFromStreamNToStream
191#ifndef TEST_SMALL_ARRAY
192 prop "length . fromStream === n" testLengthFromStream
193 prop "toStream . fromStream === id" testFromStreamToStream
194 prop "read . write === id" testFoldUnfold
197#if defined(TEST_ARRAY) ||\
198 defined(DATA_ARRAY_PRIM) ||\
199 defined(DATA_ARRAY_PRIM_PINNED)
200 prop "arraysOf concats to original" testArraysOf
205 prop "lastN : 0 <= n <= len" $ testLastN
206 describe "lastN boundary conditions" $ do
207 it "lastN -1" (testLastN_LN 10 (-1) `shouldReturn` True)
208 it "lastN 0" (testLastN_LN 10 0 `shouldReturn` True)
209 it "lastN length" (testLastN_LN 10 10 `shouldReturn` True)
210 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