@@ -1,19 +1,29 @@
1module Main (main) where
1module Main (main) where
3−import qualified Streamly.Prelude as S
4import Streamly.Internal.Data.Fold
3import Streamly.Internal.Data.Fold
4+import qualified Streamly.Prelude as S
5+import qualified Streamly.Data.Fold as FL
6import Test.Hspec.QuickCheck
8import Test.Hspec.QuickCheck
7import Test.QuickCheck (Property, forAll, Gen, vectorOf, arbitrary, choose)
9import Test.QuickCheck (Property, forAll, Gen, vectorOf, arbitrary, choose)
8import Test.QuickCheck.Monadic (monadicIO, assert, run)
10import Test.QuickCheck.Monadic (monadicIO, assert, run)
10−import Test.Hspec as H
12maxStreamLen :: Int
12maxStreamLen :: Int
13maxStreamLen = 1000
13maxStreamLen = 1000
21+{-# INLINE maxStreamLen #-}
15testRollingHashFirstN :: Property
25testRollingHashFirstN :: Property
16−testRollingHashFirstN =
26+testRollingHashFirstN =
17 forAll (choose (0, maxStreamLen)) $ \len ->
27 forAll (choose (0, maxStreamLen)) $ \len ->
18 forAll (choose (0, len)) $ \n ->
28 forAll (choose (0, len)) $ \n ->
19 forAll (vectorOf len (arbitrary :: Gen Int)) $ \vec -> monadicIO $ do
29 forAll (vectorOf len (arbitrary :: Gen Int)) $ \vec -> monadicIO $ do
@@ -21,7 +31,175 @@ testRollingHashFirstN =
21 b <- run $ S.fold (rollingHashFirstN n) $ S.fromList vec
31 b <- run $ S.fold (rollingHashFirstN n) $ S.fromList vec
22 assert $ a == b
32 assert $ a == b
35+testHead :: [Int] -> Expectation
36+testHead ls = S.fold FL.head (S.fromList ls) `shouldReturn` headl ls
42+testLength :: [Int] -> Expectation
43+testLength ls = S.fold FL.length (S.fromList ls) `shouldReturn` Prelude.length ls
46+testSum :: [Int] -> Expectation
47+testSum ls = S.fold FL.sum (S.fromList ls) `shouldReturn` foldl (+) 0 ls
50+testProduct :: [Int] -> Expectation
51+testProduct ls = S.fold FL.product (S.fromList ls) `shouldReturn` foldl (*) 1 ls
54+lesser :: (a -> a -> Ordering) -> a -> a -> a
55+lesser f x y = if f x y == LT then x else y
58+greater :: (a -> a -> Ordering) -> a -> a -> a
59+greater f x y = if f x y == GT then x else y
62+foldMaybe :: (b -> a -> b) -> b -> [a] -> Maybe b
63+foldMaybe f acc ls = case ls of
65+ _ -> Just (foldl f acc ls)
68+testMaximumBy :: (Ord a, Show a) => a -> (a -> a -> Ordering) -> [a] -> Expectation
69+testMaximumBy genmin f ls = S.fold (FL.maximumBy f) (S.fromList ls) `shouldReturn` foldMaybe (greater f) genmin ls
72+testMaximum :: (Show a, Ord a) => a -> [a] -> Expectation
73+testMaximum genmin ls = S.fold FL.maximum (S.fromList ls) `shouldReturn` foldMaybe (greater compare) genmin ls
76+testMinimumBy :: (Ord a, Show a) => a -> (a -> a -> Ordering) -> [a] -> Expectation
77+testMinimumBy genmax f ls = S.fold (FL.minimumBy f) (S.fromList ls) `shouldReturn` foldMaybe (lesser f) genmax ls
80+testMinimum :: (Show a, Ord a) => a -> [a] -> Expectation
81+testMinimum genmax ls = S.fold FL.minimum (S.fromList ls) `shouldReturn` foldMaybe (lesser compare) genmax ls
84+testToList :: [Int] -> Expectation
85+testToList ls = S.fold FL.toList (S.fromList ls) `shouldReturn` ls
88+safeLast :: [a] -> Maybe a
90+safeLast (x:[]) = Just x
91+safeLast (_:xs) = safeLast xs
94+testLast :: [String] -> Expectation
95+testLast ls = S.fold FL.last (S.fromList ls) `shouldReturn` safeLast ls
98+nth :: Int -> [a] -> Maybe a
99+nth idx (x:xs) = if idx == 0
103+ else nth (idx - 1) xs
107+testIndex :: Int -> [String] -> Expectation
108+testIndex idx ls = let
109+ x = S.fold (FL.index idx) (S.fromList ls)
111+ x `shouldReturn` (nth idx ls)
114+testFind :: (Show a, Eq a) => (a -> Bool) -> [a] -> Expectation
116+ let x = S.fold (FL.findIndex f) (S.fromList ls)
119+ Nothing -> S.fold (FL.find f) (S.fromList ls) `shouldReturn` Nothing
120+ Just idx -> S.fold (FL.any f) (S.fromList $ take idx ls) `shouldReturn` False
123+neg :: (a -> Bool) -> a -> Bool
124+neg f x = if f x == True then False else True
126+testFindIndex :: (a -> Bool) -> [a] -> Expectation
127+testFindIndex f ls = do
128+ let x = S.fold (FL.findIndex f) (S.fromList ls)
131+ Nothing -> S.fold (FL.all $ neg f) (S.fromList ls) `shouldReturn` True
132+ Just idx -> if idx == 0
133+ then S.fold (FL.all f) (S.fromList []) `shouldReturn` True
134+ else S.fold (FL.all f) (S.fromList $ (take idx ls)) `shouldReturn` False
136+predicate :: Int -> Bool
137+predicate x = if x * x < 100 then True else False
139+testElemIndex :: Int -> [Int] -> Expectation
140+testElemIndex elm ls = do
141+ let x = S.fold (FL.elemIndex elm) (S.fromList ls)
144+ Nothing -> S.fold (FL.any (\z -> if z == elm then True else False)) (S.fromList ls) `shouldReturn` False
145+ Just idx -> S.fold (FL.any (\z -> if z == elm then True else False)) (S.fromList $ (take idx ls)) `shouldReturn` False
147+testNull :: [Int] -> Expectation
148+testNull ls = S.fold FL.null (S.fromList ls) `shouldReturn` case ls of
151+testElem :: Int -> [Int] -> Expectation
153+ let x = S.fold (FL.elem elm) (S.fromList ls)
155+ S.fold (FL.any (\z -> if z == elm then True else False)) (S.fromList ls) `shouldReturn` y
158+testNotElem :: Int -> [Int] -> Expectation
159+testNotElem elm ls = do
160+ let x = S.fold (FL.notElem elm) (S.fromList ls)
162+ S.fold (FL.any (\z -> if z == elm then True else False)) (S.fromList ls) `shouldReturn` (if y == True then False else True)
165+testAll :: (a -> Bool) -> [a] -> Expectation
166+testAll f ls = S.fold (FL.all f) (S.fromList ls) `shouldReturn` Prelude.and (map f ls)
169+testAny :: (a -> Bool) -> [a] -> Expectation
170+testAny f ls = S.fold (FL.any f) (S.fromList ls) `shouldReturn` Prelude.any f ls
173+testAnd :: [Bool] -> Expectation
174+testAnd ls = S.fold FL.and (S.fromList ls) `shouldReturn` Prelude.and ls
177+testOr :: [Bool] -> Expectation
178+testOr ls = S.fold FL.or (S.fromList ls) `shouldReturn` Prelude.or ls
24main :: IO ()
181main :: IO ()
25main = hspec $
182main = hspec $
26− describe "Rolling Hash Folds" $
183+ describe "Fold Tests" $ do
27 prop "testRollingHashFirstN" testRollingHashFirstN
184 prop "testRollingHashFirstN" testRollingHashFirstN
185+ prop "testIndex" $ testIndex
186+ prop "testHead" testHead
187+ prop "testLast" testLast
188+ prop "testLength" testLength
189+ prop "testSum" testSum
190+ prop "testProduct" testProduct
191+ prop "testMaximumBy" $ testMaximumBy intMin compare
192+ prop "testMaximum" $ testMaximum intMin
193+ prop "testMinimumBy" $ testMinimumBy intMax compare
194+ prop "testMinimum" $ testMinimum intMax
195+ prop "testToList" testToList
196+ prop "testFind" $ testFind predicate
197+ prop "testFindIndex" $ testFindIndex predicate
198+ prop "testElemIndex" $ testElemIndex 10
199+ prop "testNull" testNull
200+ prop "testElem" $ testElem 10
201+ prop "testNotElem" $ testNotElem 10
202+ prop "testAll" $ testAll predicate
203+ prop "testAny" $ testAny predicate
204+ prop "testAnd" testAnd
205+ prop "testOr" testOr