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