2-- Module : Streamly.Test.Data.Array
3-- Copyright : (c) 2019 Composewell technologies
4-- License : BSD-3-Clause
5-- Maintainer : streamly@composewell.com
6-- Stability : experimental
9module Streamly.Test.Data.Array (main) where
11import Data.Char (isLower)
12import Data.List (sort)
13import Data.Word(Word8)
14import Foreign.Storable (peek)
15import GHC.Ptr (plusPtr)
16import Streamly.Data.Fold (Fold)
17import Streamly.Internal.Data.Stream (Stream)
18import Streamly.Internal.Data.Unboxed (Unbox, sizeOf)
19import Streamly.Test.Common (listEquals)
21import qualified Streamly.Data.Fold as Fold
22import qualified Streamly.Internal.Data.Array as A
23import qualified Streamly.Internal.Data.Array.Type as A
24import qualified Streamly.Internal.Data.Array.Mut.Type as MA
25import qualified Streamly.Internal.Data.Stream as S
28import Test.Hspec.QuickCheck
29import Test.QuickCheck (Property, chooseInt, listOf
30 , forAll, Gen, vectorOf, arbitrary, choose)
31import Test.QuickCheck.Monadic (monadicIO, assert, run)
36moduleName = "Data.Array"
38#include "Streamly/Test/Data/Array/Common.hs"
40testFromStreamToStream :: Property
41testFromStreamToStream = genericTestFromTo (const A.fromStream) A.read (==)
43testFoldUnfold :: Property
45 genericTestFromTo (const (S.fold A.write)) (S.unfold A.reader) (==)
47testFromList :: Property
49 forAll (choose (0, maxArrLen)) $ \len ->
50 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
52 let arr = A.fromList list
53 xs <- run $ S.fold Fold.toList $ S.unfold A.reader arr
56testLengthFromStream :: Property
57testLengthFromStream = genericTestFrom (const A.fromStream)
59unsafeWriteIndex :: [Int] -> Int -> Int -> IO Bool
60unsafeWriteIndex xs i x = do
62 MA.putIndexUnsafe i x arr
63 x1 <- MA.getIndexUnsafe i arr
66lastN :: Int -> [a] -> [a]
67lastN n l = drop (length l - n) l
71 forAll (choose (0, maxArrLen)) $ \len ->
72 forAll (choose (0, len)) $ \n ->
73 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
77 $ S.fold (A.writeLastN n)
79 assert (xs == lastN n list)
81testLastN_LN :: Int -> Int -> IO Bool
82testLastN_LN len n = do
84 l1 <- fmap A.toList $ S.fold (A.writeLastN n) $ S.fromList list
90 dt <- MA.fromList "abcDEFgeh"
91 dt' <- MA.strip isLower dt
95testStripLeft :: IO Bool
97 dt <- MA.fromList "abcDEF"
98 dt' <- MA.strip isLower dt
102testStripRight :: IO Bool
104 dt <- MA.fromList "DEFgeh"
105 dt' <- MA.strip isLower dt
109testStripZero :: IO Bool
111 dt <- MA.fromList "DEF"
112 dt' <- MA.strip isLower dt
116testStripEmpty :: IO Bool
118 dt <- MA.fromList "abc"
119 dt' <- MA.strip isLower dt
123testStripNull :: IO Bool
126 dt' <- MA.strip isLower dt
130unsafeSlice :: Int -> Int -> [Int] -> Bool
131unsafeSlice i n list =
132 let lst = take n $ drop i list
133 arr = A.toList $ A.getSliceUnsafe i n $ A.fromList list
136testBubbleWith :: Bool -> Property
138 forAll (listOf (chooseInt (-50, 100))) $ \ls0 ->
139 monadicIO $ action ls0
144 x <- S.fold (fldm ls) $ S.fromList ls
147 then assert (sort ls == lst)
148 else assert (sort ls == reverse lst)
155 then MA.bubble compare arr
156 else MA.bubble (flip compare) arr
159 (MA.newPinned $ length ls)
161testBubbleAsc :: Property
162testBubbleAsc = testBubbleWith True
164testBubbleDesc :: Property
165testBubbleDesc = testBubbleWith False
167testByteLengthWithMA :: forall a. Unbox a => a -> IO ()
168testByteLengthWithMA _ = do
169 arrA <- MA.newPinned 100 :: IO (MA.Array a)
170 let arrW8 = MA.castUnsafe arrA :: MA.Array Word8
171 MA.byteLength arrA `shouldBe` MA.length arrW8
173testBreakOn :: [Word8] -> Word8 -> [Word8] -> Maybe [Word8] -> IO ()
174testBreakOn inp sep bef aft = do
175 (bef_, aft_) <- A.breakOn sep (A.fromList inp)
176 bef_ `shouldBe` A.fromList bef
177 aft_ `shouldBe` fmap A.fromList aft
179testWrite :: [Char] -> IO ()
181 arr <- S.fold A.write (S.fromList inp)
182 A.toList arr `shouldBe` inp
184testFromToList :: [Char] -> IO ()
185testFromToList inp = A.toList (A.fromList inp) `shouldBe` inp
187testUnsafeIndxedFromList :: [Char] -> IO ()
188testUnsafeIndxedFromList inp =
189 let arr = A.fromList inp
190 in fmap (`A.unsafeIndex` arr) [0 .. (length inp - 1)] `shouldBe` inp
192testAsPtrUnsafeMA :: IO ()
193testAsPtrUnsafeMA = do
194 arr <- MA.fromList ([0 .. 99] :: [Int])
195 MA.asPtrUnsafe arr (getList (0 :: Int)) `shouldReturn` [0 .. 99]
199 sizeOfInt = sizeOf (undefined :: Int)
201 -- We need to be careful here. We assume Unboxed and Storable are compatible
202 -- with each other. For Int, they are compatible.
204 | i >= 100 = return []
207 rest <- getList (i + 1) (p `plusPtr` sizeOfInt)
213 bSize = len * sizeOf (undefined :: Char)
214 in forAll (vectorOf len (arbitrary :: Gen Char)) $ \vec ->
215 forAll (chooseInt (bSize - 2000, bSize + 2000)) $ \newBLen -> do
216 arr <- MA.fromList vec
217 arr1 <- MA.realloc newBLen arr
219 lst1 <- MA.toList arr1
226 modifyMaxSuccess (const maxTestCount) $ do
227 describe moduleName $ do
229 describe "Construction" $ do
230 -- XXX There is an issue https://github.com/composewell/streamly/issues/1577
231 --prop "testAppend" testAppend
232 prop "testBubbleAsc" testBubbleAsc
233 prop "testBubbleDesc" testBubbleDesc
234 prop "length . fromStream === n" testLengthFromStream
235 prop "toStream . fromStream === id" testFromStreamToStream
236 prop "read . write === id" testFoldUnfold
237 prop "fromList" testFromList
238 prop "foldMany with writeNUnsafe concats to original"
239 (foldManyWith (\n -> Fold.take n (A.writeNUnsafe n)))
240 describe "unsafeSlice" $ do
241 it "partial" $ unsafeSlice 2 4 [1..10]
242 it "none" $ unsafeSlice 10 0 [1..10]
243 it "full" $ unsafeSlice 0 10 [1..10]
244 describe "Mut.unsafeWriteIndex" $ do
245 it "first" (unsafeWriteIndex [1..10] 0 0 `shouldReturn` True)
246 it "middle" (unsafeWriteIndex [1..10] 5 0 `shouldReturn` True)
247 it "last" (unsafeWriteIndex [1..10] 9 0 `shouldReturn` True)
249 prop "writeLastN : 0 <= n <= len" testLastN
250 describe "writeLastN boundary conditions" $ do
251 it "writeLastN -1" (testLastN_LN 10 (-1) `shouldReturn` True)
252 it "writeLastN 0" (testLastN_LN 10 0 `shouldReturn` True)
253 it "writeLastN length" (testLastN_LN 10 10 `shouldReturn` True)
254 it "writeLastN (length + 1)" (testLastN_LN 10 11 `shouldReturn` True)
255 describe "Strip" $ do
256 it "strip" (testStrip `shouldReturn` True)
257 it "stripLeft" (testStripLeft `shouldReturn` True)
258 it "stripRight" (testStripRight `shouldReturn` True)
259 it "stripZero" (testStripZero `shouldReturn` True)
260 it "stripEmpty" (testStripEmpty `shouldReturn` True)
261 it "stripNull" (testStripNull `shouldReturn` True)
263 it "testByteLengthWithMA Int"
264 (testByteLengthWithMA (undefined :: Int))
265 it "testByteLengthWithMA Char"
266 (testByteLengthWithMA (undefined :: Char))
267 it "testAsPtrUnsafeMA" testAsPtrUnsafeMA
268 it "reallocMA" reallocMA
269 describe "breakOn" $ do
270 it "testBreakOn [1, 0, 2] 0"
271 (testBreakOn [1, 0, 2] 0 [1] (Just [2]))
272 it "testBreakOn [1, 0] 0" (testBreakOn [1, 0] 0 [1] (Just []))
273 it "testBreakOn [1] 0" (testBreakOn [1] 0 [1] Nothing)
274 describe "toList . fromList" $ do
275 it "testFromToList abc" (testFromToList "abc")
276 it "testFromToList \\22407" (testFromToList "\22407")
277 describe "unsafeIndex . fromList" $ do
278 it "testUnsafeIndxedFromList abc" (testUnsafeIndxedFromList "abc")
279 it "testUnsafeIndxedFromList \\22407"
280 (testUnsafeIndxedFromList "\22407")
281 describe "write" $ do
282 it "testWrite abc" (testWrite "abc")
283 it "testWrite \\22407" (testWrite "\22407")
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