on 28fe29b help sign in
794 lines 29 kB history raw
1module Main (main) where
3import Control.Exception (SomeException(..), displayException)
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, property, listOf,
10 vectorOf, Gen)
11import Test.QuickCheck.Monadic (monadicIO, assert, run)
13import Prelude hiding (sequence)
15import qualified Data.List as List
16import qualified Prelude
17import qualified Streamly.Internal.Data.Array.Foreign as A
18import qualified Streamly.Internal.Data.Fold as FL
19import qualified Streamly.Internal.Data.Parser as P
20import qualified Streamly.Internal.Data.Stream.IsStream as S
21import qualified Test.Hspec as H
23#if MIN_VERSION_QuickCheck(2,14,0)
25import Test.QuickCheck (chooseAny)
27#else
29import System.Random (Random(random))
30import Test.QuickCheck.Gen (Gen(MkGen))
32-- | Generates a random element over the natural range of `a`.
33chooseAny :: Random a => Gen a
34chooseAny = MkGen (\r _ -> let (x,_) = random r in x)
36#endif
39maxTestCount :: Int
40maxTestCount = 100
42min_value :: Int
43min_value = 0
45mid_value :: Int
46mid_value = 5000
48max_value :: Int
49max_value = 10000
51max_length :: Int
52max_length = 1000
54-- Accumulator Tests
56fromFold :: Property
57fromFold =
58 forAll (listOf $ chooseInt (min_value, max_value)) $ \ls ->
59 case (==) <$> S.parse (P.fromFold FL.sum) (S.fromList ls)
60 <*> S.fold FL.sum (S.fromList ls) of
61 Right is_equal -> is_equal
62 Left _ -> False
64fromPure :: Property
65fromPure =
66 forAll (chooseInt (min_value, max_value)) $ \x ->
67 case S.parse (P.fromPure x) (S.fromList [1 :: Int]) of
68 Right r -> r == x
69 Left _ -> False
71fromEffect :: Property
72fromEffect =
73 forAll (chooseInt (min_value, max_value)) $ \x ->
74 case S.parse (P.fromEffect $ return x) (S.fromList [1 :: Int]) of
75 Right r -> r == x
76 Left _ -> False
78die :: Property
79die =
80 property $
81 case S.parse (P.die "die test") (S.fromList [0 :: Int]) of
82 Right _ -> False
83 Left _ -> True
85dieM :: Property
86dieM =
87 property $
88 case S.parse (P.dieM (Right "die test")) (S.fromList [0 :: Int]) of
89 Right _ -> False
90 Left _ -> True
92parserFail :: Property
93parserFail =
94 property $
95 case S.parse (fail err) (S.fromList [0 :: Int]) of
96 Right _ -> False
97 Left (SomeException e) -> err == displayException e
98 where
99 err = "Testing MonadFail.fail."
101-- Element Parser Tests
103peekPass :: Property
104peekPass =
105 forAll (chooseInt (1, max_length)) $ \list_length ->
106 forAll (vectorOf list_length (chooseInt (min_value, max_value))) $ \ls ->
107 case S.parse P.peek (S.fromList ls) of
108 Right head_value -> case ls of
109 head_ls : _ -> head_value == head_ls
110 _ -> False
111 Left _ -> False
113peekFail :: Property
114peekFail =
115 property (case S.parse P.peek (S.fromList []) of
116 Right _ -> False
117 Left _ -> True)
119eofPass :: Property
120eofPass =
121 property (case S.parse P.eof (S.fromList []) of
122 Right _ -> True
123 Left _ -> False)
125eofFail :: Property
126eofFail =
127 forAll (chooseInt (1, max_length)) $ \list_length ->
128 forAll (vectorOf list_length (chooseInt (min_value, max_value))) $ \ls ->
129 case S.parse P.eof (S.fromList ls) of
130 Right _ -> False
131 Left _ -> True
133satisfyPass :: Property
134satisfyPass =
135 forAll (chooseInt (mid_value, max_value)) $ \first_element ->
136 forAll (listOf (chooseInt (min_value, max_value))) $ \ls_tail ->
137 let
138 ls = first_element : ls_tail
139 predicate = (>= mid_value)
140 in
141 case S.parse (P.satisfy predicate) (S.fromList ls) of
142 Right r -> r == first_element
143 Left _ -> False
145satisfy :: Property
146satisfy =
147 forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
148 case S.parse (P.satisfy predicate) (S.fromList ls) of
149 Right r -> case ls of
150 [] -> False
151 (x : _) -> predicate x && (r == x)
152 Left _ -> case ls of
153 [] -> True
154 (x : _) -> not $ predicate x
155 where
156 predicate = (>= mid_value)
158-- Sequence Parsers Tests
159takeBetweenPass :: Property
160takeBetweenPass =
161 forAll (chooseInt (min_value, max_value)) $ \m ->
162 forAll (chooseInt (m, max_value)) $ \n ->
163 forAll (chooseInt (m, max_value)) $ \list_length ->
164 forAll (vectorOf list_length (chooseInt (min_value, max_value)))
165 $ \ls ->
166 case S.parse (P.takeBetween m n FL.toList)
167 (S.fromList ls) of
168 Right parsed_list ->
169 let lpl = Prelude.length parsed_list
170 in checkListEqual parsed_list
171 $ Prelude.take lpl ls
172 Left _ -> property False
174takeBetween :: Property
175takeBetween =
176 forAll (chooseInt (min_value, max_value)) $ \m ->
177 forAll (chooseInt (min_value, max_value)) $ \n ->
178 forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
179 go m n ls
181 where
183 go m n ls =
184 let inputLen = Prelude.length ls
185 in case S.parse (P.takeBetween m n FL.toList) (S.fromList ls) of
186 Right xs ->
187 let parsedLen = Prelude.length xs
188 in if inputLen >= m && parsedLen >= m && parsedLen <= n
189 then checkListEqual xs $ Prelude.take parsedLen ls
190 else property False
191 Left _ ->
192 property ((m >= 0 && n >= 0 && m > n) || inputLen < m)
194takeEQPass :: Property
195takeEQPass =
196 forAll (chooseInt (min_value, max_value)) $ \n ->
197 forAll (chooseInt (n, max_value)) $ \list_length ->
198 forAll (vectorOf list_length
199 (chooseInt (min_value, max_value))) $ \ls ->
200 case S.parse (P.takeEQ n FL.toList) (S.fromList ls) of
201 Right parsed_list ->
202 checkListEqual parsed_list (Prelude.take n ls)
203 Left _ -> property False
205takeEQ :: Property
206takeEQ =
207 forAll (chooseInt (min_value, max_value)) $ \n ->
208 forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
209 let
210 list_length = Prelude.length ls
211 in
212 case S.parse (P.takeEQ n FL.toList) (S.fromList ls) of
213 Right parsed_list ->
214 if n <= list_length
215 then checkListEqual parsed_list (Prelude.take n ls)
216 else property False
217 Left _ -> property (n > list_length)
219takeGEPass :: Property
220takeGEPass =
221 forAll (chooseInt (min_value, max_value)) $ \n ->
222 forAll (chooseInt (n, max_value)) $ \list_length ->
223 forAll (vectorOf list_length (chooseInt (min_value, max_value)))
224 $ \ls ->
225 case S.parse (P.takeGE n FL.toList) (S.fromList ls) of
226 Right parsed_list -> checkListEqual parsed_list ls
227 Left _ -> property False
229takeGE :: Property
230takeGE =
231 forAll (chooseInt (min_value, max_value)) $ \n ->
232 forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
233 let
234 list_length = Prelude.length ls
235 in
236 case S.parse (P.takeGE n FL.toList) (S.fromList ls) of
237 Right parsed_list ->
238 if n <= list_length
239 then checkListEqual parsed_list ls
240 else property False
241 Left _ -> property (n > list_length)
243nLessThanEqual0 ::
244 ( Int
245 -> FL.Fold (Either SomeException) Int [Int]
246 -> P.Parser (Either SomeException) Int [Int]
247 )
248 -> (Int -> [Int] -> [Int])
249 -> Property
250nLessThanEqual0 tk ltk =
251 forAll (elements [0, (-1)]) $ \n ->
252 forAll (listOf arbitrary) $ \ls ->
253 case S.parse (tk n FL.toList) (S.fromList ls) of
254 Right parsed_list -> checkListEqual parsed_list (ltk n ls)
255 Left _ -> property False
257takeProperties :: Spec
258takeProperties =
259 describe "take combinators when n <= 0/" $ do
260 prop "takeEQ n FL.toList = []" $
261 nLessThanEqual0 P.takeEQ (\_ -> const [])
262 prop "takeGE n FL.toList xs = xs" $
263 nLessThanEqual0 P.takeGE (\_ -> id)
265-- lookAheadPass :: Property
266-- lookAheadPass =
267-- forAll (chooseInt (min_value + 1, max_value)) $ \n ->
268-- let
269-- takeWithoutConsume = P.lookAhead $ P.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, max_value)) $ \list_length ->
276-- forAll (vectorOf list_length (chooseInt (min_value, max_value))) $ \ls ->
277-- case S.parse 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
281-- lookAheadFail :: Property
282-- lookAheadFail =
283-- forAll (chooseInt (min_value + 1, max_value)) $ \n ->
284-- let
285-- takeWithoutConsume = P.lookAhead $ P.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 (chooseInt (min_value, n - 1)) $ \list_length ->
292-- forAll (vectorOf list_length (chooseInt (min_value, max_value))) $ \ls ->
293-- case S.parse parseTwice (S.fromList ls) of
294-- Right _ -> False
295-- Left _ -> True
297-- lookAhead :: Property
298-- lookAhead =
299-- forAll (chooseInt (min_value, max_value)) $ \n ->
300-- let
301-- takeWithoutConsume = P.lookAhead $ P.take n FL.toList
302-- parseTwice = do
303-- parsed_list_1 <- takeWithoutConsume
304-- parsed_list_2 <- takeWithoutConsume
305-- return (parsed_list_1, parsed_list_2)
306-- in
307-- forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
308-- case S.parse parseTwice (S.fromList ls) of
309-- Right (ls_1, ls_2) -> checkListEqual ls_1 ls_2 .&&. checkListEqual ls_1 (Prelude.take n ls)
310-- Left _ -> property ((list_length < n) || (list_length == n && n == 0))
311-- where
312-- list_length = Prelude.length ls
314sliceSepByP :: Property
315sliceSepByP =
316 forAll (listOf (chooseInt (min_value, max_value ))) $ \ls ->
317 case S.parse (P.sliceSepByP predicate prsr) (S.fromList ls) of
318 Right parsed_list ->
319 checkListEqual parsed_list (tkwhl ls)
320 Left _ -> property False
321 where
322 predicate = (>= 100)
323 prsr = P.many (P.satisfy (const True)) FL.toList
324 tkwhl ls = Prelude.takeWhile (not . predicate) ls
326sliceBeginWith :: Property
327sliceBeginWith =
328 forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
329 let ls1 = 1:ls
330 in
331 case S.parse parser (S.fromList ls1) of
332 Right parsed_list ->
333 if not $ Prelude.null ls1
334 then
335 let tls = Prelude.takeWhile (not . predicate) (tail ls1)
336 in checkListEqual parsed_list $
337 if predicate (head ls1)
338 then head ls1 : tls
339 else Prelude.takeWhile (not . predicate) ls1
340 else property $ Prelude.null parsed_list
341 Left _ -> property False
342 where
343 predicate = odd
344 parser = P.sliceBeginWith predicate FL.toList
346takeWhile :: Property
347takeWhile =
348 forAll (listOf (chooseInt (0, 1))) $ \ ls ->
349 case S.parse (P.takeWhile predicate FL.toList) (S.fromList ls) of
350 Right parsed_list ->
351 checkListEqual parsed_list (Prelude.takeWhile predicate ls)
352 Left _ -> property False
353 where
354 predicate = (== 0)
356takeP :: Property
357takeP =
358 forAll
359 ((,) <$> chooseInt (min_value, max_value)
360 <*> listOf (chooseInt (0, 1)))
361 $ \(takeNum, ls) ->
362 case S.parse
363 (P.takeP takeNum (P.fromFold FL.toList))
364 (S.fromList ls) of
365 Right parsed_list ->
366 checkListEqual parsed_list (Prelude.take takeNum ls)
367 Left _ -> property False
369takeWhile1 :: Property
370takeWhile1 =
371 forAll (listOf (chooseInt (0, 1))) $ \ ls ->
372 case S.parse (P.takeWhile1 predicate FL.toList) (S.fromList ls) of
373 Right parsed_list -> case ls of
374 [] -> property False
375 (x : _) ->
376 if predicate x
377 then
378 checkListEqual parsed_list
379 $ Prelude.takeWhile predicate ls
380 else
381 property False
382 Left _ -> case ls of
383 [] -> property True
384 (x : _) -> property (not $ predicate x)
385 where
386 predicate = (== 0)
388choice :: Property
389choice =
390 forAll
391 ((,,) <$> chooseInt (min_value, max_value)
392 <*> chooseInt (min_value, max_value)
393 <*> listOf (chooseInt (0, 1)))
394 $ \(i, j, ls) ->
395 case S.parse (P.choice [parser i, parser j]) (S.fromList ls) of
396 Right parsed_list ->
397 checkListEqual parsed_list $ take (min i j) ls
398 Left _ -> property False
400 where
402 parser i = P.fromFold (FL.take i FL.toList)
404groupBy :: Property
405groupBy =
406 forAll (listOf (chooseInt (0, 1)))
407 $ \ls ->
408 case S.parse parser (S.fromList ls) of
409 Right parsed -> checkListEqual parsed (groupByLF ls)
410 Left _ -> property False
412 where
414 cmp = (==)
415 parser = P.groupBy cmp FL.toList
416 groupByLF lst
417 | null lst = []
418 | otherwise = head $ List.groupBy cmp lst
420wordBy :: Property
421wordBy =
422 forAll (listOf (elements [' ', 's']))
423 $ \ls ->
424 case S.parse parser (S.fromList ls) of
425 Right parsed -> checkListEqual parsed (words' ls)
426 Left _ -> property False
428 where
430 predicate = (== ' ')
431 parser = P.many (P.wordBy predicate FL.toList) FL.toList
432 words' lst =
433 let wrds = words lst
434 in if wrds == [] && length lst > 0 then [""] else wrds
436-- splitWithPass :: Property
437-- splitWithPass =
438-- forAll (listOf (chooseInt (0, 1))) $ \ls ->
439-- case S.parse (P.serialWith (,) (P.satisfy (== 0)) (P.satisfy (== 1))) (S.fromList ls) of
440-- Right (result_first, result_second) -> case ls of
441-- 0 : 1 : _ -> (result_first == 0) && (result_second == 1)
442-- _ -> False
443-- Left _ -> case ls of
444-- 0 : 1 : _ -> False
445-- _ -> True
447-- splitWithFailLeft :: Property
448-- splitWithFailLeft =
449-- property (case S.parse (P.serialWith (,) (P.die "die") (P.fromPure (1 :: Int))) (S.fromList [1 :: Int]) of
450-- Right _ -> False
451-- Left _ -> True)
453-- splitWithFailRight :: Property
454-- splitWithFailRight =
455-- property (case S.parse (P.serialWith (,) (P.fromPure (1 :: Int)) (P.die "die")) (S.fromList [1 :: Int]) of
456-- Right _ -> False
457-- Left _ -> True)
459-- splitWithFailBoth :: Property
460-- splitWithFailBoth =
461-- property (case S.parse (P.serialWith (,) (P.die "die") (P.die "die")) (S.fromList [1 :: Int]) of
462-- Right _ -> False
463-- Left _ -> True)
465-- teeWithPass :: Property
466-- teeWithPass =
467-- forAll (chooseInt (0, 10000)) $ \n ->
468-- forAll (listOf (chooseInt (0, 1))) $ \ls ->
469-- let
470-- prsr = P.take n FL.toList
471-- in
472-- case S.parse (P.teeWith (,) prsr prsr) (S.fromList ls) of
473-- Right (ls_1, ls_2) -> checkListEqual (Prelude.take n ls) ls_1 .&&. checkListEqual ls_1 ls_2
474-- Left _ -> property False
476-- teeWithFailLeft :: Property
477-- teeWithFailLeft =
478-- property (case S.parse (P.teeWith (,) (P.die "die") (P.fromPure (1 :: Int))) (S.fromList [1 :: Int]) of
479-- Right _ -> False
480-- Left _ -> True)
482-- teeWithFailRight :: Property
483-- teeWithFailRight =
484-- property (case S.parse (P.teeWith (,) (P.fromPure (1 :: Int)) (P.die "die")) (S.fromList [1 :: Int]) of
485-- Right _ -> False
486-- Left _ -> True)
488-- teeWithFailBoth :: Property
489-- teeWithFailBoth =
490-- property (case S.parse (P.teeWith (,) (P.die "die") (P.die "die")) (S.fromList [1 :: Int]) of
491-- Right _ -> False
492-- Left _ -> True)
494-- deintercalate :: Property
495-- deintercalate =
496-- forAll (listOf (chooseInt (0, 1))) $ \ls ->
497-- case S.parse (P.deintercalate concatFold prsr_1 concatFold prsr_2) (S.fromList ls) of
498-- Right parsed_list_tuple -> parsed_list_tuple == (partition (== 0) ls)
499-- Left _ -> False
501-- where
502-- prsr_1 = (P.takeWhile (== 0) FL.toList)
503-- prsr_2 = (P.takeWhile (== 1) FL.toList)
504-- concatFold = FL.Fold (\concatList curr_list -> return $ concatList ++ curr_list) (return []) return
506-- shortestPass :: Property
507-- shortestPass =
508-- forAll (listOf (chooseInt(min_value, max_value))) $ \ls ->
509-- let
510-- prsr_1 = P.takeWhile (<= (mid_value `Prelude.div` 2)) FL.toList
511-- prsr_2 = P.takeWhile (<= mid_value) FL.toList
512-- prsr_shortest = P.shortest prsr_1 prsr_2
513-- in
514-- case S.parse prsr_shortest (S.fromList ls) of
515-- Right short_list -> checkListEqual short_list (Prelude.takeWhile (<= 2500) ls)
516-- Left _ -> property False
518-- shortestFailLeft :: Property
519-- shortestFailLeft =
520-- property (case S.parse (P.shortest (P.die "die") (P.fromPure (1 :: Int))) (S.fromList [1 :: Int]) of
521-- Right r -> r == 1
522-- Left _ -> False)
524-- shortestFailRight :: Property
525-- shortestFailRight =
526-- property (case S.parse (P.shortest (P.fromPure (1 :: Int)) (P.die "die")) (S.fromList [1 :: Int]) of
527-- Right r -> r == 1
528-- Left _ -> False)
530-- shortestFailBoth :: Property
531-- shortestFailBoth =
532-- property (case S.parse (P.shortest (P.die "die") (P.die "die")) (S.fromList [1 :: Int]) of
533-- Right _ -> False
534-- Left _ -> True)
536many :: Property
537many =
538 forAll (listOf (chooseInt (0, 1))) $ \ls ->
539 let fldstp conL currL = return $ FL.Partial $ conL ++ currL
540 concatFold = FL.Fold fldstp (return (FL.Partial [])) return
541 prsr =
542 flip P.many concatFold $ P.fromFold $ FL.takeEndBy_ (== 1) FL.toList
543 in
544 case S.parse prsr (S.fromList ls) of
545 Right res_list -> checkListEqual res_list
546 $ Prelude.filter (== 0) ls
547 Left _ -> property False
549-- many_empty :: Property
550-- many_empty =
551-- property (case S.parse (P.many FL.toList (P.die "die")) (S.fromList [1 :: Int]) of
552-- Right res_list -> checkListEqual res_list ([] :: [Int])
553-- Left _ -> property False)
555some :: Property
556some =
557 forAll (listOf (chooseInt (0, 1))) $ \genLs ->
558 let
559 ls = 0 : genLs
560 fldstp conL currL = return $ FL.Partial $ conL ++ currL
561 concatFold = FL.Fold fldstp (return (FL.Partial [])) return
562 prsr =
563 flip P.some concatFold $ P.fromFold $ FL.takeEndBy_ (== 1) FL.toList
564 in
565 case S.parse prsr (S.fromList ls) of
566 Right res_list -> res_list == Prelude.filter (== 0) ls
567 Left _ -> False
569-- someFail :: Property
570-- someFail =
571-- property (case S.parse (P.some FL.toList (P.die "die")) (S.fromList [1 :: Int]) of
572-- Right _ -> False
573-- Left _ -> True)
575-------------------------------------------------------------------------------
576-- Instances
577-------------------------------------------------------------------------------
579applicative :: Property
580applicative =
581 forAll (listOf (chooseAny :: Gen Int)) $ \ list1 ->
582 forAll (listOf (chooseAny :: Gen Int)) $ \ list2 ->
583 let parser =
584 (,)
585 <$> P.fromFold (FL.take (length list1) FL.toList)
586 <*> P.fromFold (FL.take (length list2) FL.toList)
587 in monadicIO $ do
588 (olist1, olist2) <-
589 run $ S.parse parser (S.fromList $ list1 ++ list2)
590 listEquals (==) olist1 list1
591 listEquals (==) olist2 list2
593sequence :: Property
594sequence =
595 forAll (vectorOf 11 (listOf (chooseAny :: Gen Int))) $ \ ins ->
596 let p xs = P.fromFold (FL.take (length xs) FL.toList)
597 in monadicIO $ do
598 outs <- run $
599 S.parse
600 (Prelude.sequence $ fmap p ins)
601 (S.fromList $ concat ins)
602 listEquals (==) outs ins
604monad :: Property
605monad =
606 forAll (listOf (chooseAny :: Gen Int)) $ \ list1 ->
607 forAll (listOf (chooseAny :: Gen Int)) $ \ list2 ->
608 let parser = do
609 olist1 <- P.fromFold (FL.take (length list1) FL.toList)
610 olist2 <- P.fromFold (FL.take (length list2) FL.toList)
611 return (olist1, olist2)
612 in monadicIO $ do
613 (olist1, olist2) <-
614 run $ S.parse parser (S.fromList $ list1 ++ list2)
615 listEquals (==) olist1 list1
616 listEquals (==) olist2 list2
618-------------------------------------------------------------------------------
619-- Stream parsing
620-------------------------------------------------------------------------------
622parseMany :: Property
623parseMany =
624 forAll (chooseInt (1,100)) $ \len ->
625 forAll (listOf (vectorOf len (chooseAny :: Gen Int))) $ \ ins ->
626 monadicIO $ do
627 outs <- do
628 let p = P.fromFold $ FL.take len FL.toList
629 run
630 $ S.toList
631 $ S.parseMany p (S.fromList $ concat ins)
632 listEquals (==) outs ins
634-------------------------------------------------------------------------------
635-- Test for a particular case hit during fs events testing
636-------------------------------------------------------------------------------
638evId :: [Word8]
639evId = [96,238,17,9,0,0,0,0]
641evFlags :: [Word8]
642evFlags = [0,4,1,0,0,0,0,0]
644evPathLen :: [Word8]
645evPathLen = [71,0,0,0,0,0,0,0]
647evPath :: [Word8]
648evPath =
649 [47,85,115,101,114,115,47,118,111,108,47,118,101,109,98,97,47,99,111,109
650 ,112,111,115,101,119,101 ,108,108,45,116,101,99,104,47,69,110,103,47,112
651 ,114,111,106,101,99,116,115,47,115,116,114,101,97,109,108,121,47,115,116
652 ,114,101,97,109,108,121,47,116,109,112,47,122,122
653 ]
655event :: [Word8]
656event = evId ++ evFlags ++ evPathLen ++ evPath
658data Event = Event
659 { eventId :: Word64
660 , eventFlags :: Word32
661 , eventAbsPath :: A.Array Word8
662 } deriving (Show, Ord, Eq)
664readOneEvent :: P.Parser IO Word8 Event
665readOneEvent = do
666 arr <- P.takeEQ 24 (A.writeN 24)
667 let arr1 = A.unsafeCast arr :: A.Array Word64
668 eid = A.unsafeIndex arr1 0
669 eflags = A.unsafeIndex arr1 1
670 pathLen = fromIntegral $ A.unsafeIndex arr1 2
671 -- XXX handle if pathLen is 0
672 path <- P.takeEQ pathLen (A.writeN pathLen)
673 return $ Event
674 { eventId = eid
675 , eventFlags = fromIntegral eflags
676 , eventAbsPath = path
677 }
679parseMany2Events :: Property
680parseMany2Events =
681 monadicIO $ do
682 xs <-
683 ( run
684 $ S.toList
685 $ S.parseMany readOneEvent
686 $ S.fromList (concat (replicate 2 event))
687 )
688 assert (length xs == 2)
689 -- XXX assuming little endian machine
690 let ev = Event
691 { eventId = 152170080
692 , eventFlags = 66560
693 , eventAbsPath = A.fromList evPath
694 }
695 in listEquals (==) xs (replicate 2 ev)
697manyEqParseMany :: Property
698manyEqParseMany =
699 forAll (listOf (chooseInt (0, 100))) $ \lst ->
700 forAll (chooseInt (1, 100)) $ \i ->
701 monadicIO $ do
702 let strm = S.fromList lst
703 r1 <- run $ S.parse (P.many (split i) FL.toList) strm
704 r2 <- run $ S.toList $ S.parseMany (split i) strm
705 assert $ r1 == r2
707 where
709 split i = P.fromFold (FL.take i FL.toList)
711-------------------------------------------------------------------------------
712-- Main
713-------------------------------------------------------------------------------
715moduleName :: String
716moduleName = "Data.Parser"
718main :: IO ()
719main =
720 hspec $
721 H.parallel $
722 modifyMaxSuccess (const maxTestCount) $ do
723 describe moduleName $ do
725 describe "Instances" $ do
726 prop "applicative" applicative
727 prop "monad" monad
728 prop "sequence" sequence
730 describe "Stream parsing" $ do
731 prop "parseMany" parseMany
732 prop "parseMany2Events" parseMany2Events
734 describe "test for accumulator" $ do
735 prop "P.fromFold FL.sum = FL.sum" fromFold
736 prop "fromPure value provided" fromPure
737 prop "fromPure monadic value provided" fromEffect
738 prop "fail err = Left (SomeException (ParseError err))" parserFail
739 prop "always fail" die
740 prop "always fail but monadic" dieM
742 describe "test for element parser" $ do
743 prop "peek = head with list length > 0" peekPass
744 prop "peek fail on []" peekFail
745 prop "eof pass on []" eofPass
746 prop "eof fail on non-empty list" eofFail
747 prop "first element exists and >= mid_value" satisfyPass
748 prop "check first element exists and satisfies predicate" satisfy
750 describe "test for sequence parser" $ do
751 prop "P.takeBetween = Prelude.take when len >= m and len <= n"
752 takeBetweenPass
753 prop ("P.takeBetween = Prelude.take when len >= m and len <= n and fail"
754 ++ "otherwise fail") Main.takeBetween
756 prop "P.takeEQ = Prelude.take when len >= n" takeEQPass
757 prop "P.takeEQ = Prelude.take when len >= n and fail otherwise"
758 Main.takeEQ
759 prop "P.takeGE n ls = ls when len >= n" takeGEPass
760 prop "P.takeGE n ls = ls when len >= n and fail otherwise" Main.takeGE
761 -- prop "lookAhead . take n >> lookAhead . take n = lookAhead . take n" lookAheadPass
762 -- prop "Fail when stream length exceeded" lookAheadFail
763 -- prop "lookAhead . take n >> lookAhead . take n = lookAhead . take n, else fail" lookAhead
764 prop "P.sliceSepByP test" Main.sliceSepByP
765 prop ("P.sliceBeginWith pred = head : Prelude.takeWhile (not . pred)"
766 ++ " tail") sliceBeginWith
767 prop "P.takeWhile = Prelude.takeWhile" Main.takeWhile
768 prop ("P.takeWhile1 = Prelude.takeWhile if taken something,"
769 ++ " else check why failed") takeWhile1
770 prop ("P.takeP = Prelude.take") takeP
771 prop "P.groupBy = Prelude.head . Prelude.groupBy" groupBy
772 prop "many (P.wordBy ' ') = words'" wordBy
773 prop "choice" choice
774 -- prop "" splitWithPass
775 -- prop "" splitWithFailLeft
776 -- prop "" splitWithFailRight
777 -- prop "" splitWithFailBoth
778 -- prop "" teeWithPass
779 -- prop "" teeWithFailLeft
780 -- prop "" teeWithFailRight
781 -- prop "" teeWithFailBoth
782 -- prop "" deintercalate
783 -- prop "" shortestPass
784 -- prop "" shortestFailLeft
785 -- prop "" shortestFailRight
786 -- prop "" shortestFailBoth
787 prop ("P.many concatFold $ P.takeEndBy_ (== 1) FL.toList ="
788 ++ "Prelude.filter (== 0)") many
789 -- prop "[] due to parser being die" many_empty
790 prop ("P.some concatFold $ P.takeEndBy_ (== 1) FL.toList ="
791 ++ "Prelude.filter (== 0)") some
792 -- prop "fail due to parser being die" someFail
793 prop "P.many == S.parseMany" manyEqParseMany
794 takeProperties