@@ -22,7 +22,7 @@ import GHC.Word (Word8)
2222import Test.Hspec.QuickCheck
2323import Test.QuickCheck
2424 (counterexample, Property, withMaxSuccess, forAll, choose, Gen,
25− arbitrary, elements, frequency, listOf) --, listOf1, vectorOf, suchThat)
25+ arbitrary, elements, frequency, listOf, vectorOf) --, listOf1, suchThat)
2626import Test.QuickCheck.Monadic (run, monadicIO, monitor, assert, PropertyM)
2727
2828import Test.Hspec as H
@@ -34,6 +34,9 @@ import qualified Streamly.Prelude as S
3434import qualified Streamly.Data.Fold as FL
3535import qualified Streamly.Internal.Data.Fold as FL
3636
37+maxStreamLen :: Int
38+maxStreamLen = 1000
39+
3740-- Coverage build takes too long with default number of tests
3841maxTestCount :: Int
3942#ifdef DEVBUILD
@@ -990,6 +993,56 @@ monadBind constr eq t (a, b) = withMaxSuccess maxTestCount $
990993 let list = a >>= \x -> (+ x) <$> b
991994 listEquals eq stream list
992995
996+-------------------------------------------------------------------------------
997+-- Tests for S.groupsBy
998+-------------------------------------------------------------------------------
999+
1000+-- |
1001+-- If the list is empty, returns Nothing,
1002+-- else wraps the minimum value of the list in Just.
1003+maybeMinimum :: [Int] -> Maybe Int
1004+maybeMinimum [] = Nothing
1005+maybeMinimum ls = Just $ minimum ls
1006+
1007+
1008+-- |
1009+-- After grouping (and folding) Int stream using @>@ operation,
1010+-- the first @Int@ of every @[Int]@ in the @[Int]@ stream should be the minimum.
1011+testGroupsBy :: Property
1012+testGroupsBy =
1013+ forAll (choose (0, maxStreamLen)) $ \len ->
1014+ forAll (vectorOf len (arbitrary :: Gen Int)) $ \vec -> monadicIO $ do
1015+ r <- run $ S.all (\ls ->
1016+ case ls of
1017+ [] -> True
1018+ (x:_) -> x == minimum ls)
1019+ $ S.groupsBy (>) FL.toList
1020+ $ S.fromList vec
1021+ assert $ r == True
1022+
1023+-- |
1024+-- Checks if the @[Int]@ is non-increasing.
1025+decreasing :: [Maybe Int] -> Bool
1026+decreasing [] = True
1027+decreasing xs = all (== True) $ zipWith (<=) (tail xs) xs
1028+
1029+
1030+-- |
1031+-- To check if the minimum elements (after grouping on @>@)
1032+-- are non-increasing (either decrease or remain the same).
1033+-- Had an element been strictly greater, it would have been grouped
1034+-- with that element only.
1035+testGroupsBySep :: Property
1036+testGroupsBySep =
1037+ forAll (choose (0, maxStreamLen)) $ \len ->
1038+ forAll (vectorOf len (arbitrary :: Gen Int)) $ \vec -> monadicIO $ do
1039+ a <- run $ S.toList
1040+ $ S.map maybeMinimum
1041+ $ S.groupsBy (>) FL.toList
1042+ $ S.fromList vec
1043+ assert $ decreasing a == True
1044+
1045+
9931046main :: IO ()
9941047main = hspec
9951048 $ H.parallel
@@ -1347,3 +1400,7 @@ main = hspec
13471400 aheadOps $ eliminationOpsOrdered folded "aheadly folded"
13481401 zipSerialOps $ eliminationOpsOrdered folded "zipSerially folded"
13491402 zipAsyncOps $ eliminationOpsOrdered folded "zipAsyncly folded"
1403+
1404+ describe "Tests for S.groupsBy" $ do
1405+ prop "testGroupsBy" testGroupsBy
1406+ prop "testGroupsBySep" testGroupsBySep