on aaa279c help sign in
791 lines 29 kB history raw
1module Main (main) where
3import Control.Exception (SomeException(..))
4import Data.Word (Word8, Word32, Word64)
5import Streamly.Test.Common (listEquals, checkListEqual, chooseInt, equals)
6import Test.Hspec (Spec, hspec, describe)
7import Test.Hspec.QuickCheck
8import Test.QuickCheck
9 (arbitrary, forAll, elements, Property,
10 property, listOf, vectorOf, (.&&.), Gen)
11import Test.QuickCheck.Monadic (monadicIO, assert, run)
13import qualified Data.List as List
14import qualified Prelude
15import qualified Streamly.Internal.Data.Array.Foreign as A
16import qualified Streamly.Internal.Data.Fold as FL
17import qualified Streamly.Internal.Data.Parser.ParserD as P
18import qualified Streamly.Internal.Data.Producer.Source as Source
19import qualified Streamly.Internal.Data.Producer as Producer
20import qualified Streamly.Internal.Data.Stream.IsStream as S
21import qualified Streamly.Internal.Data.Stream.StreamD as D
22import qualified Streamly.Internal.Data.Unfold as Unfold
23import qualified Test.Hspec as H
25import Prelude hiding (sequence)
27#if MIN_VERSION_QuickCheck(2,14,0)
29import Test.QuickCheck (chooseAny)
31#else
33import System.Random (Random(random))
34import Test.QuickCheck.Gen (Gen(MkGen))
36-- | Generates a random element over the natural range of `a`.
37chooseAny :: Random a => Gen a
38chooseAny = MkGen (\r _ -> let (x,_) = random r in x)
40#endif
42maxTestCount :: Int
43maxTestCount = 100
45min_value :: Int
46min_value = 0
48mid_value :: Int
49mid_value = 5000
51max_value :: Int
52max_value = 10000
54max_length :: Int
55max_length = 1000
57-- Accumulator Tests
59fromFold :: Property
60fromFold =
61 forAll (listOf $ chooseInt (min_value, max_value))
62 $ \ls ->
63 case (==) <$> (S.parseD (P.fromFold FL.sum) (S.fromList ls))
64 <*> (S.fold FL.sum (S.fromList ls)) of
65 Right is_equal -> is_equal
66 Left _ -> False
68fromPure :: Property
69fromPure =
70 forAll (chooseInt (min_value, max_value)) $ \x ->
71 case S.parseD (P.fromPure x) (S.fromList [1 :: Int]) of
72 Right r -> r == x
73 Left _ -> False
75fromEffect :: Property
76fromEffect =
77 forAll (chooseInt (min_value, max_value)) $ \x ->
78 case S.parseD (P.fromEffect $ return x) (S.fromList [1 :: Int]) of
79 Right r -> r == x
80 Left _ -> False
82die :: Property
83die =
84 property $
85 case S.parseD (P.die "die test") (S.fromList [0 :: Int]) of
86 Right _ -> False
87 Left _ -> True
89dieM :: Property
90dieM =
91 property $
92 case S.parseD (P.dieM (Right "die test")) (S.fromList [0 :: Int]) of
93 Right _ -> False
94 Left _ -> True
96-- Element Parser Tests
98peekPass :: Property
99peekPass =
100 forAll (chooseInt (1, max_length)) $ \list_length ->
101 forAll (vectorOf list_length (chooseInt (min_value, max_value))) $ \ls ->
102 case S.parseD P.peek (S.fromList ls) of
103 Right head_value -> case ls of
104 head_ls : _ -> head_value == head_ls
105 _ -> False
106 Left _ -> False
108peekFail :: Property
109peekFail =
110 property (case S.parseD P.peek (S.fromList []) of
111 Right _ -> False
112 Left _ -> True)
114eofPass :: Property
115eofPass =
116 property (case S.parseD P.eof (S.fromList []) of
117 Right _ -> True
118 Left _ -> False)
120eofFail :: Property
121eofFail =
122 forAll (chooseInt (1, max_length)) $ \list_length ->
123 forAll (vectorOf list_length (chooseInt (min_value, max_value))) $ \ls ->
124 case S.parseD P.eof (S.fromList ls) of
125 Right _ -> False
126 Left _ -> True
128satisfyPass :: Property
129satisfyPass =
130 forAll (chooseInt (mid_value, max_value)) $ \first_element ->
131 forAll (listOf (chooseInt (min_value, max_value))) $ \ls_tail ->
132 let
133 ls = first_element : ls_tail
134 predicate = (>= mid_value)
135 in
136 case S.parseD (P.satisfy predicate) (S.fromList ls) of
137 Right r -> r == first_element
138 Left _ -> False
140satisfy :: Property
141satisfy =
142 forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
143 case S.parseD (P.satisfy predicate) (S.fromList ls) of
144 Right r -> case ls of
145 [] -> False
146 (x : _) -> predicate x && (r == x)
147 Left _ -> case ls of
148 [] -> True
149 (x : _) -> not $ predicate x
150 where
151 predicate = (>= mid_value)
153-- Sequence Parsers Tests
154takeBetweenPass :: Property
155takeBetweenPass =
156 forAll (chooseInt (min_value, max_value)) $ \m ->
157 forAll (chooseInt (m, max_value)) $ \n ->
158 forAll (chooseInt (m, max_value)) $ \list_length ->
159 forAll (vectorOf list_length (chooseInt (min_value, max_value))) $ \ls ->
160 case S.parseD (P.takeBetween m n FL.toList) (S.fromList ls) of
161 Right parsed_list ->
162 let lpl = Prelude.length parsed_list
163 in checkListEqual parsed_list (Prelude.take lpl ls)
164 Left _ -> property False
167takeBetween :: Property
168takeBetween =
169 forAll (chooseInt (min_value, max_value)) $ \m ->
170 forAll (chooseInt (min_value, max_value)) $ \n ->
171 forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
172 let
173 list_length = Prelude.length ls
174 in
175 case S.parseD (P.takeBetween m n FL.toList) (S.fromList ls) of
176 Right parsed_list ->
177 if m <= list_length && n >= m
178 then
179 let lpl = Prelude.length parsed_list
180 in checkListEqual parsed_list (Prelude.take
181 lpl ls)
182 else property False
183 Left _ -> property (m > n || list_length < m)
185take :: Property
186take =
187 forAll (chooseInt (min_value, max_value)) $ \n ->
188 forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
189 case S.parseD (P.fromFold $ FL.take n FL.toList) (S.fromList ls) of
190 Right parsed_list -> checkListEqual parsed_list (Prelude.take n ls)
191 Left _ -> property False
193takeEQPass :: Property
194takeEQPass =
195 forAll (chooseInt (min_value, max_value)) $ \n ->
196 forAll (chooseInt (n, max_value)) $ \list_length ->
197 forAll (vectorOf list_length (chooseInt (min_value, max_value))) $ \ls ->
198 case S.parseD (P.takeEQ n FL.toList) (S.fromList ls) of
199 Right parsed_list -> checkListEqual parsed_list (Prelude.take n ls)
200 Left _ -> property False
202takeEQ :: Property
203takeEQ =
204 forAll (chooseInt (min_value, max_value)) $ \n ->
205 forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
206 let
207 list_length = Prelude.length ls
208 in
209 case S.parseD (P.takeEQ n FL.toList) (S.fromList ls) of
210 Right parsed_list ->
211 if (n <= list_length) then
212 checkListEqual parsed_list (Prelude.take n ls)
213 else
214 property False
215 Left _ -> property (n > list_length)
217takeGEPass :: Property
218takeGEPass =
219 forAll (chooseInt (min_value, max_value)) $ \n ->
220 forAll (chooseInt (n, max_value)) $ \list_length ->
221 forAll (vectorOf list_length (chooseInt (min_value, max_value))) $ \ls ->
222 case S.parseD (P.takeGE n FL.toList) (S.fromList ls) of
223 Right parsed_list -> checkListEqual parsed_list ls
224 Left _ -> property False
226takeGE :: Property
227takeGE =
228 forAll (chooseInt (min_value, max_value)) $ \n ->
229 forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
230 let
231 list_length = Prelude.length ls
232 in
233 case S.parseD (P.takeGE n FL.toList) (S.fromList ls) of
234 Right parsed_list ->
235 if (n <= list_length) then
236 checkListEqual parsed_list ls
237 else
238 property False
239 Left _ -> property (n > list_length)
241nLessThanEqual0 ::
242 ( Int
243 -> FL.Fold (Either SomeException) Int [Int]
244 -> P.Parser (Either SomeException) Int [Int]
245 )
246 -> (Int -> [Int] -> [Int])
247 -> Property
248nLessThanEqual0 tk ltk =
249 forAll (elements [0, (-1)]) $ \n ->
250 forAll (listOf arbitrary) $ \ls ->
251 case S.parseD (tk n FL.toList) (S.fromList ls) of
252 Right parsed_list -> checkListEqual parsed_list (ltk n ls)
253 Left _ -> property False
255takeProperties :: Spec
256takeProperties =
257 describe "take combinators when n <= 0/" $ do
258 prop "takeEQ n FL.toList = []" $
259 nLessThanEqual0 P.takeEQ (\_ -> const [])
260 prop "takeGE n FL.toList xs = xs" $
261 nLessThanEqual0 P.takeGE (\_ -> id)
264-- XXX lookAhead can't deal with EOF which in this case means when
265-- n==list_length, this test will fail. So excluding that case for now.
266lookAheadPass :: Property
267lookAheadPass =
268 forAll (chooseInt (min_value, max_value)) $ \n ->
269 let
270 takeWithoutConsume = P.lookAhead $ P.fromFold $ FL.take n FL.toList
271 parseTwice = do
272 parsed_list_1 <- takeWithoutConsume
273 parsed_list_2 <- takeWithoutConsume
274 return (parsed_list_1, parsed_list_2)
275 in
276 forAll (chooseInt (n+1, max_value)) $ \list_length ->
277 forAll (vectorOf list_length (chooseInt (min_value, max_value))) $ \ls ->
278 case S.parseD parseTwice (S.fromList ls) of
279 Right (ls_1, ls_2) -> checkListEqual ls_1 ls_2 .&&. checkListEqual ls_1 (Prelude.take n ls)
280 Left _ -> property $ False
282lookAhead :: Property
283lookAhead =
284 forAll (chooseInt (min_value, max_value)) $ \n ->
285 let
286 takeWithoutConsume = P.lookAhead $ P.fromFold $ FL.take n FL.toList
287 parseTwice = do
288 parsed_list_1 <- takeWithoutConsume
289 parsed_list_2 <- takeWithoutConsume
290 return (parsed_list_1, parsed_list_2)
291 in
292 forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
293 case S.parseD parseTwice (S.fromList ls) of
294 Right (ls_1, ls_2) -> checkListEqual ls_1 ls_2 .&&. checkListEqual ls_1 (Prelude.take n ls)
295 Left _ -> property ((list_length < n) || (list_length == n && n == 0))
296 where
297 list_length = Prelude.length ls
299takeWhile :: Property
300takeWhile =
301 forAll (listOf (chooseInt (0, 1))) $ \ ls ->
302 case S.parseD (P.takeWhile predicate FL.toList) (S.fromList ls) of
303 Right parsed_list -> checkListEqual parsed_list (Prelude.takeWhile predicate ls)
304 Left _ -> property False
305 where
306 predicate = (== 0)
308takeWhile1 :: Property
309takeWhile1 =
310 forAll (listOf (chooseInt (0, 1))) $ \ ls ->
311 case S.parseD (P.takeWhile1 predicate FL.toList) (S.fromList ls) of
312 Right parsed_list -> case ls of
313 [] -> property False
314 (x : _) ->
315 if predicate x then
316 checkListEqual parsed_list (Prelude.takeWhile predicate ls)
317 else
318 property False
319 Left _ -> case ls of
320 [] -> property True
321 (x : _) -> property (not $ predicate x)
322 where
323 predicate = (== 0)
325groupBy :: Property
326groupBy =
327 forAll (listOf (chooseInt (0, 1)))
328 $ \ls ->
329 case S.parseD parser (S.fromList ls) of
330 Right parsed -> checkListEqual parsed (groupByLF ls)
331 Left _ -> property False
333 where
335 cmp = (==)
336 parser = P.groupBy cmp FL.toList
337 groupByLF lst
338 | null lst = []
339 | otherwise = head $ List.groupBy cmp lst
341groupByRolling :: Property
342groupByRolling =
343 forAll (listOf (chooseInt (0, 1)))
344 $ \ls ->
345 case S.parseD parser (S.fromList ls) of
346 Right parsed -> checkListEqual parsed (groupByLF Nothing ls)
347 Left _ -> property False
349 where
351 cmp = (==)
352 parser = P.groupBy cmp FL.toList
353 groupByLF _ [] = []
354 groupByLF Nothing (x:xs) = x : groupByLF (Just x) xs
355 groupByLF (Just y) (x:xs) =
356 if cmp y x
357 then x : groupByLF (Just x) xs
358 else []
360takeEndByOrMax :: Property
361takeEndByOrMax =
362 forAll (chooseInt (min_value, max_value)) $ \n ->
363 forAll (listOf (chooseInt (0, 1))) $ \ls ->
364 case S.parseD (P.fromFold $ FL.takeEndBy_ predicate (FL.take n FL.toList)) (S.fromList ls) of
365 Right parsed_list -> checkListEqual parsed_list (Prelude.take n (Prelude.takeWhile (not . predicate) ls))
366 Left _ -> property False
367 where
368 predicate = (== 1)
370wordBy :: Property
371wordBy =
372 forAll (listOf (elements [' ', 's']))
373 $ \ls ->
374 case S.parseD parser (S.fromList ls) of
375 Right parsed -> checkListEqual parsed (words' ls)
376 Left _ -> property False
378 where
380 predicate = (== ' ')
381 parser = P.many (P.wordBy predicate FL.toList) FL.toList
382 words' lst =
383 let wrds = words lst
384 in if wrds == [] && length lst > 0 then [""] else wrds
387serialWith :: Property
388serialWith =
389 forAll (listOf (chooseInt (0, 1))) $ \ls ->
390 case S.parseD (P.serialWith (,) (P.satisfy (== 0)) (P.satisfy (== 1))) (S.fromList ls) of
391 Right (result_first, result_second) -> case ls of
392 0 : 1 : _ -> (result_first == 0) && (result_second == 1)
393 _ -> False
394 Left _ -> case ls of
395 0 : 1 : _ -> False
396 _ -> True
398splitWithFailLeft :: Property
399splitWithFailLeft =
400 property (case S.parseD (P.serialWith (,) (P.die "die") (P.fromPure (1 :: Int))) (S.fromList [1 :: Int]) of
401 Right _ -> False
402 Left _ -> True)
404splitWithFailRight :: Property
405splitWithFailRight =
406 property (case S.parseD (P.serialWith (,) (P.fromPure (1 :: Int)) (P.die "die")) (S.fromList [1 :: Int]) of
407 Right _ -> False
408 Left _ -> True)
410splitWithFailBoth :: Property
411splitWithFailBoth =
412 property (case S.parseD (P.serialWith (,) (P.die "die") (P.die "die")) (S.fromList [1 :: Int]) of
413 Right _ -> False
414 Left _ -> True)
416teeWithPass :: Property
417teeWithPass =
418 forAll (chooseInt (min_value, max_value)) $ \n ->
419 forAll (listOf (chooseInt (0, 1))) $ \ls ->
420 let
421 prsr = P.fromFold $ FL.take n FL.toList
422 in
423 case S.parseD (P.teeWith (,) prsr prsr) (S.fromList ls) of
424 Right (ls_1, ls_2) -> checkListEqual (Prelude.take n ls) ls_1 .&&. checkListEqual ls_1 ls_2
425 Left _ -> property False
427teeWithFailLeft :: Property
428teeWithFailLeft =
429 property (case S.parseD (P.teeWith (,) (P.die "die") (P.fromPure (1 :: Int))) (S.fromList [1 :: Int]) of
430 Right _ -> False
431 Left _ -> True)
433teeWithFailRight :: Property
434teeWithFailRight =
435 property (case S.parseD (P.teeWith (,) (P.fromPure (1 :: Int)) (P.die "die")) (S.fromList [1 :: Int]) of
436 Right _ -> False
437 Left _ -> True)
439teeWithFailBoth :: Property
440teeWithFailBoth =
441 property (case S.parseD (P.teeWith (,) (P.die "die") (P.die "die")) (S.fromList [1 :: Int]) of
442 Right _ -> False
443 Left _ -> True)
445shortestPass :: Property
446shortestPass =
447 forAll (listOf (chooseInt(min_value, max_value))) $ \ls ->
448 let
449 half_mid_value = mid_value `Prelude.div` 2
450 prsr_1 = P.takeWhile (<= half_mid_value) FL.toList
451 prsr_2 = P.takeWhile (<= mid_value) FL.toList
452 prsr_shortest = P.shortest prsr_1 prsr_2
453 in
454 case S.parseD prsr_shortest (S.fromList ls) of
455 Right short_list -> checkListEqual short_list (Prelude.takeWhile (<= half_mid_value) ls)
456 Left _ -> property False
458shortestPassLeft :: Property
459shortestPassLeft =
460 property (case S.parseD (P.shortest (P.die "die") (P.fromPure (1 :: Int))) (S.fromList [1 :: Int]) of
461 Right r -> r == 1
462 Left _ -> False)
464shortestPassRight :: Property
465shortestPassRight =
466 property (case S.parseD (P.shortest (P.fromPure (1 :: Int)) (P.die "die")) (S.fromList [1 :: Int]) of
467 Right r -> r == 1
468 Left _ -> False)
470shortestFailBoth :: Property
471shortestFailBoth =
472 property
473 (case S.parseD
474 (P.shortest (P.die "die") (P.die "die"))
475 (S.fromList [1 :: Int]) of
476 Right _ -> False
477 Left _ -> True)
479longestPass :: Property
480longestPass =
481 forAll (listOf (chooseInt(min_value, max_value))) $ \ls ->
482 let
483 half_mid_value = mid_value `Prelude.div` 2
484 prsr_1 = P.takeWhile (<= half_mid_value) FL.toList
485 prsr_2 = P.takeWhile (<= mid_value) FL.toList
486 prsr_longest = P.longest prsr_1 prsr_2
487 in
488 case S.parseD prsr_longest (S.fromList ls) of
489 Right long_list -> long_list == Prelude.takeWhile (<= mid_value) ls
490 Left _ -> False
492longestPassLeft :: Property
493longestPassLeft =
494 property (case S.parseD (P.shortest (P.die "die") (P.fromPure (1 :: Int))) (S.fromList [1 :: Int]) of
495 Right r -> r == 1
496 Left _ -> False)
498longestPassRight :: Property
499longestPassRight =
500 property (case S.parseD (P.shortest (P.fromPure (1 :: Int)) (P.die "die")) (S.fromList [1 :: Int]) of
501 Right r -> r == 1
502 Left _ -> False)
504longestFailBoth :: Property
505longestFailBoth =
506 property
507 (case S.parseD (P.shortest (P.die "die") (P.die "die")) (S.fromList [1 :: Int]) of
508 Right _ -> False
509 Left _ -> True)
511many :: Property
512many =
513 forAll (listOf (chooseInt (0, 1)))
514 $ \ls ->
515 let fldstp conL currL = return $ FL.Partial (conL ++ currL)
516 concatFold =
517 FL.Fold fldstp (return (FL.Partial [])) return
518 prsr =
519 flip P.many concatFold
520 $ P.fromFold $ FL.takeEndBy_ (== 1) FL.toList
521 in case S.parseD prsr (S.fromList ls) of
522 Right res_list ->
523 checkListEqual res_list (Prelude.filter (== 0) ls)
524 Left _ -> property False
526many_empty :: Property
527many_empty =
528 property (case S.parseD (flip P.many FL.toList (P.die "die")) (S.fromList [1 :: Int]) of
529 Right res_list -> checkListEqual res_list ([] :: [Int])
530 Left _ -> property False)
532some :: Property
533some =
534 forAll (listOf (chooseInt (0, 1)))
535 $ \ls ->
536 let fldstp conL currL = return $ FL.Partial $ conL ++ currL
537 concatFold = FL.Fold fldstp (return (FL.Partial [])) return
538 prsr =
539 flip P.some concatFold
540 $ P.fromFold $ FL.takeEndBy_ (== 1) FL.toList
541 in case S.parseD prsr (S.fromList ls) of
542 Right res_list -> res_list == Prelude.filter (== 0) ls
543 Left _ -> False
545someFail :: Property
546someFail =
547 property (case S.parseD (P.some (P.die "die") FL.toList) (S.fromList [1 :: Int]) of
548 Right _ -> False
549 Left _ -> True)
551-------------------------------------------------------------------------------
552-- Instances
553-------------------------------------------------------------------------------
555applicative :: Property
556applicative =
557 forAll (listOf (chooseAny :: Gen Int)) $ \ list1 ->
558 forAll (listOf (chooseAny :: Gen Int)) $ \ list2 ->
559 let parser =
560 (,)
561 <$> P.fromFold (FL.take (length list1) FL.toList)
562 <*> P.fromFold (FL.take (length list2) FL.toList)
563 in monadicIO $ do
564 (olist1, olist2) <-
565 run $ S.parseD parser (S.fromList $ list1 ++ list2)
566 listEquals (==) olist1 list1
567 listEquals (==) olist2 list2
569sequence :: Property
570sequence =
571 forAll (vectorOf 11 (listOf (chooseAny :: Gen Int))) $ \ ins ->
572 let parsers = fmap (\xs -> P.fromFold $ FL.take (length xs) FL.toList) ins
573 in monadicIO $ do
574 outs <- run $
575 S.parseD
576 (Prelude.sequence parsers)
577 (S.fromList $ concat ins)
578 listEquals (==) outs ins
580monad :: Property
581monad =
582 forAll (listOf (chooseAny :: Gen Int)) $ \ list1 ->
583 forAll (listOf (chooseAny :: Gen Int)) $ \ list2 ->
584 let parser = do
585 olist1 <- P.fromFold (FL.take (length list1) FL.toList)
586 olist2 <- P.fromFold (FL.take (length list2) FL.toList)
587 return (olist1, olist2)
588 in monadicIO $ do
589 (olist1, olist2) <-
590 run $ S.parseD parser (S.fromList $ list1 ++ list2)
591 listEquals (==) olist1 list1
592 listEquals (==) olist2 list2
594-------------------------------------------------------------------------------
595-- Stream parsing
596-------------------------------------------------------------------------------
598parseMany :: Property
599parseMany =
600 forAll (chooseInt (1,100)) $ \len ->
601 forAll (listOf (vectorOf len (chooseAny :: Gen Int))) $ \ ins ->
602 monadicIO $ do
603 outs <-
604 ( run
605 $ S.toList
606 $ S.parseManyD
607 (P.fromFold $ FL.take len FL.toList) (S.fromList $ concat ins)
608 )
609 listEquals (==) outs ins
611-- basic sanity test for parsing from arrays
612parseUnfold :: Property
613parseUnfold = do
614 let len = 200
615 -- ls = input list (stream)
616 -- clen = chunk size
617 -- tlen = parser take size
618 forAll
619 ((,,)
620 <$> vectorOf len (chooseAny :: Gen Int)
621 <*> chooseInt (1, len)
622 <*> chooseInt (1, len)) $ \(ls, clen, tlen) ->
623 monadicIO $ do
624 arrays <- S.toList $ S.arraysOf clen (S.fromList ls)
625 let src = Source.source (Just (Producer.OuterLoop arrays))
626 let parser = P.fromFold (FL.take tlen FL.toList)
627 let readSrc =
628 Source.producer
629 $ Producer.concat Producer.fromList A.producer
630 let streamParser =
631 Producer.simplify (Source.parseManyD parser readSrc)
632 xs <- run
633 $ S.toList
634 $ S.unfoldMany Unfold.fromList
635 $ S.unfold streamParser src
637 listEquals (==) xs ls
639parserSequence :: Property
640parserSequence =
641 forAll (vectorOf 11 (listOf (chooseAny :: Gen Int))) $ \ins ->
642 monadicIO $ do
643 let parsers = D.fromList
644 $ fmap (\xs -> P.fromFold $ FL.take (length xs) FL.sum) ins
645 let sequencedParser = P.sequence FL.sum parsers
646 outs <-
647 run $
648 S.parseD sequencedParser $ S.concatMap S.fromList (S.fromList ins)
649 equals (==) outs (sum $ map sum ins)
651-------------------------------------------------------------------------------
652-- Test for a particular case hit during fs events testing
653-------------------------------------------------------------------------------
655evId :: [Word8]
656evId = [96,238,17,9,0,0,0,0]
658evFlags :: [Word8]
659evFlags = [0,4,1,0,0,0,0,0]
661evPathLen :: [Word8]
662evPathLen = [71,0,0,0,0,0,0,0]
664evPath :: [Word8]
665evPath =
666 [47,85,115,101,114,115,47,118,111,108,47,118,101,109,98,97,47,99,111,109
667 ,112,111,115,101,119,101 ,108,108,45,116,101,99,104,47,69,110,103,47,112
668 ,114,111,106,101,99,116,115,47,115,116,114,101,97,109,108,121,47,115,116
669 ,114,101,97,109,108,121,47,116,109,112,47,122,122
670 ]
672event :: [Word8]
673event = evId ++ evFlags ++ evPathLen ++ evPath
675data Event = Event
676 { eventId :: Word64
677 , eventFlags :: Word32
678 , eventAbsPath :: A.Array Word8
679 } deriving (Show, Ord, Eq)
681readOneEvent :: P.Parser IO Word8 Event
682readOneEvent = do
683 arr <- P.takeEQ 24 (A.writeN 24)
684 let arr1 = A.castUnsafe arr :: A.Array Word64
685 eid = A.unsafeIndex 0 arr1
686 eflags = A.unsafeIndex 1 arr1
687 pathLen = fromIntegral $ A.unsafeIndex 2 arr1
688 path <- P.takeEQ pathLen (A.writeN pathLen)
689 return $ Event
690 { eventId = eid
691 , eventFlags = fromIntegral eflags
692 , eventAbsPath = path
693 }
695parseMany2Events :: Property
696parseMany2Events =
697 monadicIO $ do
698 xs <-
699 ( run
700 $ S.toList
701 $ S.parseManyD readOneEvent
702 $ S.fromList (concat (replicate 2 event))
703 )
704 assert (length xs == 2)
705 -- XXX assuming little endian machine
706 let ev = Event
707 { eventId = 152170080
708 , eventFlags = 66560
709 , eventAbsPath = A.fromList evPath
710 }
711 in listEquals (==) xs (replicate 2 ev)
713-------------------------------------------------------------------------------
714-- Main
715-------------------------------------------------------------------------------
717moduleName :: String
718moduleName = "Data.Parser.ParserD"
720main :: IO ()
721main =
722 hspec $
723 H.parallel $
724 modifyMaxSuccess (const maxTestCount) $ do
725 describe moduleName $ do
727 describe "Instances" $ do
728 prop "applicative" applicative
729 prop "monad" monad
730 prop "sequence" sequence
732 describe "Stream parsing" $ do
733 prop "parseMany" parseMany
734 prop "parseMany2Events" parseMany2Events
735 prop "parseUnfold" parseUnfold
736 prop "parserSequence" parserSequence
738 describe "test for accumulator" $ do
739 prop "P.fromFold FL.sum = FL.sum" fromFold
740 prop "fromPure value provided" fromPure
741 prop "fromPure monadic value provided" fromEffect
742 prop "always fail" die
743 prop "always fail but monadic" dieM
745 describe "test for element parser" $ do
746 prop "peek = head with list length > 0" peekPass
747 prop "peek fail on []" peekFail
748 prop "eof pass on []" eofPass
749 prop "eof fail on non-empty list" eofFail
750 prop "first element exists and >= mid_value" satisfyPass
751 prop "check first element exists and satisfies predicate" satisfy
753 describe "test for sequence parser" $ do
754 prop "P.takeBetween m n = Prelude.take when len >= m and len <= n"
755 takeBetweenPass
756 prop "P.takeBetween m n = Prelude.take when len >= m and len <= n and\
757 \fail otherwise" takeBetween
758 prop "P.take = Prelude.take" Main.take
759 prop "P.takeEQ = Prelude.take when len >= n" takeEQPass
760 prop "P.takeEQ = Prelude.take when len >= n and fail otherwise" Main.takeEQ
761 prop "P.takeGE n ls = ls when len >= n" takeGEPass
762 prop "P.takeGE n ls = ls when len >= n and fail otherwise" Main.takeGE
763 prop "lookAhead . take n >> lookAhead . take n = lookAhead . take n" lookAheadPass
764 prop "lookAhead . take n >> lookAhead . take n = lookAhead . take n, else fail" lookAhead
765 prop "P.takeWhile = Prelude.takeWhile" Main.takeWhile
766 prop "P.takeWhile1 = Prelude.takeWhile if taken something, else check why failed" takeWhile1
767 prop "P.groupBy = Prelude.head . Prelude.groupBy" groupBy
768 prop "groupByRolling" groupByRolling
769 prop "P.takeEndByOrMax = Prelude.take n (Prelude.takeWhile (not . predicate)" takeEndByOrMax
770 prop "many (P.wordBy ' ') = words'" wordBy
771 prop "parse 0, then 1, else fail" serialWith
772 prop "fail due to die as left parser" splitWithFailLeft
773 prop "fail due to die as right parser" splitWithFailRight
774 prop "fail due to die as both parsers" splitWithFailBoth
775 prop "parsed two lists should be equal" teeWithPass
776 prop "fail due to die as left parser" teeWithFailLeft
777 prop "fail due to die as right parser" teeWithFailRight
778 prop "fail due to die as both parsers" teeWithFailBoth
779 prop "P.takeWhile (<= half_mid_value) = Prelude.takeWhile half_mid_value" shortestPass
780 prop "pass even if die is left parser" shortestPassLeft
781 prop "pass even if die is right parser" shortestPassRight
782 prop "fail due to die as both parsers" shortestFailBoth
783 prop "P.takeWhile (<= mid_value) = Prelude.takeWhile (<= mid_value)" longestPass
784 prop "pass even if die is left parser" longestPassLeft
785 prop "pass even if die is right parser" longestPassRight
786 prop "fail due to die as both parsers" longestFailBoth
787 prop "P.many concatFold $ P.takeEndBy_ (== 1) FL.toList = Prelude.filter (== 0)" many
788 prop "[] due to parser being die" many_empty
789 prop "P.some concatFold $ P.takeEndBy_ (== 1) FL.toList = Prelude.filter (== 0)" some
790 prop "fail due to parser being die" someFail
791 takeProperties