{-# OPTIONS_GHC -Wno-deprecations #-} module Main (main) where import Data.List (elem, intersect, nub, sort) import Data.Maybe (isNothing) import Streamly.Prelude (SerialT) import Test.QuickCheck ( Gen , Property , choose , forAll , listOf ) import Test.QuickCheck.Monadic (monadicIO, assert, run) import qualified Streamly.Prelude as S import qualified Streamly.Internal.Data.Stream.IsStream.Top as Top import Prelude hiding (maximum, minimum, elem, notElem, null, product, sum, head, last, take) import Test.Hspec as H import Test.Hspec.QuickCheck min_value :: Int min_value = 0 max_value :: Int max_value = 10000 chooseInt :: (Int, Int) -> Gen Int chooseInt = choose eq :: Int -> Int -> Bool eq = (==) joinInner :: Property joinInner = forAll (listOf (chooseInt (min_value, max_value))) $ \ls0 -> forAll (listOf (chooseInt (min_value, max_value))) $ \ls1 -> monadicIO $ action ls0 ls1 where action ls0 ls1 = do v1 <- run $ S.toList $ Top.joinInner eq (S.fromList ls0) (S.fromList $ sort ls1) let v2 = [ (i,j) | i <- ls0, j <- ls1, i == j ] assert (v1 == v2) joinInnerMap :: Property joinInnerMap = forAll (listOf (chooseInt (min_value, max_value))) $ \ls0 -> forAll (listOf (chooseInt (min_value, max_value))) $ \ls1 -> monadicIO $ action (map (\a -> (a,a)) ls0) (map (\a -> (a,a)) ls1) where action ls0 ls1 = do v1 <- run $ S.toList $ Top.joinInnerMap (S.fromList ls0) (S.fromList ls1) let v2 = [ (fst i, fst i, fst j) | i <- ls0, j <- nub ls1 , fst i == fst j ] assert (sort v1 == sort v2) joinOuterList :: [(Int, Int)] -> [(Int, Int)] -> [(Int, Maybe Int, Maybe Int)] joinOuterList ls0 ls1 = let v2 = do i <- ls0 if i `elem` ls1 then return (fst i, Just (fst i), Just (fst i)) else return (fst i, Just (fst i), Nothing) v3 = do j <- ls1 if j `elem` ls0 then return (fst j, Just (fst j), Just (fst j)) else return (fst j, Nothing, Just (fst j)) v4 = filter (\(_, a2, _) -> isNothing a2) v3 in v2 ++ v4 {- joinOuter :: Property joinOuter = forAll (listOf (chooseInt (min_value, max_value))) $ \ls0 -> forAll (listOf (chooseInt (min_value, max_value))) $ \ls1 -> monadicIO $ action ls0 (nub ls1) where action ls0 ls1 = do v1 <- run $ S.toList $ Top.joinOuter eq (S.fromList ls0) (S.fromList ls1) let v2 = joinOuterList (map (\a -> (a, a)) ls0) (map (\a -> (a, a)) ls1) v3 = map (\(_, v10, v20) -> (v10, v20)) v2 assert (sort v1 == sort v3) -} joinOuterMap :: Property joinOuterMap = forAll (listOf (chooseInt (min_value, max_value))) $ \ls0 -> forAll (listOf (chooseInt (min_value, max_value))) $ \ls1 -> monadicIO $ action (map (\a -> (a,a)) (nub ls0)) (map (\a -> (a,a)) (nub ls1)) where action ls0 ls1 = do v1 <- run $ S.toList $ Top.joinOuterMap (S.fromList ls0) (S.fromList ls1) let v2 = joinOuterList ls0 ls1 assert (sort v1 == sort v2) joinLeftList :: [(Int, Int)] -> [(Int, Int)] -> [(Int, Int, Maybe Int)] joinLeftList ls0 ls1 = let v = do i <- ls0 if i `elem` ls1 then return (fst i, fst i, Just (fst i)) else return (fst i, fst i, Nothing) in v {- joinLeft :: Property joinLeft = forAll (listOf (chooseInt (min_value, max_value))) $ \ls0 -> forAll (listOf (chooseInt (min_value, max_value))) $ \ls1 -> -- nub the second list as no way to validate using list functions monadicIO $ action ls0 (nub ls1) where action ls0 ls1 = do v1 <- run $ S.toList $ Top.joinLeft eq (S.fromList ls0) (S.fromList ls1) let v2 = joinLeftList (map (\a -> (a,a)) ls0) (map (\a -> (a,a)) ls1) v3 = map (\ (_, x1, x2) -> (x1, x2)) v2 assert (v1 == v3) -} joinLeftMap :: Property joinLeftMap = forAll (listOf (chooseInt (min_value, max_value))) $ \ls0 -> forAll (listOf (chooseInt (min_value, max_value))) $ \ls1 -> -- nub the second list as no way to validate using list functions monadicIO $ action (map (\a -> (a,a)) ls0) (map (\a -> (a,a)) (nub ls1)) where action ls0 ls1 = do v1 <- run $ S.toList $ Top.joinLeftMap (S.fromList ls0) (S.fromList ls1) let v2 = joinLeftList ls0 ls1 assert (v1 == v2) intersectBy :: ([Int] -> [Int]) -> ( (Int -> Int -> a) -> SerialT IO Int -> SerialT IO Int -> SerialT IO Int ) -> (Int -> Int -> a) -> Property intersectBy srt intersectFunc cmp = forAll (listOf (chooseInt (min_value, max_value))) $ \ls0 -> forAll (listOf (chooseInt (min_value, max_value))) $ \ls1 -> monadicIO $ action (srt ls0) (srt ls1) where action ls0 ls1 = do v1 <- run $ S.toList $ intersectFunc cmp (S.fromList ls0) (S.fromList ls1) let v2 = ls0 `intersect` ls1 assert (sort v1 == sort v2) ------------------------------------------------------------------------------- -- Main ------------------------------------------------------------------------------- moduleName :: String moduleName = "Prelude.Top" main :: IO () main = hspec $ do describe moduleName $ do -- Joins prop "joinInner" Main.joinInner prop "joinInnerMap" Main.joinInnerMap -- prop "joinOuter" Main.joinOuter prop "joinOuterMap" Main.joinOuterMap -- prop "joinLeft" Main.joinLeft prop "joinLeftMap" Main.joinLeftMap -- intersect prop "intersectBy" (intersectBy id Top.intersectBy (==)) prop "intersectBySorted" (intersectBy sort Top.intersectBySorted compare)