on 7b5bc73 help sign in
764 lines 28 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 let
180 list_length = Prelude.length ls
181 in
182 case S.parse (P.takeBetween m n FL.toList)
183 (S.fromList ls) of
184 Right parsed_list ->
185 if m <= list_length && n >= list_length
186 then
187 let lpl = Prelude.length parsed_list
188 in checkListEqual parsed_list
189 $ Prelude.take lpl ls
190 else property False
191 Left _ -> property (m > n || list_length < 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)
356takeWhile1 :: Property
357takeWhile1 =
358 forAll (listOf (chooseInt (0, 1))) $ \ ls ->
359 case S.parse (P.takeWhile1 predicate FL.toList) (S.fromList ls) of
360 Right parsed_list -> case ls of
361 [] -> property False
362 (x : _) ->
363 if predicate x
364 then
365 checkListEqual parsed_list
366 $ Prelude.takeWhile predicate ls
367 else
368 property False
369 Left _ -> case ls of
370 [] -> property True
371 (x : _) -> property (not $ predicate x)
372 where
373 predicate = (== 0)
375groupBy :: Property
376groupBy =
377 forAll (listOf (chooseInt (0, 1)))
378 $ \ls ->
379 case S.parse parser (S.fromList ls) of
380 Right parsed -> checkListEqual parsed (groupByLF ls)
381 Left _ -> property False
383 where
385 cmp = (==)
386 parser = P.groupBy cmp FL.toList
387 groupByLF lst
388 | null lst = []
389 | otherwise = head $ List.groupBy cmp lst
392wordBy :: Property
393wordBy =
394 forAll (listOf (elements [' ', 's']))
395 $ \ls ->
396 case S.parse parser (S.fromList ls) of
397 Right parsed -> checkListEqual parsed (words' ls)
398 Left _ -> property False
400 where
402 predicate = (== ' ')
403 parser = P.many (P.wordBy predicate FL.toList) FL.toList
404 words' lst =
405 let wrds = words lst
406 in if wrds == [] && length lst > 0 then [""] else wrds
408-- splitWithPass :: Property
409-- splitWithPass =
410-- forAll (listOf (chooseInt (0, 1))) $ \ls ->
411-- case S.parse (P.serialWith (,) (P.satisfy (== 0)) (P.satisfy (== 1))) (S.fromList ls) of
412-- Right (result_first, result_second) -> case ls of
413-- 0 : 1 : _ -> (result_first == 0) && (result_second == 1)
414-- _ -> False
415-- Left _ -> case ls of
416-- 0 : 1 : _ -> False
417-- _ -> True
419-- splitWithFailLeft :: Property
420-- splitWithFailLeft =
421-- property (case S.parse (P.serialWith (,) (P.die "die") (P.fromPure (1 :: Int))) (S.fromList [1 :: Int]) of
422-- Right _ -> False
423-- Left _ -> True)
425-- splitWithFailRight :: Property
426-- splitWithFailRight =
427-- property (case S.parse (P.serialWith (,) (P.fromPure (1 :: Int)) (P.die "die")) (S.fromList [1 :: Int]) of
428-- Right _ -> False
429-- Left _ -> True)
431-- splitWithFailBoth :: Property
432-- splitWithFailBoth =
433-- property (case S.parse (P.serialWith (,) (P.die "die") (P.die "die")) (S.fromList [1 :: Int]) of
434-- Right _ -> False
435-- Left _ -> True)
437-- teeWithPass :: Property
438-- teeWithPass =
439-- forAll (chooseInt (0, 10000)) $ \n ->
440-- forAll (listOf (chooseInt (0, 1))) $ \ls ->
441-- let
442-- prsr = P.take n FL.toList
443-- in
444-- case S.parse (P.teeWith (,) prsr prsr) (S.fromList ls) of
445-- Right (ls_1, ls_2) -> checkListEqual (Prelude.take n ls) ls_1 .&&. checkListEqual ls_1 ls_2
446-- Left _ -> property False
448-- teeWithFailLeft :: Property
449-- teeWithFailLeft =
450-- property (case S.parse (P.teeWith (,) (P.die "die") (P.fromPure (1 :: Int))) (S.fromList [1 :: Int]) of
451-- Right _ -> False
452-- Left _ -> True)
454-- teeWithFailRight :: Property
455-- teeWithFailRight =
456-- property (case S.parse (P.teeWith (,) (P.fromPure (1 :: Int)) (P.die "die")) (S.fromList [1 :: Int]) of
457-- Right _ -> False
458-- Left _ -> True)
460-- teeWithFailBoth :: Property
461-- teeWithFailBoth =
462-- property (case S.parse (P.teeWith (,) (P.die "die") (P.die "die")) (S.fromList [1 :: Int]) of
463-- Right _ -> False
464-- Left _ -> True)
466-- deintercalate :: Property
467-- deintercalate =
468-- forAll (listOf (chooseInt (0, 1))) $ \ls ->
469-- case S.parse (P.deintercalate concatFold prsr_1 concatFold prsr_2) (S.fromList ls) of
470-- Right parsed_list_tuple -> parsed_list_tuple == (partition (== 0) ls)
471-- Left _ -> False
473-- where
474-- prsr_1 = (P.takeWhile (== 0) FL.toList)
475-- prsr_2 = (P.takeWhile (== 1) FL.toList)
476-- concatFold = FL.Fold (\concatList curr_list -> return $ concatList ++ curr_list) (return []) return
478-- shortestPass :: Property
479-- shortestPass =
480-- forAll (listOf (chooseInt(min_value, max_value))) $ \ls ->
481-- let
482-- prsr_1 = P.takeWhile (<= (mid_value `Prelude.div` 2)) FL.toList
483-- prsr_2 = P.takeWhile (<= mid_value) FL.toList
484-- prsr_shortest = P.shortest prsr_1 prsr_2
485-- in
486-- case S.parse prsr_shortest (S.fromList ls) of
487-- Right short_list -> checkListEqual short_list (Prelude.takeWhile (<= 2500) ls)
488-- Left _ -> property False
490-- shortestFailLeft :: Property
491-- shortestFailLeft =
492-- property (case S.parse (P.shortest (P.die "die") (P.fromPure (1 :: Int))) (S.fromList [1 :: Int]) of
493-- Right r -> r == 1
494-- Left _ -> False)
496-- shortestFailRight :: Property
497-- shortestFailRight =
498-- property (case S.parse (P.shortest (P.fromPure (1 :: Int)) (P.die "die")) (S.fromList [1 :: Int]) of
499-- Right r -> r == 1
500-- Left _ -> False)
502-- shortestFailBoth :: Property
503-- shortestFailBoth =
504-- property (case S.parse (P.shortest (P.die "die") (P.die "die")) (S.fromList [1 :: Int]) of
505-- Right _ -> False
506-- Left _ -> True)
508many :: Property
509many =
510 forAll (listOf (chooseInt (0, 1))) $ \ls ->
511 let fldstp conL currL = return $ FL.Partial $ conL ++ currL
512 concatFold = FL.Fold fldstp (return (FL.Partial [])) return
513 prsr =
514 flip P.many concatFold $ P.fromFold $ FL.takeEndBy_ (== 1) FL.toList
515 in
516 case S.parse prsr (S.fromList ls) of
517 Right res_list -> checkListEqual res_list
518 $ Prelude.filter (== 0) ls
519 Left _ -> property False
521-- many_empty :: Property
522-- many_empty =
523-- property (case S.parse (P.many FL.toList (P.die "die")) (S.fromList [1 :: Int]) of
524-- Right res_list -> checkListEqual res_list ([] :: [Int])
525-- Left _ -> property False)
527some :: Property
528some =
529 forAll (listOf (chooseInt (0, 1))) $ \genLs ->
530 let
531 ls = 0 : genLs
532 fldstp conL currL = return $ FL.Partial $ conL ++ currL
533 concatFold = FL.Fold fldstp (return (FL.Partial [])) return
534 prsr =
535 flip P.some concatFold $ P.fromFold $ FL.takeEndBy_ (== 1) FL.toList
536 in
537 case S.parse prsr (S.fromList ls) of
538 Right res_list -> res_list == Prelude.filter (== 0) ls
539 Left _ -> False
541-- someFail :: Property
542-- someFail =
543-- property (case S.parse (P.some FL.toList (P.die "die")) (S.fromList [1 :: Int]) of
544-- Right _ -> False
545-- Left _ -> True)
547-------------------------------------------------------------------------------
548-- Instances
549-------------------------------------------------------------------------------
551applicative :: Property
552applicative =
553 forAll (listOf (chooseAny :: Gen Int)) $ \ list1 ->
554 forAll (listOf (chooseAny :: Gen Int)) $ \ list2 ->
555 let parser =
556 (,)
557 <$> P.fromFold (FL.take (length list1) FL.toList)
558 <*> P.fromFold (FL.take (length list2) FL.toList)
559 in monadicIO $ do
560 (olist1, olist2) <-
561 run $ S.parse parser (S.fromList $ list1 ++ list2)
562 listEquals (==) olist1 list1
563 listEquals (==) olist2 list2
565sequence :: Property
566sequence =
567 forAll (vectorOf 11 (listOf (chooseAny :: Gen Int))) $ \ ins ->
568 let p xs = P.fromFold (FL.take (length xs) FL.toList)
569 in monadicIO $ do
570 outs <- run $
571 S.parse
572 (Prelude.sequence $ fmap p ins)
573 (S.fromList $ concat ins)
574 listEquals (==) outs ins
576monad :: Property
577monad =
578 forAll (listOf (chooseAny :: Gen Int)) $ \ list1 ->
579 forAll (listOf (chooseAny :: Gen Int)) $ \ list2 ->
580 let parser = do
581 olist1 <- P.fromFold (FL.take (length list1) FL.toList)
582 olist2 <- P.fromFold (FL.take (length list2) FL.toList)
583 return (olist1, olist2)
584 in monadicIO $ do
585 (olist1, olist2) <-
586 run $ S.parse parser (S.fromList $ list1 ++ list2)
587 listEquals (==) olist1 list1
588 listEquals (==) olist2 list2
590-------------------------------------------------------------------------------
591-- Stream parsing
592-------------------------------------------------------------------------------
594parseMany :: Property
595parseMany =
596 forAll (chooseInt (1,100)) $ \len ->
597 forAll (listOf (vectorOf len (chooseAny :: Gen Int))) $ \ ins ->
598 monadicIO $ do
599 outs <- do
600 let p = P.fromFold $ FL.take len FL.toList
601 run
602 $ S.toList
603 $ S.parseMany p (S.fromList $ concat ins)
604 listEquals (==) outs ins
606-------------------------------------------------------------------------------
607-- Test for a particular case hit during fs events testing
608-------------------------------------------------------------------------------
610evId :: [Word8]
611evId = [96,238,17,9,0,0,0,0]
613evFlags :: [Word8]
614evFlags = [0,4,1,0,0,0,0,0]
616evPathLen :: [Word8]
617evPathLen = [71,0,0,0,0,0,0,0]
619evPath :: [Word8]
620evPath =
621 [47,85,115,101,114,115,47,118,111,108,47,118,101,109,98,97,47,99,111,109
622 ,112,111,115,101,119,101 ,108,108,45,116,101,99,104,47,69,110,103,47,112
623 ,114,111,106,101,99,116,115,47,115,116,114,101,97,109,108,121,47,115,116
624 ,114,101,97,109,108,121,47,116,109,112,47,122,122
625 ]
627event :: [Word8]
628event = evId ++ evFlags ++ evPathLen ++ evPath
630data Event = Event
631 { eventId :: Word64
632 , eventFlags :: Word32
633 , eventAbsPath :: A.Array Word8
634 } deriving (Show, Ord, Eq)
636readOneEvent :: P.Parser IO Word8 Event
637readOneEvent = do
638 arr <- P.takeEQ 24 (A.writeN 24)
639 let arr1 = A.unsafeCast arr :: A.Array Word64
640 eid = A.unsafeIndex arr1 0
641 eflags = A.unsafeIndex arr1 1
642 pathLen = fromIntegral $ A.unsafeIndex arr1 2
643 -- XXX handle if pathLen is 0
644 path <- P.takeEQ pathLen (A.writeN pathLen)
645 return $ Event
646 { eventId = eid
647 , eventFlags = fromIntegral eflags
648 , eventAbsPath = path
649 }
651parseMany2Events :: Property
652parseMany2Events =
653 monadicIO $ do
654 xs <-
655 ( run
656 $ S.toList
657 $ S.parseMany readOneEvent
658 $ S.fromList (concat (replicate 2 event))
659 )
660 assert (length xs == 2)
661 -- XXX assuming little endian machine
662 let ev = Event
663 { eventId = 152170080
664 , eventFlags = 66560
665 , eventAbsPath = A.fromList evPath
666 }
667 in listEquals (==) xs (replicate 2 ev)
669manyEqParseMany :: Property
670manyEqParseMany =
671 forAll (listOf (chooseInt (0, 100))) $ \lst ->
672 forAll (chooseInt (1, 100)) $ \i ->
673 monadicIO $ do
674 let strm = S.fromList lst
675 r1 <- run $ S.parse (P.many (split i) FL.toList) strm
676 r2 <- run $ S.toList $ S.parseMany (split i) strm
677 assert $ r1 == r2
679 where
681 split i = P.fromFold (FL.take i FL.toList)
683-------------------------------------------------------------------------------
684-- Main
685-------------------------------------------------------------------------------
687moduleName :: String
688moduleName = "Data.Parser"
690main :: IO ()
691main =
692 hspec $
693 H.parallel $
694 modifyMaxSuccess (const maxTestCount) $ do
695 describe moduleName $ do
697 describe "Instances" $ do
698 prop "applicative" applicative
699 prop "monad" monad
700 prop "sequence" sequence
702 describe "Stream parsing" $ do
703 prop "parseMany" parseMany
704 prop "parseMany2Events" parseMany2Events
706 describe "test for accumulator" $ do
707 prop "P.fromFold FL.sum = FL.sum" fromFold
708 prop "fromPure value provided" fromPure
709 prop "fromPure monadic value provided" fromEffect
710 prop "fail err = Left (SomeException (ParseError err))" parserFail
711 prop "always fail" die
712 prop "always fail but monadic" dieM
714 describe "test for element parser" $ do
715 prop "peek = head with list length > 0" peekPass
716 prop "peek fail on []" peekFail
717 prop "eof pass on []" eofPass
718 prop "eof fail on non-empty list" eofFail
719 prop "first element exists and >= mid_value" satisfyPass
720 prop "check first element exists and satisfies predicate" satisfy
722 describe "test for sequence parser" $ do
723 prop "P.takeBetween = Prelude.take when len >= m and len <= n"
724 takeBetweenPass
725 prop ("P.takeBetween = Prelude.take when len >= m and len <= n and fail"
726 ++ "otherwise fail") Main.takeBetween
728 prop "P.takeEQ = Prelude.take when len >= n" takeEQPass
729 prop "P.takeEQ = Prelude.take when len >= n and fail otherwise"
730 Main.takeEQ
731 prop "P.takeGE n ls = ls when len >= n" takeGEPass
732 prop "P.takeGE n ls = ls when len >= n and fail otherwise" Main.takeGE
733 -- prop "lookAhead . take n >> lookAhead . take n = lookAhead . take n" lookAheadPass
734 -- prop "Fail when stream length exceeded" lookAheadFail
735 -- prop "lookAhead . take n >> lookAhead . take n = lookAhead . take n, else fail" lookAhead
736 prop "P.sliceSepByP test" Main.sliceSepByP
737 prop ("P.sliceBeginWith pred = head : Prelude.takeWhile (not . pred)"
738 ++ " tail") sliceBeginWith
739 prop "P.takeWhile = Prelude.takeWhile" Main.takeWhile
740 prop ("P.takeWhile1 = Prelude.takeWhile if taken something,"
741 ++ " else check why failed") takeWhile1
742 prop "P.groupBy = Prelude.head . Prelude.groupBy" groupBy
743 prop "many (P.wordBy ' ') = words'" wordBy
744 -- prop "" splitWithPass
745 -- prop "" splitWithFailLeft
746 -- prop "" splitWithFailRight
747 -- prop "" splitWithFailBoth
748 -- prop "" teeWithPass
749 -- prop "" teeWithFailLeft
750 -- prop "" teeWithFailRight
751 -- prop "" teeWithFailBoth
752 -- prop "" deintercalate
753 -- prop "" shortestPass
754 -- prop "" shortestFailLeft
755 -- prop "" shortestFailRight
756 -- prop "" shortestFailBoth
757 prop ("P.many concatFold $ P.takeEndBy_ (== 1) FL.toList ="
758 ++ "Prelude.filter (== 0)") many
759 -- prop "[] due to parser being die" many_empty
760 prop ("P.some concatFold $ P.takeEndBy_ (== 1) FL.toList ="
761 ++ "Prelude.filter (== 0)") some
762 -- prop "fail due to parser being die" someFail
763 prop "P.many == S.parseMany" manyEqParseMany
764 takeProperties