mirror of
https://github.com/ilyakooo0/streamly.git
synced 2024-10-26 09:59:48 +03:00
225 lines
6.8 KiB
Haskell
225 lines
6.8 KiB
Haskell
{-# 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 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)
|