on 501be5e help sign in
812 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
327takeEndBy_ :: Property
328takeEndBy_ =
329 forAll (listOf (chooseInt (min_value, max_value ))) $ \ls ->
330 case S.parse (P.takeEndBy_ 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
339takeStartBy :: Property
340takeStartBy =
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.takeStartBy 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)
507deintercalate :: Property
508deintercalate =
509 forAll (listOf (chooseAny :: Gen Int)) $ \ls ->
510 case S.parse p (S.fromList ls) of
511 Right evenOdd -> evenOdd == List.partition even ls
512 Left _ -> False
514 where
515 p1 = P.takeWhile even FL.toList
516 p2 = P.takeWhile odd FL.toList
517 partition =
518 FL.tee (fmap concat $ FL.lefts FL.toList)
519 (fmap concat $ FL.rights FL.toList)
520 p = P.deintercalate partition p1 p2
522-- shortestPass :: Property
523-- shortestPass =
524-- forAll (listOf (chooseInt(min_value, max_value))) $ \ls ->
525-- let
526-- prsr_1 = P.takeWhile (<= (mid_value `Prelude.div` 2)) FL.toList
527-- prsr_2 = P.takeWhile (<= mid_value) FL.toList
528-- prsr_shortest = P.shortest prsr_1 prsr_2
529-- in
530-- case S.parse prsr_shortest (S.fromList ls) of
531-- Right short_list -> checkListEqual short_list (Prelude.takeWhile (<= 2500) ls)
532-- Left _ -> property False
534-- shortestFailLeft :: Property
535-- shortestFailLeft =
536-- property (case S.parse (P.shortest (P.die "die") (P.fromPure (1 :: Int))) (S.fromList [1 :: Int]) of
537-- Right r -> r == 1
538-- Left _ -> False)
540-- shortestFailRight :: Property
541-- shortestFailRight =
542-- property (case S.parse (P.shortest (P.fromPure (1 :: Int)) (P.die "die")) (S.fromList [1 :: Int]) of
543-- Right r -> r == 1
544-- Left _ -> False)
546-- shortestFailBoth :: Property
547-- shortestFailBoth =
548-- property (case S.parse (P.shortest (P.die "die") (P.die "die")) (S.fromList [1 :: Int]) of
549-- Right _ -> False
550-- Left _ -> True)
552many :: Property
553many =
554 forAll (listOf (chooseInt (0, 1))) $ \ls ->
555 let fldstp conL currL = return $ FL.Partial $ conL ++ currL
556 concatFold = FL.Fold fldstp (return (FL.Partial [])) return
557 prsr =
558 flip P.many concatFold $ P.fromFold $ FL.takeEndBy_ (== 1) FL.toList
559 in
560 case S.parse prsr (S.fromList ls) of
561 Right res_list -> checkListEqual res_list
562 $ Prelude.filter (== 0) ls
563 Left _ -> property False
565-- many_empty :: Property
566-- many_empty =
567-- property (case S.parse (P.many FL.toList (P.die "die")) (S.fromList [1 :: Int]) of
568-- Right res_list -> checkListEqual res_list ([] :: [Int])
569-- Left _ -> property False)
571some :: Property
572some =
573 forAll (listOf (chooseInt (0, 1))) $ \genLs ->
574 let
575 ls = 0 : genLs
576 fldstp conL currL = return $ FL.Partial $ conL ++ currL
577 concatFold = FL.Fold fldstp (return (FL.Partial [])) return
578 prsr =
579 flip P.some concatFold $ P.fromFold $ FL.takeEndBy_ (== 1) FL.toList
580 in
581 case S.parse prsr (S.fromList ls) of
582 Right res_list -> res_list == Prelude.filter (== 0) ls
583 Left _ -> False
585-- someFail :: Property
586-- someFail =
587-- property (case S.parse (P.some FL.toList (P.die "die")) (S.fromList [1 :: Int]) of
588-- Right _ -> False
589-- Left _ -> True)
591-------------------------------------------------------------------------------
592-- Instances
593-------------------------------------------------------------------------------
595applicative :: Property
596applicative =
597 forAll (listOf (chooseAny :: Gen Int)) $ \ list1 ->
598 forAll (listOf (chooseAny :: Gen Int)) $ \ list2 ->
599 let parser =
600 (,)
601 <$> P.fromFold (FL.take (length list1) FL.toList)
602 <*> P.fromFold (FL.take (length list2) FL.toList)
603 in monadicIO $ do
604 (olist1, olist2) <-
605 run $ S.parse parser (S.fromList $ list1 ++ list2)
606 listEquals (==) olist1 list1
607 listEquals (==) olist2 list2
609sequence :: Property
610sequence =
611 forAll (vectorOf 11 (listOf (chooseAny :: Gen Int))) $ \ ins ->
612 let p xs = P.fromFold (FL.take (length xs) FL.toList)
613 in monadicIO $ do
614 outs <- run $
615 S.parse
616 (Prelude.sequence $ fmap p ins)
617 (S.fromList $ concat ins)
618 listEquals (==) outs ins
620monad :: Property
621monad =
622 forAll (listOf (chooseAny :: Gen Int)) $ \ list1 ->
623 forAll (listOf (chooseAny :: Gen Int)) $ \ list2 ->
624 let parser = do
625 olist1 <- P.fromFold (FL.take (length list1) FL.toList)
626 olist2 <- P.fromFold (FL.take (length list2) FL.toList)
627 return (olist1, olist2)
628 in monadicIO $ do
629 (olist1, olist2) <-
630 run $ S.parse parser (S.fromList $ list1 ++ list2)
631 listEquals (==) olist1 list1
632 listEquals (==) olist2 list2
634-------------------------------------------------------------------------------
635-- Stream parsing
636-------------------------------------------------------------------------------
638parseMany :: Property
639parseMany =
640 forAll (chooseInt (1,100)) $ \len ->
641 forAll (listOf (vectorOf len (chooseAny :: Gen Int))) $ \ ins ->
642 monadicIO $ do
643 outs <- do
644 let p = P.fromFold $ FL.take len FL.toList
645 run
646 $ S.toList
647 $ S.parseMany p (S.fromList $ concat ins)
648 listEquals (==) outs ins
650-------------------------------------------------------------------------------
651-- Test for a particular case hit during fs events testing
652-------------------------------------------------------------------------------
654evId :: [Word8]
655evId = [96,238,17,9,0,0,0,0]
657evFlags :: [Word8]
658evFlags = [0,4,1,0,0,0,0,0]
660evPathLen :: [Word8]
661evPathLen = [71,0,0,0,0,0,0,0]
663evPath :: [Word8]
664evPath =
665 [47,85,115,101,114,115,47,118,111,108,47,118,101,109,98,97,47,99,111,109
666 ,112,111,115,101,119,101 ,108,108,45,116,101,99,104,47,69,110,103,47,112
667 ,114,111,106,101,99,116,115,47,115,116,114,101,97,109,108,121,47,115,116
668 ,114,101,97,109,108,121,47,116,109,112,47,122,122
669 ]
671event :: [Word8]
672event = evId ++ evFlags ++ evPathLen ++ evPath
674data Event = Event
675 { eventId :: Word64
676 , eventFlags :: Word32
677 , eventAbsPath :: A.Array Word8
678 } deriving (Show, Ord, Eq)
680readOneEvent :: P.Parser IO Word8 Event
681readOneEvent = do
682 arr <- P.takeEQ 24 (A.writeN 24)
683 let arr1 = A.castUnsafe arr :: A.Array Word64
684 eid = A.unsafeIndex 0 arr1
685 eflags = A.unsafeIndex 1 arr1
686 pathLen = fromIntegral $ A.unsafeIndex 2 arr1
687 -- XXX handle if pathLen is 0
688 path <- P.takeEQ pathLen (A.writeN pathLen)
689 return $ Event
690 { eventId = eid
691 , eventFlags = fromIntegral eflags
692 , eventAbsPath = path
693 }
695parseMany2Events :: Property
696parseMany2Events =
697 monadicIO $ do
698 xs <-
699 ( run
700 $ S.toList
701 $ S.parseMany readOneEvent
702 $ S.fromList (concat (replicate 2 event))
703 )
704 assert (length xs == 2)
705 -- XXX assuming little endian machine
706 let ev = Event
707 { eventId = 152170080
708 , eventFlags = 66560
709 , eventAbsPath = A.fromList evPath
710 }
711 in listEquals (==) xs (replicate 2 ev)
713manyEqParseMany :: Property
714manyEqParseMany =
715 forAll (listOf (chooseInt (0, 100))) $ \lst ->
716 forAll (chooseInt (1, 100)) $ \i ->
717 monadicIO $ do
718 let strm = S.fromList lst
719 r1 <- run $ S.parse (P.many (split i) FL.toList) strm
720 r2 <- run $ S.toList $ S.parseMany (split i) strm
721 assert $ r1 == r2
723 where
725 split i = P.fromFold (FL.take i FL.toList)
727-------------------------------------------------------------------------------
728-- Main
729-------------------------------------------------------------------------------
731moduleName :: String
732moduleName = "Data.Parser"
734main :: IO ()
735main =
736 hspec $
737 H.parallel $
738 modifyMaxSuccess (const maxTestCount) $ do
739 describe moduleName $ do
741 describe "Instances" $ do
742 prop "applicative" applicative
743 prop "monad" monad
744 prop "sequence" sequence
746 describe "Stream parsing" $ do
747 prop "parseMany" parseMany
748 prop "parseMany2Events" parseMany2Events
750 describe "test for accumulator" $ do
751 prop "P.fromFold FL.sum = FL.sum" fromFold
752 prop "fromPure value provided" fromPure
753 prop "fromPure monadic value provided" fromEffect
754 prop "fail err = Left (SomeException (ParseError err))" parserFail
755 prop "always fail" die
756 prop "always fail but monadic" dieM
758 describe "test for element parser" $ do
759 prop "peek = head with list length > 0" peekPass
760 prop "peek fail on []" peekFail
761 prop "eof pass on []" eofPass
762 prop "eof fail on non-empty list" eofFail
763 prop "first element exists and >= mid_value" satisfyPass
764 prop "next pass on [Int]" nextPass
765 prop "next fail on []" next
766 prop "check first element exists and satisfies predicate" satisfy
768 describe "test for sequence parser" $ do
769 prop "P.takeBetween = Prelude.take when len >= m and len <= n"
770 takeBetweenPass
771 prop ("P.takeBetween = Prelude.take when len >= m and len <= n and fail"
772 ++ "otherwise fail") Main.takeBetween
774 prop "P.takeEQ = Prelude.take when len >= n" takeEQPass
775 prop "P.takeEQ = Prelude.take when len >= n and fail otherwise"
776 Main.takeEQ
777 prop "P.takeGE n ls = ls when len >= n" takeGEPass
778 prop "P.takeGE n ls = ls when len >= n and fail otherwise" Main.takeGE
779 -- prop "lookAhead . take n >> lookAhead . take n = lookAhead . take n" lookAheadPass
780 -- prop "Fail when stream length exceeded" lookAheadFail
781 -- prop "lookAhead . take n >> lookAhead . take n = lookAhead . take n, else fail" lookAhead
782 prop "P.takeEndBy_ test" Main.takeEndBy_
783 prop ("P.takeStartBy pred = head : Prelude.takeWhile (not . pred)"
784 ++ " tail") takeStartBy
785 prop "P.takeWhile = Prelude.takeWhile" Main.takeWhile
786 prop ("P.takeWhile1 = Prelude.takeWhile if taken something,"
787 ++ " else check why failed") takeWhile1
788 prop ("P.takeP = Prelude.take") takeP
789 prop "P.groupBy = Prelude.head . Prelude.groupBy" groupBy
790 prop "many (P.wordBy ' ') = words'" wordBy
791 prop "choice" choice
792 -- prop "" splitWithPass
793 -- prop "" splitWithFailLeft
794 -- prop "" splitWithFailRight
795 -- prop "" splitWithFailBoth
796 -- prop "" teeWithPass
797 -- prop "" teeWithFailLeft
798 -- prop "" teeWithFailRight
799 -- prop "" teeWithFailBoth
800 prop "deintercalate" deintercalate
801 -- prop "" shortestPass
802 -- prop "" shortestFailLeft
803 -- prop "" shortestFailRight
804 -- prop "" shortestFailBoth
805 prop ("P.many concatFold $ P.takeEndBy_ (== 1) FL.toList ="
806 ++ "Prelude.filter (== 0)") many
807 -- prop "[] due to parser being die" many_empty
808 prop ("P.some concatFold $ P.takeEndBy_ (== 1) FL.toList ="
809 ++ "Prelude.filter (== 0)") some
810 -- prop "fail due to parser being die" someFail
811 prop "P.many == S.parseMany" manyEqParseMany
812 takeProperties