on fe89e02 help sign in
809 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)
158nextPass :: Property
159nextPass =
160 forAll (chooseInt (1, max_value)) $ \int ->
161 property (case S.parse P.next (S.fromList [int]) of
162 Right (Just i) -> i == int
163 _ -> False)
165next :: Property
166next =
167 property (case S.parse P.next (S.fromList []) of
168 Right Nothing -> True
169 _ -> False)
171-- Sequence Parsers Tests
172takeBetweenPass :: Property
173takeBetweenPass =
174 forAll (chooseInt (min_value, max_value)) $ \m ->
175 forAll (chooseInt (m, max_value)) $ \n ->
176 forAll (chooseInt (m, max_value)) $ \list_length ->
177 forAll (vectorOf list_length (chooseInt (min_value, max_value)))
178 $ \ls ->
179 case S.parse (P.takeBetween m n FL.toList)
180 (S.fromList ls) of
181 Right parsed_list ->
182 let lpl = Prelude.length parsed_list
183 in checkListEqual parsed_list
184 $ Prelude.take lpl ls
185 Left _ -> property False
187takeBetween :: Property
188takeBetween =
189 forAll (chooseInt (min_value, max_value)) $ \m ->
190 forAll (chooseInt (min_value, max_value)) $ \n ->
191 forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
192 go m n ls
194 where
196 go m n ls =
197 let inputLen = Prelude.length ls
198 in case S.parse (P.takeBetween m n FL.toList) (S.fromList ls) of
199 Right xs ->
200 let parsedLen = Prelude.length xs
201 in if inputLen >= m && parsedLen >= m && parsedLen <= n
202 then checkListEqual xs $ Prelude.take parsedLen ls
203 else property False
204 Left _ ->
205 property ((m >= 0 && n >= 0 && m > n) || inputLen < m)
207takeEQPass :: Property
208takeEQPass =
209 forAll (chooseInt (min_value, max_value)) $ \n ->
210 forAll (chooseInt (n, max_value)) $ \list_length ->
211 forAll (vectorOf list_length
212 (chooseInt (min_value, max_value))) $ \ls ->
213 case S.parse (P.takeEQ n FL.toList) (S.fromList ls) of
214 Right parsed_list ->
215 checkListEqual parsed_list (Prelude.take n ls)
216 Left _ -> property False
218takeEQ :: Property
219takeEQ =
220 forAll (chooseInt (min_value, max_value)) $ \n ->
221 forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
222 let
223 list_length = Prelude.length ls
224 in
225 case S.parse (P.takeEQ n FL.toList) (S.fromList ls) of
226 Right parsed_list ->
227 if n <= list_length
228 then checkListEqual parsed_list (Prelude.take n ls)
229 else property False
230 Left _ -> property (n > list_length)
232takeGEPass :: Property
233takeGEPass =
234 forAll (chooseInt (min_value, max_value)) $ \n ->
235 forAll (chooseInt (n, max_value)) $ \list_length ->
236 forAll (vectorOf list_length (chooseInt (min_value, max_value)))
237 $ \ls ->
238 case S.parse (P.takeGE n FL.toList) (S.fromList ls) of
239 Right parsed_list -> checkListEqual parsed_list ls
240 Left _ -> property False
242takeGE :: Property
243takeGE =
244 forAll (chooseInt (min_value, max_value)) $ \n ->
245 forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
246 let
247 list_length = Prelude.length ls
248 in
249 case S.parse (P.takeGE n FL.toList) (S.fromList ls) of
250 Right parsed_list ->
251 if n <= list_length
252 then checkListEqual parsed_list ls
253 else property False
254 Left _ -> property (n > list_length)
256nLessThanEqual0 ::
257 ( Int
258 -> FL.Fold (Either SomeException) Int [Int]
259 -> P.Parser (Either SomeException) Int [Int]
260 )
261 -> (Int -> [Int] -> [Int])
262 -> Property
263nLessThanEqual0 tk ltk =
264 forAll (elements [0, (-1)]) $ \n ->
265 forAll (listOf arbitrary) $ \ls ->
266 case S.parse (tk n FL.toList) (S.fromList ls) of
267 Right parsed_list -> checkListEqual parsed_list (ltk n ls)
268 Left _ -> property False
270takeProperties :: Spec
271takeProperties =
272 describe "take combinators when n <= 0/" $ do
273 prop "takeEQ n FL.toList = []" $
274 nLessThanEqual0 P.takeEQ (\_ -> const [])
275 prop "takeGE n FL.toList xs = xs" $
276 nLessThanEqual0 P.takeGE (\_ -> id)
278-- lookAheadPass :: Property
279-- lookAheadPass =
280-- forAll (chooseInt (min_value + 1, max_value)) $ \n ->
281-- let
282-- takeWithoutConsume = P.lookAhead $ P.take n FL.toList
283-- parseTwice = do
284-- parsed_list_1 <- takeWithoutConsume
285-- parsed_list_2 <- takeWithoutConsume
286-- return (parsed_list_1, parsed_list_2)
287-- in
288-- forAll (chooseInt (n, max_value)) $ \list_length ->
289-- forAll (vectorOf list_length (chooseInt (min_value, max_value))) $ \ls ->
290-- case S.parse parseTwice (S.fromList ls) of
291-- Right (ls_1, ls_2) -> checkListEqual ls_1 ls_2 .&&. checkListEqual ls_1 (Prelude.take n ls)
292-- Left _ -> property $ False
294-- lookAheadFail :: Property
295-- lookAheadFail =
296-- forAll (chooseInt (min_value + 1, max_value)) $ \n ->
297-- let
298-- takeWithoutConsume = P.lookAhead $ P.take n FL.toList
299-- parseTwice = do
300-- parsed_list_1 <- takeWithoutConsume
301-- parsed_list_2 <- takeWithoutConsume
302-- return (parsed_list_1, parsed_list_2)
303-- in
304-- forAll (chooseInt (min_value, n - 1)) $ \list_length ->
305-- forAll (vectorOf list_length (chooseInt (min_value, max_value))) $ \ls ->
306-- case S.parse parseTwice (S.fromList ls) of
307-- Right _ -> False
308-- Left _ -> True
310-- lookAhead :: Property
311-- lookAhead =
312-- forAll (chooseInt (min_value, max_value)) $ \n ->
313-- let
314-- takeWithoutConsume = P.lookAhead $ P.take n FL.toList
315-- parseTwice = do
316-- parsed_list_1 <- takeWithoutConsume
317-- parsed_list_2 <- takeWithoutConsume
318-- return (parsed_list_1, parsed_list_2)
319-- in
320-- forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
321-- case S.parse parseTwice (S.fromList ls) of
322-- Right (ls_1, ls_2) -> checkListEqual ls_1 ls_2 .&&. checkListEqual ls_1 (Prelude.take n ls)
323-- Left _ -> property ((list_length < n) || (list_length == n && n == 0))
324-- where
325-- list_length = Prelude.length ls
327sliceSepByP :: Property
328sliceSepByP =
329 forAll (listOf (chooseInt (min_value, max_value ))) $ \ls ->
330 case S.parse (P.sliceSepByP predicate prsr) (S.fromList ls) of
331 Right parsed_list ->
332 checkListEqual parsed_list (tkwhl ls)
333 Left _ -> property False
334 where
335 predicate = (>= 100)
336 prsr = P.many (P.satisfy (const True)) FL.toList
337 tkwhl ls = Prelude.takeWhile (not . predicate) ls
339sliceBeginWith :: Property
340sliceBeginWith =
341 forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
342 let ls1 = 1:ls
343 in
344 case S.parse parser (S.fromList ls1) of
345 Right parsed_list ->
346 if not $ Prelude.null ls1
347 then
348 let tls = Prelude.takeWhile (not . predicate) (tail ls1)
349 in checkListEqual parsed_list $
350 if predicate (head ls1)
351 then head ls1 : tls
352 else Prelude.takeWhile (not . predicate) ls1
353 else property $ Prelude.null parsed_list
354 Left _ -> property False
355 where
356 predicate = odd
357 parser = P.sliceBeginWith predicate FL.toList
359takeWhile :: Property
360takeWhile =
361 forAll (listOf (chooseInt (0, 1))) $ \ ls ->
362 case S.parse (P.takeWhile predicate FL.toList) (S.fromList ls) of
363 Right parsed_list ->
364 checkListEqual parsed_list (Prelude.takeWhile predicate ls)
365 Left _ -> property False
366 where
367 predicate = (== 0)
369takeP :: Property
370takeP =
371 forAll
372 ((,) <$> chooseInt (min_value, max_value)
373 <*> listOf (chooseInt (0, 1)))
374 $ \(takeNum, ls) ->
375 case S.parse
376 (P.takeP takeNum (P.fromFold FL.toList))
377 (S.fromList ls) of
378 Right parsed_list ->
379 checkListEqual parsed_list (Prelude.take takeNum ls)
380 Left _ -> property False
382takeWhile1 :: Property
383takeWhile1 =
384 forAll (listOf (chooseInt (0, 1))) $ \ ls ->
385 case S.parse (P.takeWhile1 predicate FL.toList) (S.fromList ls) of
386 Right parsed_list -> case ls of
387 [] -> property False
388 (x : _) ->
389 if predicate x
390 then
391 checkListEqual parsed_list
392 $ Prelude.takeWhile predicate ls
393 else
394 property False
395 Left _ -> case ls of
396 [] -> property True
397 (x : _) -> property (not $ predicate x)
398 where
399 predicate = (== 0)
401choice :: Property
402choice =
403 forAll
404 ((,,) <$> chooseInt (min_value, max_value)
405 <*> chooseInt (min_value, max_value)
406 <*> listOf (chooseInt (0, 1)))
407 $ \(i, j, ls) ->
408 case S.parse (P.choice [parser i, parser j]) (S.fromList ls) of
409 Right parsed_list ->
410 checkListEqual parsed_list $ take (min i j) ls
411 Left _ -> property False
413 where
415 parser i = P.fromFold (FL.take i FL.toList)
417groupBy :: Property
418groupBy =
419 forAll (listOf (chooseInt (0, 1)))
420 $ \ls ->
421 case S.parse parser (S.fromList ls) of
422 Right parsed -> checkListEqual parsed (groupByLF ls)
423 Left _ -> property False
425 where
427 cmp = (==)
428 parser = P.groupBy cmp FL.toList
429 groupByLF lst
430 | null lst = []
431 | otherwise = head $ List.groupBy cmp lst
433wordBy :: Property
434wordBy =
435 forAll (listOf (elements [' ', 's']))
436 $ \ls ->
437 case S.parse parser (S.fromList ls) of
438 Right parsed -> checkListEqual parsed (words' ls)
439 Left _ -> property False
441 where
443 predicate = (== ' ')
444 parser = P.many (P.wordBy predicate FL.toList) FL.toList
445 words' lst =
446 let wrds = words lst
447 in if wrds == [] && length lst > 0 then [""] else wrds
449-- splitWithPass :: Property
450-- splitWithPass =
451-- forAll (listOf (chooseInt (0, 1))) $ \ls ->
452-- case S.parse (P.serialWith (,) (P.satisfy (== 0)) (P.satisfy (== 1))) (S.fromList ls) of
453-- Right (result_first, result_second) -> case ls of
454-- 0 : 1 : _ -> (result_first == 0) && (result_second == 1)
455-- _ -> False
456-- Left _ -> case ls of
457-- 0 : 1 : _ -> False
458-- _ -> True
460-- splitWithFailLeft :: Property
461-- splitWithFailLeft =
462-- property (case S.parse (P.serialWith (,) (P.die "die") (P.fromPure (1 :: Int))) (S.fromList [1 :: Int]) of
463-- Right _ -> False
464-- Left _ -> True)
466-- splitWithFailRight :: Property
467-- splitWithFailRight =
468-- property (case S.parse (P.serialWith (,) (P.fromPure (1 :: Int)) (P.die "die")) (S.fromList [1 :: Int]) of
469-- Right _ -> False
470-- Left _ -> True)
472-- splitWithFailBoth :: Property
473-- splitWithFailBoth =
474-- property (case S.parse (P.serialWith (,) (P.die "die") (P.die "die")) (S.fromList [1 :: Int]) of
475-- Right _ -> False
476-- Left _ -> True)
478-- teeWithPass :: Property
479-- teeWithPass =
480-- forAll (chooseInt (0, 10000)) $ \n ->
481-- forAll (listOf (chooseInt (0, 1))) $ \ls ->
482-- let
483-- prsr = P.take n FL.toList
484-- in
485-- case S.parse (P.teeWith (,) prsr prsr) (S.fromList ls) of
486-- Right (ls_1, ls_2) -> checkListEqual (Prelude.take n ls) ls_1 .&&. checkListEqual ls_1 ls_2
487-- Left _ -> property False
489-- teeWithFailLeft :: Property
490-- teeWithFailLeft =
491-- property (case S.parse (P.teeWith (,) (P.die "die") (P.fromPure (1 :: Int))) (S.fromList [1 :: Int]) of
492-- Right _ -> False
493-- Left _ -> True)
495-- teeWithFailRight :: Property
496-- teeWithFailRight =
497-- property (case S.parse (P.teeWith (,) (P.fromPure (1 :: Int)) (P.die "die")) (S.fromList [1 :: Int]) of
498-- Right _ -> False
499-- Left _ -> True)
501-- teeWithFailBoth :: Property
502-- teeWithFailBoth =
503-- property (case S.parse (P.teeWith (,) (P.die "die") (P.die "die")) (S.fromList [1 :: Int]) of
504-- Right _ -> False
505-- Left _ -> True)
507-- deintercalate :: Property
508-- deintercalate =
509-- forAll (listOf (chooseInt (0, 1))) $ \ls ->
510-- case S.parse (P.deintercalate concatFold prsr_1 concatFold prsr_2) (S.fromList ls) of
511-- Right parsed_list_tuple -> parsed_list_tuple == (partition (== 0) ls)
512-- Left _ -> False
514-- where
515-- prsr_1 = (P.takeWhile (== 0) FL.toList)
516-- prsr_2 = (P.takeWhile (== 1) FL.toList)
517-- concatFold = FL.Fold (\concatList curr_list -> return $ concatList ++ curr_list) (return []) return
519-- shortestPass :: Property
520-- shortestPass =
521-- forAll (listOf (chooseInt(min_value, max_value))) $ \ls ->
522-- let
523-- prsr_1 = P.takeWhile (<= (mid_value `Prelude.div` 2)) FL.toList
524-- prsr_2 = P.takeWhile (<= mid_value) FL.toList
525-- prsr_shortest = P.shortest prsr_1 prsr_2
526-- in
527-- case S.parse prsr_shortest (S.fromList ls) of
528-- Right short_list -> checkListEqual short_list (Prelude.takeWhile (<= 2500) ls)
529-- Left _ -> property False
531-- shortestFailLeft :: Property
532-- shortestFailLeft =
533-- property (case S.parse (P.shortest (P.die "die") (P.fromPure (1 :: Int))) (S.fromList [1 :: Int]) of
534-- Right r -> r == 1
535-- Left _ -> False)
537-- shortestFailRight :: Property
538-- shortestFailRight =
539-- property (case S.parse (P.shortest (P.fromPure (1 :: Int)) (P.die "die")) (S.fromList [1 :: Int]) of
540-- Right r -> r == 1
541-- Left _ -> False)
543-- shortestFailBoth :: Property
544-- shortestFailBoth =
545-- property (case S.parse (P.shortest (P.die "die") (P.die "die")) (S.fromList [1 :: Int]) of
546-- Right _ -> False
547-- Left _ -> True)
549many :: Property
550many =
551 forAll (listOf (chooseInt (0, 1))) $ \ls ->
552 let fldstp conL currL = return $ FL.Partial $ conL ++ currL
553 concatFold = FL.Fold fldstp (return (FL.Partial [])) return
554 prsr =
555 flip P.many concatFold $ P.fromFold $ FL.takeEndBy_ (== 1) FL.toList
556 in
557 case S.parse prsr (S.fromList ls) of
558 Right res_list -> checkListEqual res_list
559 $ Prelude.filter (== 0) ls
560 Left _ -> property False
562-- many_empty :: Property
563-- many_empty =
564-- property (case S.parse (P.many FL.toList (P.die "die")) (S.fromList [1 :: Int]) of
565-- Right res_list -> checkListEqual res_list ([] :: [Int])
566-- Left _ -> property False)
568some :: Property
569some =
570 forAll (listOf (chooseInt (0, 1))) $ \genLs ->
571 let
572 ls = 0 : genLs
573 fldstp conL currL = return $ FL.Partial $ conL ++ currL
574 concatFold = FL.Fold fldstp (return (FL.Partial [])) return
575 prsr =
576 flip P.some concatFold $ P.fromFold $ FL.takeEndBy_ (== 1) FL.toList
577 in
578 case S.parse prsr (S.fromList ls) of
579 Right res_list -> res_list == Prelude.filter (== 0) ls
580 Left _ -> False
582-- someFail :: Property
583-- someFail =
584-- property (case S.parse (P.some FL.toList (P.die "die")) (S.fromList [1 :: Int]) of
585-- Right _ -> False
586-- Left _ -> True)
588-------------------------------------------------------------------------------
589-- Instances
590-------------------------------------------------------------------------------
592applicative :: Property
593applicative =
594 forAll (listOf (chooseAny :: Gen Int)) $ \ list1 ->
595 forAll (listOf (chooseAny :: Gen Int)) $ \ list2 ->
596 let parser =
597 (,)
598 <$> P.fromFold (FL.take (length list1) FL.toList)
599 <*> P.fromFold (FL.take (length list2) FL.toList)
600 in monadicIO $ do
601 (olist1, olist2) <-
602 run $ S.parse parser (S.fromList $ list1 ++ list2)
603 listEquals (==) olist1 list1
604 listEquals (==) olist2 list2
606sequence :: Property
607sequence =
608 forAll (vectorOf 11 (listOf (chooseAny :: Gen Int))) $ \ ins ->
609 let p xs = P.fromFold (FL.take (length xs) FL.toList)
610 in monadicIO $ do
611 outs <- run $
612 S.parse
613 (Prelude.sequence $ fmap p ins)
614 (S.fromList $ concat ins)
615 listEquals (==) outs ins
617monad :: Property
618monad =
619 forAll (listOf (chooseAny :: Gen Int)) $ \ list1 ->
620 forAll (listOf (chooseAny :: Gen Int)) $ \ list2 ->
621 let parser = do
622 olist1 <- P.fromFold (FL.take (length list1) FL.toList)
623 olist2 <- P.fromFold (FL.take (length list2) FL.toList)
624 return (olist1, olist2)
625 in monadicIO $ do
626 (olist1, olist2) <-
627 run $ S.parse parser (S.fromList $ list1 ++ list2)
628 listEquals (==) olist1 list1
629 listEquals (==) olist2 list2
631-------------------------------------------------------------------------------
632-- Stream parsing
633-------------------------------------------------------------------------------
635parseMany :: Property
636parseMany =
637 forAll (chooseInt (1,100)) $ \len ->
638 forAll (listOf (vectorOf len (chooseAny :: Gen Int))) $ \ ins ->
639 monadicIO $ do
640 outs <- do
641 let p = P.fromFold $ FL.take len FL.toList
642 run
643 $ S.toList
644 $ S.parseMany p (S.fromList $ concat ins)
645 listEquals (==) outs ins
647-------------------------------------------------------------------------------
648-- Test for a particular case hit during fs events testing
649-------------------------------------------------------------------------------
651evId :: [Word8]
652evId = [96,238,17,9,0,0,0,0]
654evFlags :: [Word8]
655evFlags = [0,4,1,0,0,0,0,0]
657evPathLen :: [Word8]
658evPathLen = [71,0,0,0,0,0,0,0]
660evPath :: [Word8]
661evPath =
662 [47,85,115,101,114,115,47,118,111,108,47,118,101,109,98,97,47,99,111,109
663 ,112,111,115,101,119,101 ,108,108,45,116,101,99,104,47,69,110,103,47,112
664 ,114,111,106,101,99,116,115,47,115,116,114,101,97,109,108,121,47,115,116
665 ,114,101,97,109,108,121,47,116,109,112,47,122,122
666 ]
668event :: [Word8]
669event = evId ++ evFlags ++ evPathLen ++ evPath
671data Event = Event
672 { eventId :: Word64
673 , eventFlags :: Word32
674 , eventAbsPath :: A.Array Word8
675 } deriving (Show, Ord, Eq)
677readOneEvent :: P.Parser IO Word8 Event
678readOneEvent = do
679 arr <- P.takeEQ 24 (A.writeN 24)
680 let arr1 = A.castUnsafe arr :: A.Array Word64
681 eid = A.unsafeIndex 0 arr1
682 eflags = A.unsafeIndex 1 arr1
683 pathLen = fromIntegral $ A.unsafeIndex 2 arr1
684 -- XXX handle if pathLen is 0
685 path <- P.takeEQ pathLen (A.writeN pathLen)
686 return $ Event
687 { eventId = eid
688 , eventFlags = fromIntegral eflags
689 , eventAbsPath = path
690 }
692parseMany2Events :: Property
693parseMany2Events =
694 monadicIO $ do
695 xs <-
696 ( run
697 $ S.toList
698 $ S.parseMany readOneEvent
699 $ S.fromList (concat (replicate 2 event))
700 )
701 assert (length xs == 2)
702 -- XXX assuming little endian machine
703 let ev = Event
704 { eventId = 152170080
705 , eventFlags = 66560
706 , eventAbsPath = A.fromList evPath
707 }
708 in listEquals (==) xs (replicate 2 ev)
710manyEqParseMany :: Property
711manyEqParseMany =
712 forAll (listOf (chooseInt (0, 100))) $ \lst ->
713 forAll (chooseInt (1, 100)) $ \i ->
714 monadicIO $ do
715 let strm = S.fromList lst
716 r1 <- run $ S.parse (P.many (split i) FL.toList) strm
717 r2 <- run $ S.toList $ S.parseMany (split i) strm
718 assert $ r1 == r2
720 where
722 split i = P.fromFold (FL.take i FL.toList)
724-------------------------------------------------------------------------------
725-- Main
726-------------------------------------------------------------------------------
728moduleName :: String
729moduleName = "Data.Parser"
731main :: IO ()
732main =
733 hspec $
734 H.parallel $
735 modifyMaxSuccess (const maxTestCount) $ do
736 describe moduleName $ do
738 describe "Instances" $ do
739 prop "applicative" applicative
740 prop "monad" monad
741 prop "sequence" sequence
743 describe "Stream parsing" $ do
744 prop "parseMany" parseMany
745 prop "parseMany2Events" parseMany2Events
747 describe "test for accumulator" $ do
748 prop "P.fromFold FL.sum = FL.sum" fromFold
749 prop "fromPure value provided" fromPure
750 prop "fromPure monadic value provided" fromEffect
751 prop "fail err = Left (SomeException (ParseError err))" parserFail
752 prop "always fail" die
753 prop "always fail but monadic" dieM
755 describe "test for element parser" $ do
756 prop "peek = head with list length > 0" peekPass
757 prop "peek fail on []" peekFail
758 prop "eof pass on []" eofPass
759 prop "eof fail on non-empty list" eofFail
760 prop "first element exists and >= mid_value" satisfyPass
761 prop "next pass on [Int]" nextPass
762 prop "next fail on []" next
763 prop "check first element exists and satisfies predicate" satisfy
765 describe "test for sequence parser" $ do
766 prop "P.takeBetween = Prelude.take when len >= m and len <= n"
767 takeBetweenPass
768 prop ("P.takeBetween = Prelude.take when len >= m and len <= n and fail"
769 ++ "otherwise fail") Main.takeBetween
771 prop "P.takeEQ = Prelude.take when len >= n" takeEQPass
772 prop "P.takeEQ = Prelude.take when len >= n and fail otherwise"
773 Main.takeEQ
774 prop "P.takeGE n ls = ls when len >= n" takeGEPass
775 prop "P.takeGE n ls = ls when len >= n and fail otherwise" Main.takeGE
776 -- prop "lookAhead . take n >> lookAhead . take n = lookAhead . take n" lookAheadPass
777 -- prop "Fail when stream length exceeded" lookAheadFail
778 -- prop "lookAhead . take n >> lookAhead . take n = lookAhead . take n, else fail" lookAhead
779 prop "P.sliceSepByP test" Main.sliceSepByP
780 prop ("P.sliceBeginWith pred = head : Prelude.takeWhile (not . pred)"
781 ++ " tail") sliceBeginWith
782 prop "P.takeWhile = Prelude.takeWhile" Main.takeWhile
783 prop ("P.takeWhile1 = Prelude.takeWhile if taken something,"
784 ++ " else check why failed") takeWhile1
785 prop ("P.takeP = Prelude.take") takeP
786 prop "P.groupBy = Prelude.head . Prelude.groupBy" groupBy
787 prop "many (P.wordBy ' ') = words'" wordBy
788 prop "choice" choice
789 -- prop "" splitWithPass
790 -- prop "" splitWithFailLeft
791 -- prop "" splitWithFailRight
792 -- prop "" splitWithFailBoth
793 -- prop "" teeWithPass
794 -- prop "" teeWithFailLeft
795 -- prop "" teeWithFailRight
796 -- prop "" teeWithFailBoth
797 -- prop "" deintercalate
798 -- prop "" shortestPass
799 -- prop "" shortestFailLeft
800 -- prop "" shortestFailRight
801 -- prop "" shortestFailBoth
802 prop ("P.many concatFold $ P.takeEndBy_ (== 1) FL.toList ="
803 ++ "Prelude.filter (== 0)") many
804 -- prop "[] due to parser being die" many_empty
805 prop ("P.some concatFold $ P.takeEndBy_ (== 1) FL.toList ="
806 ++ "Prelude.filter (== 0)") some
807 -- prop "fail due to parser being die" someFail
808 prop "P.many == S.parseMany" manyEqParseMany
809 takeProperties