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.Proxy (Proxy(..))
14import Data.Word(Word8)
15import Foreign.Storable (peek)
16import GHC.Ptr (plusPtr)
17import Streamly.Internal.Data.Unboxed (Unbox, sizeOf)
18import Streamly.Internal.Data.Array.Mut.Type (MutArray)
19import Test.QuickCheck (chooseInt, listOf)
21import qualified Streamly.Internal.Data.Array as A
22import qualified Streamly.Internal.Data.Array.Type as A
23import qualified Streamly.Internal.Data.Array.Mut.Type as MA
25#include "Streamly/Test/Data/Array/CommonImports.hs"
30moduleName = "Data.Array"
32#include "Streamly/Test/Data/Array/Common.hs"
34testFromStreamToStream :: Property
35testFromStreamToStream = genericTestFromTo (const A.fromStream) A.read (==)
37testFoldUnfold :: Property
39 genericTestFromTo (const (S.fold A.write)) (S.unfold A.reader) (==)
41testFromList :: Property
43 forAll (choose (0, maxArrLen)) $ \len ->
44 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
46 let arr = A.fromList list
47 xs <- run $ S.fold Fold.toList $ S.unfold A.reader arr
50testLengthFromStream :: Property
51testLengthFromStream = genericTestFrom (const A.fromStream)
53unsafeWriteIndex :: [Int] -> Int -> Int -> IO Bool
54unsafeWriteIndex xs i x = do
56 MA.putIndexUnsafe i arr x
57 x1 <- MA.getIndexUnsafe i arr
60lastN :: Int -> [a] -> [a]
61lastN n l = drop (length l - n) l
65 forAll (choose (0, maxArrLen)) $ \len ->
66 forAll (choose (0, len)) $ \n ->
67 forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
71 $ S.fold (A.writeLastN n)
73 assert (xs == lastN n list)
75testLastN_LN :: Int -> Int -> IO Bool
76testLastN_LN len n = do
78 l1 <- fmap A.toList $ S.fold (A.writeLastN n) $ S.fromList list
84 dt <- MA.fromList "abcDEFgeh"
85 dt' <- MA.strip isLower dt
89testStripLeft :: IO Bool
91 dt <- MA.fromList "abcDEF"
92 dt' <- MA.strip isLower dt
96testStripRight :: IO Bool
98 dt <- MA.fromList "DEFgeh"
99 dt' <- MA.strip isLower dt
103testStripZero :: IO Bool
105 dt <- MA.fromList "DEF"
106 dt' <- MA.strip isLower dt
110testStripEmpty :: IO Bool
112 dt <- MA.fromList "abc"
113 dt' <- MA.strip isLower dt
117testStripNull :: IO Bool
120 dt' <- MA.strip isLower dt
124unsafeSlice :: Int -> Int -> [Int] -> Bool
125unsafeSlice i n list =
126 let lst = take n $ drop i list
127 arr = A.toList $ A.getSliceUnsafe i n $ A.fromList list
130testBubbleWith :: Bool -> Property
132 forAll (listOf (chooseInt (-50, 100))) $ \ls0 ->
133 monadicIO $ action ls0
138 x <- S.fold (fldm ls) $ S.fromList ls
141 then assert (sort ls == lst)
142 else assert (sort ls == reverse lst)
149 then MA.bubble compare arr
150 else MA.bubble (flip compare) arr
153 (MA.newPinned $ length ls)
155testBubbleAsc :: Property
156testBubbleAsc = testBubbleWith True
158testBubbleDesc :: Property
159testBubbleDesc = testBubbleWith False
161testByteLengthWithMA :: forall a. Unbox a => a -> IO ()
162testByteLengthWithMA _ = do
163 arrA <- MA.newPinned 100 :: IO (MutArray a)
164 let arrW8 = MA.castUnsafe arrA :: MutArray Word8
165 MA.byteLength arrA `shouldBe` MA.length arrW8
167testBreakOn :: [Word8] -> Word8 -> [Word8] -> Maybe [Word8] -> IO ()
168testBreakOn inp sep bef aft = do
169 (bef_, aft_) <- A.breakOn sep (A.fromList inp)
170 bef_ `shouldBe` A.fromList bef
171 aft_ `shouldBe` fmap A.fromList aft
173testWrite :: [Char] -> IO ()
175 arr <- S.fold A.write (S.fromList inp)
176 A.toList arr `shouldBe` inp
178testFromToList :: [Char] -> IO ()
179testFromToList inp = A.toList (A.fromList inp) `shouldBe` inp
181testUnsafeIndxedFromList :: [Char] -> IO ()
182testUnsafeIndxedFromList inp =
183 let arr = A.fromList inp
184 in fmap (`A.unsafeIndex` arr) [0 .. (length inp - 1)] `shouldBe` inp
186testAsPtrUnsafeMA :: IO ()
187testAsPtrUnsafeMA = do
188 arr <- MA.fromList ([0 .. 99] :: [Int])
189 MA.asPtrUnsafe arr (getList (0 :: Int)) `shouldReturn` [0 .. 99]
193 sizeOfInt = sizeOf (Proxy :: Proxy Int)
195 -- We need to be careful here. We assume Unboxed and Storable are compatible
196 -- with each other. For Int, they are compatible.
198 | i >= 100 = return []
201 rest <- getList (i + 1) (p `plusPtr` sizeOfInt)
207 bSize = len * sizeOf (Proxy :: Proxy Char)
208 in forAll (vectorOf len (arbitrary :: Gen Char)) $ \vec ->
209 forAll (chooseInt (bSize - 2000, bSize + 2000)) $ \newBLen -> do
210 arr <- MA.fromList vec
211 arr1 <- MA.realloc newBLen arr
213 lst1 <- MA.toList arr1
220 modifyMaxSuccess (const maxTestCount) $ do
221 describe moduleName $ do
223 describe "Construction" $ do
224 -- XXX There is an issue https://github.com/composewell/streamly/issues/1577
225 --prop "testAppend" testAppend
226 prop "testBubbleAsc" testBubbleAsc
227 prop "testBubbleDesc" testBubbleDesc
228 prop "length . fromStream === n" testLengthFromStream
229 prop "toStream . fromStream === id" testFromStreamToStream
230 prop "read . write === id" testFoldUnfold
231 prop "fromList" testFromList
232 prop "foldMany with writeNUnsafe concats to original"
233 (foldManyWith (\n -> Fold.take n (A.writeNUnsafe n)))
234 describe "unsafeSlice" $ do
235 it "partial" $ unsafeSlice 2 4 [1..10]
236 it "none" $ unsafeSlice 10 0 [1..10]
237 it "full" $ unsafeSlice 0 10 [1..10]
238 describe "Mut.unsafeWriteIndex" $ do
239 it "first" (unsafeWriteIndex [1..10] 0 0 `shouldReturn` True)
240 it "middle" (unsafeWriteIndex [1..10] 5 0 `shouldReturn` True)
241 it "last" (unsafeWriteIndex [1..10] 9 0 `shouldReturn` True)
243 prop "writeLastN : 0 <= n <= len" testLastN
244 describe "writeLastN boundary conditions" $ do
245 it "writeLastN -1" (testLastN_LN 10 (-1) `shouldReturn` True)
246 it "writeLastN 0" (testLastN_LN 10 0 `shouldReturn` True)
247 it "writeLastN length" (testLastN_LN 10 10 `shouldReturn` True)
248 it "writeLastN (length + 1)" (testLastN_LN 10 11 `shouldReturn` True)
249 describe "Strip" $ do
250 it "strip" (testStrip `shouldReturn` True)
251 it "stripLeft" (testStripLeft `shouldReturn` True)
252 it "stripRight" (testStripRight `shouldReturn` True)
253 it "stripZero" (testStripZero `shouldReturn` True)
254 it "stripEmpty" (testStripEmpty `shouldReturn` True)
255 it "stripNull" (testStripNull `shouldReturn` True)
257 it "testByteLengthWithMA Int"
258 (testByteLengthWithMA (undefined :: Int))
259 it "testByteLengthWithMA Char"
260 (testByteLengthWithMA (undefined :: Char))
261 it "testAsPtrUnsafeMA" testAsPtrUnsafeMA
262 it "reallocMA" reallocMA
263 describe "breakOn" $ do
264 it "testBreakOn [1, 0, 2] 0"
265 (testBreakOn [1, 0, 2] 0 [1] (Just [2]))
266 it "testBreakOn [1, 0] 0" (testBreakOn [1, 0] 0 [1] (Just []))
267 it "testBreakOn [1] 0" (testBreakOn [1] 0 [1] Nothing)
268 describe "toList . fromList" $ do
269 it "testFromToList abc" (testFromToList "abc")
270 it "testFromToList \\22407" (testFromToList "\22407")
271 describe "unsafeIndex . fromList" $ do
272 it "testUnsafeIndxedFromList abc" (testUnsafeIndxedFromList "abc")
273 it "testUnsafeIndxedFromList \\22407"
274 (testUnsafeIndxedFromList "\22407")
275 describe "write" $ do
276 it "testWrite abc" (testWrite "abc")
277 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