on master help sign in
Add test cases for newly added functions
0b87705Ranjeet Kumar Ranjan
test/Streamly/Test/Data/Fold.hs+168−12
@@ -16,6 +16,7 @@ import Test.QuickCheck
16 )
16 )
17import Test.QuickCheck.Monadic (monadicIO, assert, run)
17import Test.QuickCheck.Monadic (monadicIO, assert, run)
18
18
19+import qualified Data.Map
19import qualified Prelude
20import qualified Prelude
20import qualified Streamly.Internal.Data.Fold as F
21import qualified Streamly.Internal.Data.Fold as F
21import qualified Streamly.Prelude as S
22import qualified Streamly.Prelude as S
@@ -53,7 +54,8 @@ rollingHashFirstN :: Property
53rollingHashFirstN =
54rollingHashFirstN =
54 forAll (choose (0, maxStreamLen)) $ \len ->
55 forAll (choose (0, maxStreamLen)) $ \len ->
55 forAll (choose (0, len)) $ \n ->
56 forAll (choose (0, len)) $ \n ->
56− forAll (vectorOf len (arbitrary :: Gen Int)) $ \vec -> monadicIO $ do
57+ forAll (vectorOf len (arbitrary :: Gen Int)) $ \vec ->
58+ monadicIO $ do
57 a <- run $ S.fold F.rollingHash $ S.take n $ S.fromList vec
59 a <- run $ S.fold F.rollingHash $ S.take n $ S.fromList vec
58 b <- run $ S.fold (F.rollingHashFirstN n) $ S.fromList vec
60 b <- run $ S.fold (F.rollingHashFirstN n) $ S.fromList vec
59 assert $ a == b
61 assert $ a == b
@@ -110,6 +112,9 @@ minimum genmax ls =
110toList :: [Int] -> Expectation
112toList :: [Int] -> Expectation
111toList ls = S.fold FL.toList (S.fromList ls) `shouldReturn` ls
113toList ls = S.fold FL.toList (S.fromList ls) `shouldReturn` ls
112
114
115+toListRev :: [Int] -> Expectation
116+toListRev ls = S.fold FL.toListRev (S.fromList ls) `shouldReturn` reverse ls
117+
113safeLast :: [a] -> Maybe a
118safeLast :: [a] -> Maybe a
114safeLast [] = Nothing
119safeLast [] = Nothing
115safeLast (x:[]) = Just x
120safeLast (x:[]) = Just x
@@ -124,7 +129,7 @@ mapMaybe ls =
124 if even x
129 if even x
125 then Just x
130 then Just x
126 else Nothing
131 else Nothing
127− f = F.mapMaybe maybeEven FL.toList
132+ f = FL.mapMaybe maybeEven FL.toList
128 in S.fold f (S.fromList ls) `shouldReturn` filter even ls
133 in S.fold f (S.fromList ls) `shouldReturn` filter even ls
129
134
130nth :: Int -> [a] -> Maybe a
135nth :: Int -> [a] -> Maybe a
@@ -179,7 +184,8 @@ elemIndex elm ls = do
179 let fld = S.fold (FL.any (== elm)) (S.fromList ls)
184 let fld = S.fold (FL.any (== elm)) (S.fromList ls)
180 in fld `shouldReturn` False
185 in fld `shouldReturn` False
181 Just idx ->
186 Just idx ->
187+ let fld =
182− let fld = S.fold (FL.any (== elm)) (S.fromList $ Prelude.take idx ls)
188+ S.fold (FL.any (== elm)) (S.fromList $ Prelude.take idx ls)
183 in fld `shouldReturn` False
189 in fld `shouldReturn` False
184
190
185null :: [Int] -> Expectation
191null :: [Int] -> Expectation
@@ -218,14 +224,14 @@ or ls = S.fold FL.or (S.fromList ls) `shouldReturn` Prelude.or ls
218take :: [Int] -> Property
224take :: [Int] -> Property
219take ls =
225take ls =
220 forAll (chooseInt (-1, Prelude.length ls + 2)) $ \n ->
226 forAll (chooseInt (-1, Prelude.length ls + 2)) $ \n ->
221− S.fold (F.take n FL.toList) (S.fromList ls)
227+ S.fold (FL.take n FL.toList) (S.fromList ls)
222 `shouldReturn` Prelude.take n ls
228 `shouldReturn` Prelude.take n ls
223
229
224takeEndBy_ :: Property
230takeEndBy_ :: Property
225takeEndBy_ =
231takeEndBy_ =
226 forAll (listOf (chooseInt (0, 1))) $ \ls ->
232 forAll (listOf (chooseInt (0, 1))) $ \ls ->
227 let p = (== 1)
233 let p = (== 1)
228− f = F.takeEndBy_ p FL.toList
234+ f = FL.takeEndBy_ p FL.toList
229 ys = Prelude.takeWhile (not . p) ls
235 ys = Prelude.takeWhile (not . p) ls
230 in case S.fold f (S.fromList ls) of
236 in case S.fold f (S.fromList ls) of
231 Right xs -> checkListEqual xs ys
237 Right xs -> checkListEqual xs ys
@@ -236,7 +242,7 @@ takeEndByOrMax =
236 forAll (chooseInt (min_value, max_value)) $ \n ->
242 forAll (chooseInt (min_value, max_value)) $ \n ->
237 forAll (listOf (chooseInt (0, 1))) $ \ls ->
243 forAll (listOf (chooseInt (0, 1))) $ \ls ->
238 let p = (== 1)
244 let p = (== 1)
239− f = F.takeEndBy_ p (F.take n FL.toList)
245+ f = FL.takeEndBy_ p (FL.take n FL.toList)
240 ys = Prelude.take n (Prelude.takeWhile (not . p) ls)
246 ys = Prelude.take n (Prelude.takeWhile (not . p) ls)
241 in case S.fold f (S.fromList ls) of
247 in case S.fold f (S.fromList ls) of
242 Right xs -> checkListEqual xs ys
248 Right xs -> checkListEqual xs ys
@@ -335,10 +341,11 @@ lookup =
335 where
341 where
336
342
337 action key = do
343 action key = do
338− let ls = [(1, "first"), (2, "second"), (3, "third"), (4, "fourth")
344+ let ls = [ (1, "first"), (2, "second"), (3, "third"), (4, "fourth")
339− , (5, "fifth"), (6, "fifth+first"), (7, "fifth+second")
345+ , (5, "fifth"), (6, "fifth+first"), (7, "fifth+second")
340− , (8, "fifth+third"), (9, "fifth+fourth")
346+ , (8, "fifth+third"), (9, "fifth+fourth")
341− , (10, "fifth+fifth")]
347+ , (10, "fifth+fifth")
348+ ]
342 v1 <- run $ S.fold (FL.lookup key) $ S.fromList ls
349 v1 <- run $ S.fold (FL.lookup key) $ S.fromList ls
343 let v2 = Prelude.lookup key ls
350 let v2 = Prelude.lookup key ls
344 assert (v1 == v2)
351 assert (v1 == v2)
@@ -423,13 +430,13 @@ many =
423 forAll (chooseInt (1, 100)) $ \i ->
430 forAll (chooseInt (1, 100)) $ \i ->
424 monadicIO $ do
431 monadicIO $ do
425 let strm = S.fromList lst
432 let strm = S.fromList lst
426− r1 <- S.fold (F.many (split i) F.toList) strm
433+ r1 <- S.fold (FL.many (split i) FL.toList) strm
427 r2 <- S.toList $ Stream.foldMany (split i) strm
434 r2 <- S.toList $ Stream.foldMany (split i) strm
428 assert $ r1 == r2
435 assert $ r1 == r2
429
436
430 where
437 where
431
438
432− split i = F.take i F.toList
439+ split i = FL.take i FL.toList
433
440
434headAndRest :: [Int] -> Property
441headAndRest :: [Int] -> Property
435headAndRest ls = monadicIO $ do
442headAndRest ls = monadicIO $ do
@@ -444,6 +451,143 @@ headAndRest ls = monadicIO $ do
444 taill [] = []
451 taill [] = []
445 taill (_:xs) = xs
452 taill (_:xs) = xs
446
453
454+partitionByM :: Property
455+partitionByM =
456+ forAll (listOf1 (chooseInt (intMin, intMax)))
457+ $ \ls0 -> monadicIO $ action ls0
458+
459+ where
460+
461+ action ls = do
462+ let f = \x -> if odd x then return (Left x) else return (Right x)
463+ v1 <-
464+ run
465+ $ S.fold (F.partitionByM f FL.length FL.length)
466+ $ S.fromList ls
467+ let v2 = Prelude.length $ filter odd ls
468+ v3 = Prelude.length $ filter even ls
469+ assert (v1 == (v2, v3))
470+
471+demux :: Expectation
472+demux =
473+ let table = Data.Map.fromList [("SUM", FL.sum), ("PRODUCT", FL.product)]
474+ input = Stream.fromList (
475+ [ ("SUM", 1)
476+ , ("PRODUCT", 2)
477+ , ("SUM",3)
478+ , ("PRODUCT", 4)
479+ ] :: [(String, Int)])
480+ in Stream.fold
481+ (F.demux table)
482+ input
483+ `shouldReturn`
484+ Data.Map.fromList [("PRODUCT", 8),("SUM", 4)]
485+
486+
487+demuxWithSum :: Expectation
488+demuxWithSum =
489+ let f x = ("SUM", x::Int)
490+ table = Data.Map.fromList [("SUM", FL.sum)]
491+ input = Stream.fromList [1, 4]
492+ in Stream.fold
493+ (F.demuxWith f table)
494+ input
495+ `shouldReturn`
496+ Data.Map.fromList [("SUM", 5)]
497+
498+demuxWithProduct :: Expectation
499+demuxWithProduct =
500+ let f x = ("PRODUCT", x::Int)
501+ table = Data.Map.fromList [("PRODUCT", FL.product)]
502+ input = Stream.fromList [2, 4]
503+ in Stream.fold
504+ (F.demuxWith f table)
505+ input
506+ `shouldReturn`
507+ Data.Map.fromList [("PRODUCT", 8)]
508+
509+demuxDefaultWithSum :: Expectation
510+demuxDefaultWithSum =
511+ let f x = ("SUM", x::Int)
512+ table = Data.Map.fromList [("SUM", FL.sum)]
513+ input = Stream.fromList [2, 4]
514+ in Stream.fold
515+ (F.demuxDefaultWith f table (FL.lmap snd FL.sum))
516+ input
517+ `shouldReturn`
518+ (Data.Map.fromList [("SUM" , 6)] , 0)
519+
520+demuxDefaultWithProduct :: Expectation
521+demuxDefaultWithProduct =
522+ let f x = ("PRODUCT", x::Int)
523+ table = Data.Map.fromList [("PRODUCT", FL.product)]
524+ input = Stream.fromList [2, 4]
525+ in Stream.fold
526+ (F.demuxDefaultWith f table (FL.lmap snd FL.product))
527+ input
528+ `shouldReturn`
529+ (Data.Map.fromList [("PRODUCT" , 8)] , 1)
530+
531+demuxDefault :: Expectation
532+demuxDefault =
533+ let table = Data.Map.fromList [("SUM", FL.sum), ("PRODUCT", FL.product)]
534+ input = Stream.fromList
535+ [ ("SUM", 1::Int)
536+ , ("PRODUCT", 2::Int)
537+ , ("SUM",3)
538+ , ("PRODUCT", 4::Int)
539+ ]
540+ in Stream.fold
541+ (F.demuxDefault table (FL.lmap snd FL.product))
542+ input
543+ `shouldReturn`
544+ (Data.Map.fromList [("PRODUCT", 8), ("SUM", 4)], 1)
545+
546+demuxDefaultEmpty :: Expectation
547+demuxDefaultEmpty =
548+ let table = Data.Map.empty
549+ input = Stream.fromList []
550+ in Stream.fold
551+ (F.demuxDefault table (FL.lmap snd FL.product))
552+ input
553+ `shouldReturn`
554+ (Data.Map.fromList ([]::[(String, Int)]), 1)
555+
556+classifyWith :: Expectation
557+classifyWith =
558+ let input = Stream.fromList [("ONE",1),("ONE",1.1),("TWO",2), ("TWO",2.2)]
559+ in Stream.fold
560+ (F.classifyWith fst (FL.lmap snd FL.toList))
561+ input
562+ `shouldReturn`
563+ Data.Map.fromList
564+ [("ONE",[1.0, 1.1 :: Double]), ("TWO",[2.0, 2.2])]
565+
566+classify :: Expectation
567+classify =
568+ let input =
569+ Stream.fromList
570+ [
571+ ("ONE", (1::Int, 1))
572+ , ("ONE", (1, 1.1:: Double))
573+ , ("TWO", (2, 2))
574+ , ("TWO",(2, 2.2))
575+ ]
576+ in Stream.fold
577+ (F.classify (FL.lmap snd FL.toList))
578+ input
579+ `shouldReturn`
580+ Data.Map.fromList
581+ [("ONE",[1.0, 1.1 :: Double]), ("TWO",[2.0, 2.2])]
582+
583+splitAt :: Expectation
584+splitAt =
585+ Stream.fold
586+ (F.splitAt 6 FL.toList FL.toList)
587+ (Stream.fromList "Hello World!")
588+ `shouldReturn`
589+ ("Hello ","World!")
590+
447moduleName :: String
591moduleName :: String
448moduleName = "Data.Fold"
592moduleName = "Data.Fold"
449
593
@@ -472,6 +616,16 @@ main = hspec $ do
472 prop "rollingHashFirstN" rollingHashFirstN
616 prop "rollingHashFirstN" rollingHashFirstN
473
617
474 prop "toList" toList
618 prop "toList" toList
619+ prop "toListRev" toListRev
620+ prop "demux" demux
621+ prop "demuxWithSum" demuxWithSum
622+ prop "demuxWithProduct" demuxWithProduct
623+ prop "demuxDefaultWithSum" demuxDefaultWithSum
624+ prop "demuxDefaultWithProduct" demuxDefaultWithProduct
625+ prop "demuxDefault" demuxDefault
626+ prop "demuxDefaultEmpty" demuxDefaultEmpty
627+ prop "classifyWith" classifyWith
628+ prop "classify" classify
475
629
476 -- Terminating folds
630 -- Terminating folds
477 prop "index" index
631 prop "index" index
@@ -518,9 +672,11 @@ main = hspec $ do
518
672
519 -- Partitioning
673 -- Partitioning
520 prop "partition" Main.partition
674 prop "partition" Main.partition
675+ prop "partitionByM" partitionByM
521
676
522 -- Unzipping
677 -- Unzipping
523 prop "unzip" Main.unzip
678 prop "unzip" Main.unzip
679+ prop "splitAt" Main.splitAt
524
680
525 -- Nesting
681 -- Nesting
526 prop "many" Main.many
682 prop "many" Main.many