-
Notifications
You must be signed in to change notification settings - Fork 70
Expand file tree
/
Copy pathStream.hs
More file actions
111 lines (91 loc) · 3.8 KB
/
Stream.hs
File metadata and controls
111 lines (91 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
module Main (main) where
import Data.Word (Word8)
import Streamly.Test.Common (listEquals, chooseInt)
import Test.Hspec (hspec, describe, shouldBe)
import Test.Hspec.QuickCheck
import Test.QuickCheck (forAll, Property, vectorOf, Gen, Arbitrary (arbitrary))
import Test.QuickCheck.Monadic (assert, monadicIO, run)
import qualified Streamly.Internal.Data.Array as Array
import qualified Streamly.Internal.Data.Fold as Fold
import qualified Streamly.Internal.Data.Parser as Parser
import qualified Streamly.Internal.Data.Stream as Stream
import qualified Test.Hspec as Hspec
import Prelude hiding (sequence)
#if MIN_VERSION_QuickCheck(2,14,0)
import Test.QuickCheck (chooseAny)
#else
import System.Random (Random(random))
import Test.QuickCheck.Gen (Gen(MkGen))
-- | Generates a random element over the natural range of `a`.
chooseAny :: Random a => Gen a
chooseAny = MkGen (\r _ -> let (x,_) = random r in x)
#endif
maxTestCount :: Int
maxTestCount = 100
chunksOf :: Monad m
=> Int -> Fold.Fold m a b -> Stream.Stream m a -> Stream.Stream m b
chunksOf n f = Stream.foldMany (Fold.take n f)
parseBreak :: Property
parseBreak = do
let len = 200
-- ls = input list (stream)
-- clen = chunk size
-- tlen = parser take size
forAll
((,,)
<$> vectorOf len (chooseAny :: Gen Int)
<*> chooseInt (1, len)
<*> chooseInt (0, len))
$ \(ls, clen, tlen) ->
monadicIO $ do
(ls1, str) <-
let input =
Stream.toStreamK
$ chunksOf
clen (Array.createOf clen) (Stream.fromList ls)
parser = Parser.fromFold (Fold.take tlen Fold.toList)
in run $ Array.parseBreak (Array.toParserK parser) input
ls2 <- run $ Stream.fold Fold.toList (Array.concat $ Stream.fromStreamK str)
case ls1 of
Right x -> listEquals (==) (x ++ ls2) ls
Left _ -> assert False
splitOnSuffix :: Word8 -> [Word8] -> [[Word8]] -> IO ()
splitOnSuffix sep inp out = do
res <-
Stream.fold Fold.toList
$ Array.compactEndByByte_ sep
$ chunksOf 2 (Array.createOf 2) $ Stream.fromList inp
fmap Array.toList res `shouldBe` out
-------------------------------------------------------------------------------
-- Main
-------------------------------------------------------------------------------
moduleName :: String
moduleName = "Data.Array.Stream"
-- Instead of hard coding 10000 here we can have maxStreamLength for operations
-- that use stream of arrays.
concatArrayW8 :: Property
concatArrayW8 =
forAll (vectorOf 10000 (arbitrary :: Gen Word8))
$ \w8List -> do
let w8ArrList = Array.fromList . (: []) <$> w8List
f2 <- Stream.fold Fold.toList $ Array.concat $ Stream.fromList w8ArrList
w8List `shouldBe` f2
main :: IO ()
main =
hspec $
Hspec.parallel $
modifyMaxSuccess (const maxTestCount) $ do
describe moduleName $ do
describe "Stream parsing" $ do
prop "parseBreak" parseBreak
prop "concatArrayW8" concatArrayW8
describe "splifOnSuffix" $ do
Hspec.it "splitOnSuffix 0 [1, 2, 0, 4, 0, 5, 6]"
$ splitOnSuffix 0 [1, 2, 0, 4, 0, 5, 6]
[[1, 2], [4], [5, 6]]
Hspec.it "splitOnSuffix 0 [1, 2, 0, 4, 0, 5, 6, 0]"
$ splitOnSuffix 0 [1, 2, 0, 4, 0, 5, 6, 0]
[[1, 2], [4], [5, 6]]
Hspec.it "splitOnSuffix 0 [0, 1, 2, 0, 4, 0, 5, 6]"
$ splitOnSuffix 0 [0, 1, 2, 0, 4, 0, 5, 6]
[[], [1, 2], [4], [5, 6]]