Add test cases for Data.Fold/Array, FileSystem.Handle

Added the following test cases to Data.Fold:

drain, drainBy, mean, stdDev, variance, mconcat, foldMap, foldMapM,
lookup, mapM, teeWithLength, teeWithMax, distribute, partition, unzip

Added the following test cases to Data.Array.Storable.Foreign

* fromList and fromListN

Added FileSystem.Handle module
This commit is contained in:
Ranjeet Ranjan 2020-11-30 21:40:28 +05:30 committed by Harendra Kumar
parent 2e0a445514
commit 0bd1586175
5 changed files with 465 additions and 74 deletions

View File

@ -168,6 +168,7 @@ extra-source-files:
test/Streamly/Test/Data/Array/Storable/Foreign.hs
test/Streamly/Test/Data/Parser/ParserD.hs
test/Streamly/Test/FileSystem/Event.hs
test/Streamly/Test/FileSystem/Handle.hs
test/Streamly/Test/Prelude.hs
test/Streamly/Test/Prelude/*.hs
test/Streamly/Test/Unicode/Stream.hs

View File

@ -16,12 +16,10 @@ import Foreign.Storable (Storable(..))
import Test.Hspec.QuickCheck
import Test.QuickCheck (Property, forAll, Gen, vectorOf, arbitrary, choose)
import Test.QuickCheck.Monadic (monadicIO, assert, run)
import Test.Hspec as H
import Streamly.Prelude (SerialT)
import qualified Streamly.Prelude as S
#ifdef TEST_SMALL_ARRAY
import qualified Streamly.Internal.Data.SmallArray as A
type Array = A.SmallArray
@ -125,12 +123,31 @@ testFromStreamNUnfold = genericTestFromTo A.fromStreamN (S.unfold A.read) (==)
testFromStreamNToStream :: Property
testFromStreamNToStream = genericTestFromTo A.fromStreamN A.toStream (==)
testFromListN :: Property
testFromListN =
forAll (choose (0, maxArrLen)) $ \len ->
forAll (choose (0, len)) $ \n ->
forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
monadicIO $ do
let arr = A.fromListN n list
xs <- run $ S.toList $ (S.unfold A.read) arr
assert (xs == take n list)
#ifndef TEST_SMALL_ARRAY
testFromStreamToStream :: Property
testFromStreamToStream = genericTestFromTo (const A.fromStream) A.toStream (==)
testFoldUnfold :: Property
testFoldUnfold = genericTestFromTo (const (S.fold A.write)) (S.unfold A.read) (==)
testFromList :: Property
testFromList =
forAll (choose (0, maxArrLen)) $ \len ->
forAll (vectorOf len (arbitrary :: Gen Int)) $ \list ->
monadicIO $ do
let arr = A.fromList list
xs <- run $ S.toList $ (S.unfold A.read) arr
assert (xs == list)
#endif
#if defined(TEST_ARRAY) ||\
@ -202,10 +219,13 @@ main =
prop "toStreamRev . writeN === reverse" testFoldNToStreamRev
prop "read . fromStreamN === id" testFromStreamNUnfold
prop "toStream . fromStreamN === id" testFromStreamNToStream
prop "First N elements of a list" testFromListN
#ifndef TEST_SMALL_ARRAY
prop "length . fromStream === n" testLengthFromStream
prop "toStream . fromStream === id" testFromStreamToStream
prop "read . write === id" testFoldUnfold
prop "From a list" testFromList
#endif
#if defined(TEST_ARRAY) ||\

View File

@ -1,16 +1,31 @@
module Main (main) where
import Prelude hiding
(maximum, minimum, elem, notElem, null, product, sum, head, last)
import Data.Semigroup (Sum(..), getSum)
import Test.QuickCheck
( Gen
, Property
, arbitrary
, choose
, forAll
, listOf
, listOf1
, property
, vectorOf
, withMaxSuccess
)
import Prelude hiding
(maximum, minimum, elem, notElem, null, product, sum, head, last)
import Streamly.Test.Common (checkListEqual)
import Prelude hiding (maximum, minimum, elem, notElem, null, product, sum, head, last)
import Test.QuickCheck.Monadic (monadicIO, assert, run)
import qualified Streamly.Internal.Data.Fold as F
import qualified Streamly.Prelude as S
import qualified Streamly.Data.Fold as FL
import Test.Hspec as H
import Test.Hspec.QuickCheck
import Test.QuickCheck
(Property, property, forAll, Gen, vectorOf, arbitrary, choose, listOf)
import Test.QuickCheck.Monadic (monadicIO, assert, run)
maxStreamLen :: Int
maxStreamLen = 1000
@ -43,75 +58,75 @@ rollingHashFirstN =
b <- run $ S.fold (F.rollingHashFirstN n) $ S.fromList vec
assert $ a == b
head :: [Int] -> Expectation
head ls = S.fold FL.head (S.fromList ls) `shouldReturn` headl ls
where
headl [] = Nothing
headl (x:_) = Just x
where
headl [] = Nothing
headl (x:_) = Just x
length :: [Int] -> Expectation
length ls = S.fold FL.length (S.fromList ls) `shouldReturn` Prelude.length ls
sum :: [Int] -> Expectation
sum ls = S.fold FL.sum (S.fromList ls) `shouldReturn` foldl (+) 0 ls
product :: [Int] -> Expectation
product ls = S.fold FL.product (S.fromList ls) `shouldReturn` foldl (*) 1 ls
lesser :: (a -> a -> Ordering) -> a -> a -> a
lesser f x y = if f x y == LT then x else y
greater :: (a -> a -> Ordering) -> a -> a -> a
greater f x y = if f x y == GT then x else y
foldMaybe :: (b -> a -> b) -> b -> [a] -> Maybe b
foldMaybe f acc ls =
case ls of
[] -> Nothing
_ -> Just (foldl f acc ls)
case ls of
[] -> Nothing
_ -> Just (foldl f acc ls)
maximumBy :: (Ord a, Show a) => a -> (a -> a -> Ordering) -> [a] -> Expectation
maximumBy genmin f ls = S.fold (FL.maximumBy f) (S.fromList ls) `shouldReturn` foldMaybe (greater f) genmin ls
maximumBy genmin f ls =
S.fold (FL.maximumBy f) (S.fromList ls)
`shouldReturn`
foldMaybe (greater f) genmin ls
maximum :: (Show a, Ord a) => a -> [a] -> Expectation
maximum genmin ls = S.fold FL.maximum (S.fromList ls) `shouldReturn` foldMaybe (greater compare) genmin ls
maximum genmin ls =
S.fold FL.maximum (S.fromList ls)
`shouldReturn` foldMaybe (greater compare) genmin ls
minimumBy :: (Ord a, Show a) => a -> (a -> a -> Ordering) -> [a] -> Expectation
minimumBy genmax f ls = S.fold (FL.minimumBy f) (S.fromList ls) `shouldReturn` foldMaybe (lesser f) genmax ls
minimumBy genmax f ls =
S.fold (FL.minimumBy f) (S.fromList ls)
`shouldReturn` foldMaybe (lesser f) genmax ls
minimum :: (Show a, Ord a) => a -> [a] -> Expectation
minimum genmax ls = S.fold FL.minimum (S.fromList ls) `shouldReturn` foldMaybe (lesser compare) genmax ls
minimum genmax ls =
S.fold FL.minimum (S.fromList ls)
`shouldReturn` foldMaybe (lesser compare) genmax ls
toList :: [Int] -> Expectation
toList ls = S.fold FL.toList (S.fromList ls) `shouldReturn` ls
safeLast :: [a] -> Maybe a
safeLast [] = Nothing
safeLast (x:[]) = Just x
safeLast (_:xs) = safeLast xs
last :: [String] -> Expectation
last ls = S.fold FL.last (S.fromList ls) `shouldReturn` safeLast ls
mapMaybe :: [Int] -> Expectation
mapMaybe ls =
(let f = F.mapMaybe (\x -> if even x then Just x else Nothing) FL.toList
in S.fold f (S.fromList ls))
`shouldReturn` filter even ls
let maybeEven x =
if even x
then Just x
else Nothing
f = F.mapMaybe maybeEven FL.toList
in S.fold f (S.fromList ls) `shouldReturn` filter even ls
nth :: Int -> [a] -> Maybe a
nth idx (x:xs) = if idx == 0
@ -121,48 +136,52 @@ nth idx (x:xs) = if idx == 0
else nth (idx - 1) xs
nth _ [] = Nothing
index :: Int -> [String] -> Expectation
index idx ls = let x = S.fold (FL.index idx) (S.fromList ls)
in x `shouldReturn` (nth idx ls)
find :: (Show a, Eq a) => (a -> Bool) -> [a] -> Expectation
find f ls = do
let x = S.fold (FL.findIndex f) (S.fromList ls)
y <- x
case y of
Nothing -> S.fold (FL.find f) (S.fromList ls) `shouldReturn` Nothing
Just idx -> S.fold (FL.any f) (S.fromList $ take idx ls) `shouldReturn` False
y <- S.fold (FL.findIndex f) (S.fromList ls)
case y of
Nothing ->
let fld = S.fold (FL.find f) (S.fromList ls)
in fld `shouldReturn` Nothing
Just idx ->
let fld = S.fold (FL.any f) (S.fromList $ take idx ls)
in fld `shouldReturn` False
neg :: (a -> Bool) -> a -> Bool
neg f x = if f x == True then False else True
findIndex :: (a -> Bool) -> [a] -> Expectation
findIndex f ls = do
let x = S.fold (FL.findIndex f) (S.fromList ls)
y <- x
case y of
Nothing -> S.fold (FL.all $ neg f) (S.fromList ls) `shouldReturn` True
Just idx -> if idx == 0
then S.fold (FL.all f) (S.fromList []) `shouldReturn` True
else S.fold (FL.all f) (S.fromList $ (take idx ls)) `shouldReturn` False
y <- S.fold (FL.findIndex f) (S.fromList ls)
case y of
Nothing ->
let fld = S.fold (FL.all $ neg f) (S.fromList ls)
in fld `shouldReturn` True
Just idx -> if idx == 0
then
S.fold (FL.all f) (S.fromList []) `shouldReturn` True
else
S.fold (FL.all f) (S.fromList $ (take idx ls))
`shouldReturn`
False
predicate :: Int -> Bool
predicate x = if x * x < 100 then True else False
elemIndex :: Int -> [Int] -> Expectation
elemIndex elm ls = do
let x = S.fold (FL.elemIndex elm) (S.fromList ls)
y <- x
case y of
Nothing -> S.fold (FL.any (\z -> if z == elm
then True
else False)) (S.fromList ls) `shouldReturn` False
Just idx -> S.fold (FL.any (\z -> if z == elm
then True
else False)) (S.fromList $ (take idx ls)) `shouldReturn` False
y <- S.fold (FL.elemIndex elm) (S.fromList ls)
case y of
Nothing ->
let fld = S.fold (FL.any (== elm)) (S.fromList ls)
in fld `shouldReturn` False
Just idx ->
let fld = S.fold (FL.any (== elm)) (S.fromList $ (take idx ls))
in fld `shouldReturn` False
null :: [Int] -> Expectation
null ls = S.fold FL.null (S.fromList ls) `shouldReturn` case ls of
@ -170,36 +189,26 @@ null ls = S.fold FL.null (S.fromList ls) `shouldReturn` case ls of
_ -> False
elem :: Int -> [Int] -> Expectation
elem elm ls = do
let x = S.fold (FL.elem elm) (S.fromList ls)
y <- x
S.fold (FL.any (\z -> if z == elm
then True
else False)) (S.fromList ls) `shouldReturn` y
y <- S.fold (FL.elem elm) (S.fromList ls)
let fld = S.fold (FL.any (== elm)) (S.fromList ls)
fld `shouldReturn` y
notElem :: Int -> [Int] -> Expectation
notElem elm ls = do
let x = S.fold (FL.notElem elm) (S.fromList ls)
y <- x
S.fold (FL.any (\z -> if z == elm
then True
else False)) (S.fromList ls) `shouldReturn` (if y == True
then False
else True)
y <- S.fold (FL.notElem elm) (S.fromList ls)
let fld = S.fold (FL.any (== elm)) (S.fromList ls)
fld `shouldReturn` not y
all :: (a -> Bool) -> [a] -> Expectation
all f ls = S.fold (FL.all f) (S.fromList ls) `shouldReturn` Prelude.and (map f ls)
all f ls =
S.fold (FL.all f) (S.fromList ls) `shouldReturn` Prelude.and (map f ls)
any :: (a -> Bool) -> [a] -> Expectation
any f ls = S.fold (FL.any f) (S.fromList ls) `shouldReturn` Prelude.any f ls
and :: [Bool] -> Expectation
and ls = S.fold FL.and (S.fromList ls) `shouldReturn` Prelude.and ls
or :: [Bool] -> Expectation
or ls = S.fold FL.or (S.fromList ls) `shouldReturn` Prelude.or ls
@ -230,6 +239,181 @@ sliceSepByMax =
Right xs -> checkListEqual xs ys
Left _ -> property False
chooseFloat :: (Float, Float) -> Gen Float
chooseFloat = choose
drain :: [Int] -> Expectation
drain ls = S.fold FL.drain (S.fromList ls) `shouldReturn` ()
drainBy :: [Int] -> Expectation
drainBy ls = S.fold (FL.drainBy return) (S.fromList ls) `shouldReturn` ()
mean :: Property
mean =
forAll (listOf1 (chooseFloat (-100.0, 100.0)))
$ \ls0 -> withMaxSuccess 1000 $ monadicIO $ action ls0
where
action ls = do
v1 <- run $ S.fold FL.mean (S.fromList ls)
let v2 = (foldl (+) 0 ls) / fromIntegral (Prelude.length ls)
assert (abs (v1 - v2) < 0.0001)
stdDev :: Property
stdDev =
forAll (listOf1 (chooseFloat (-100.0, 100.0)))
$ \ls0 -> withMaxSuccess 1000 $ monadicIO $ action ls0
where
action ls = do
v1 <- run $ S.fold FL.stdDev (S.fromList ls)
let avg = (foldl (+) 0 ls) / fromIntegral (Prelude.length ls)
se = (foldl (+) 0 (map (\x -> (x - avg) * (x - avg)) ls))
sd = sqrt $ se / fromIntegral (Prelude.length ls)
assert (abs (v1 - sd) < 0.0001 )
variance :: Property
variance =
forAll (listOf1 (chooseFloat (-100.0, 100.0)))
$ \ls0 -> withMaxSuccess 1000 $ monadicIO $ action ls0
where
action ls = do
v1 <- run $ S.fold FL.variance (S.fromList ls)
let avg = (foldl (+) 0 ls) / fromIntegral (Prelude.length ls)
se = (foldl (+) 0 (map (\x -> (x - avg) * (x - avg)) ls))
vr = se / fromIntegral (Prelude.length ls)
assert (abs (v1 - vr) < 0.01 )
mconcat :: Property
mconcat =
forAll (listOf1 (chooseInt (intMin, intMax)))
$ \ls0 -> monadicIO $ action ls0
where
action ls = do
v1 <- run $ S.fold FL.mconcat (S.map Sum $ S.fromList ls)
let v2 = (foldl (+) 0 ls)
assert (getSum v1 == v2)
foldMap :: Property
foldMap =
forAll (listOf1 (chooseInt (intMin, intMax)))
$ \ls0 -> monadicIO $ action ls0
where
action ls = do
v1 <- run $ S.fold (FL.foldMap Sum) $ S.fromList ls
let v2 = (foldl (+) 0 ls)
assert (getSum v1 == v2)
foldMapM :: Property
foldMapM =
forAll (listOf1 (chooseInt (intMin, intMax)))
$ \ls0 -> monadicIO $ action ls0
where
action ls = do
v1 <- run $ S.fold (FL.foldMapM (return . Sum)) $ S.fromList ls
let v2 = (foldl (+) 0 ls)
assert (getSum v1 == v2)
lookup :: Property
lookup =
forAll (chooseInt (1, 15))
$ \key0 ->monadicIO $ action key0
where
action key = do
let ls = [(1, "first"), (2, "second"), (3, "third"), (4, "fourth")
, (5, "fifth"), (6, "fifth+first"), (7, "fifth+second")
, (8, "fifth+third"), (9, "fifth+fourth")
, (10, "fifth+fifth")]
v1 <- run $ S.fold (FL.lookup key) $ S.fromList ls
let v2 = Prelude.lookup key ls
assert (v1 == v2)
mapM :: Property
mapM =
forAll (listOf1 (chooseInt (intMin, intMax)))
$ \ls0 -> monadicIO $ action ls0
where
action ls = do
let addLen x = return $ x + Prelude.length ls
fld = FL.mapM addLen FL.sum
v2 = foldl (+) (Prelude.length ls) ls
v1 <- run $ S.fold fld $ S.fromList ls
assert (v1 == v2)
teeWithLength :: Property
teeWithLength =
forAll (listOf1 (chooseInt (intMin, intMax)))
$ \ls0 -> monadicIO $ action ls0
where
action ls = do
v1 <- run $ S.fold (FL.tee FL.sum FL.length) $ S.fromList ls
let v2 = foldl (+) 0 ls
v3 = Prelude.length ls
assert (v1 == (v2, v3))
teeWithMax :: Property
teeWithMax =
forAll (listOf1 (chooseInt (intMin, intMax)))
$ \ls0 -> monadicIO $ action ls0
where
action ls = do
v1 <- run $ S.fold (FL.tee FL.sum FL.maximum) $ S.fromList ls
let v2 = foldl (+) 0 ls
v3 = foldMaybe (greater compare) intMin ls
assert (v1 == (v2, v3))
distribute :: Property
distribute =
forAll (listOf1 (chooseInt (intMin, intMax)))
$ \ls0 -> monadicIO $ action ls0
where
action ls = do
v1 <- run $ S.fold (FL.distribute [FL.sum, FL.length]) $ S.fromList ls
let v2 = foldl (+) 0 ls
v3 = Prelude.length ls
assert (v1 == [v2, v3])
partition :: Property
partition =
monadicIO $ do
v1 :: (Int, [String]) <-
run
$ S.fold (FL.partition FL.sum FL.toList)
$ S.fromList
[Left 1, Right "abc", Left 3, Right "xy", Right "pp2"]
let v2 = (4,["abc","xy","pp2"])
assert (v1 == v2)
unzip :: Property
unzip =
monadicIO $ do
v1 :: (Int, [String]) <-
run
$ S.fold (FL.unzip FL.sum FL.toList)
$ S.fromList [(1, "aa"), (2, "bb"), (3, "cc")]
let v2 = (6, ["aa", "bb", "cc"])
assert (v1 == v2)
main :: IO ()
main = hspec $
describe "Fold s" $ do
@ -259,3 +443,18 @@ main = hspec $
prop "ltake" ltake
prop "sliceSepBy" sliceSepBy
prop "sliceSepByMax" sliceSepByMax
prop "drain" Main.drain
prop "drainBy" Main.drainBy
prop "mean" Main.mean
prop "stdDev" Main.stdDev
prop "variance" Main.variance
prop "mconcat" Main.mconcat
prop "foldMap" Main.foldMap
prop "foldMapM" Main.foldMapM
prop "lookup" Main.lookup
prop "mapM" Main.mapM
prop "teeWithLength" Main.teeWithLength
prop "teeWithMax" Main.teeWithMax
prop "distribute" Main.distribute
prop "partition" Main.partition
prop "unzip" Main.unzip

View File

@ -0,0 +1,165 @@
-- |
-- Module : Streamly.Test.FileSystem.Handle
-- Copyright : (c) 2020 Composewell technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
-- Stability : experimental
-- Portability : GHC
module Streamly.Test.FileSystem.Handle (main) where
import Data.Functor.Identity (runIdentity)
import Data.Word (Word8)
import Foreign.Storable (Storable(..))
import Streamly.Internal.Data.Stream.IsStream (IsStream, SerialT)
import System.FilePath ((</>))
import System.IO
( Handle
, IOMode(..)
, SeekMode(..)
, hClose
, hFlush
, hSeek
, openFile
)
import System.IO.Temp (withSystemTempDirectory)
import Test.QuickCheck (Property, forAll, Gen, vectorOf, choose)
import Test.QuickCheck.Monadic (monadicIO, assert, run)
import Streamly.FileSystem.Handle as FH
import Test.Hspec as H
import Test.Hspec.QuickCheck
import qualified Streamly.Data.Fold as FL
import qualified Streamly.Internal.Data.Stream.IsStream as S
import qualified Streamly.Internal.Data.Array.Storable.Foreign as A
import qualified Streamly.Internal.Unicode.Stream as U
allocOverhead :: Int
allocOverhead = 2 * sizeOf (undefined :: Int)
defaultChunkSize :: Int
defaultChunkSize = 32 * k - allocOverhead
where k = 1024
maxArrLen :: Int
maxArrLen = defaultChunkSize * 8
maxTestCount :: Int
maxTestCount = 10
chooseWord8 :: (Word8, Word8) -> Gen Word8
chooseWord8 = choose
utf8ToString :: A.Array Word8 -> String
utf8ToString = runIdentity . S.toList . U.decodeUtf8' . A.toStream
testData :: String
testData = "This is the test data for FileSystem.Handle ??`!@#$%^&*~~))`]"
testDataLarge :: String
testDataLarge = concat $ replicate 6000 testData
executor :: (Handle -> (SerialT IO Char)) -> IO (SerialT IO Char)
executor f =
withSystemTempDirectory "fs_handle" $ \fp -> do
let fpath = fp </> "tmp_read.txt"
writeFile fpath testDataLarge
h <- openFile fpath ReadMode
return $ f h
readFromHandle :: IO (SerialT IO Char)
readFromHandle =
let f = U.decodeUtf8 . S.unfold FH.read
in executor f
readWithBufferFromHandle :: IO (SerialT IO Char)
readWithBufferFromHandle =
let f1 = (\h -> (1024, h))
f2 = U.decodeUtf8 . S.unfold FH.readWithBufferOf . f1
in executor f2
readChunksFromHandle :: IO (SerialT IO Char)
readChunksFromHandle =
let f = U.decodeUtf8 . S.concatMap (A.toStream) . S.unfold FH.readChunks
in executor f
readChunksWithBuffer :: IO (SerialT IO Char)
readChunksWithBuffer =
let f1 = (\h -> (1024, h))
f2 =
U.decodeUtf8
. S.concatMap (A.toStream)
. S.unfold FH.readChunksWithBufferOf
. f1
in executor f2
testRead :: (IsStream t) => IO (t IO Char) -> Property
testRead fn = monadicIO $ do
let v2 = (S.fromList testDataLarge)
v1 <- run $ fn
res <- run $ S.eqBy (==) v1 v2
assert (res)
testWrite :: (Handle -> FL.Fold IO Word8 ()) -> Property
testWrite hfold =
forAll (choose (0, maxArrLen)) $ \len ->
forAll (vectorOf len $ chooseWord8 (0, 255)) $ \list0 ->
monadicIO $ do
res <- run $ go list0
assert res
where
go list =
withSystemTempDirectory "fs_handle" $ \fp -> do
let fpathWrite = fp </> "tmp_write.txt"
writeFile fpathWrite ""
h <- openFile fpathWrite ReadWriteMode
hSeek h AbsoluteSeek 0
S.fold (hfold h) $ S.fromList list
hFlush h
hSeek h AbsoluteSeek 0
ls <- S.toList $ S.unfold FH.read h
hClose h
return (ls == list)
testWriteWithChunk :: Property
testWriteWithChunk =
monadicIO $ do
res <- run $ go
assert res
where
go =
withSystemTempDirectory "fs_handle" $ \fp -> do
let fpathRead = fp </> "tmp_read.txt"
fpathWrite = fp </> "tmp_write.txt"
writeFile fpathRead testDataLarge
writeFile fpathWrite ""
hr <- openFile fpathRead ReadMode
hw <- openFile fpathWrite ReadWriteMode
hSeek hw AbsoluteSeek 0
S.fold (FH.writeChunks hw)
$ S.unfold FH.readChunksWithBufferOf (1024, hr)
hFlush hw
hSeek hw AbsoluteSeek 0
ls <- S.toList $ S.unfold FH.read hw
let arr = A.fromList ls
return (testDataLarge == utf8ToString arr)
main :: IO ()
main =
hspec $
H.parallel $
modifyMaxSuccess (const maxTestCount) $ do
describe "Read" $ do
prop "testRead" $ testRead readFromHandle
prop "testReadWithBuffer" $ testRead readWithBufferFromHandle
prop "testReadChunks" $ testRead readChunksFromHandle
prop "testReadChunksWithBuffer" $ testRead readChunksWithBuffer
describe "Write" $ do
prop "testWrite" $ testWrite FH.write
prop "testWriteWithBufferOf" $ testWrite $ FH.writeWithBufferOf 1024
prop "testWriteWithChunk" $ testWriteWithChunk

View File

@ -330,3 +330,9 @@ test-suite FileSystem.Event
main-is: Streamly/Test/FileSystem/Event.hs
if os(darwin)
buildable: False
test-suite FileSystem.Handle
import: test-options
type: exitcode-stdio-1.0
main-is: Streamly/Test/FileSystem/Handle.hs
ghc-options: -main-is Streamly.Test.FileSystem.Handle.main