2-- Module : Streamly.Test.FileSystem.Handle
3-- Copyright : (c) 2020 Composewell technologies
4-- License : BSD-3-Clause
5-- Maintainer : streamly@composewell.com
6-- Stability : experimental
9module Streamly.Test.FileSystem.Handle (main) where
11import Data.Functor.Identity (runIdentity)
12import Data.Word (Word8)
13import Foreign.Storable (Storable(..))
14import Streamly.Internal.Data.Stream.IsStream (IsStream, SerialT)
15import System.FilePath ((</>))
25import System.IO.Temp (withSystemTempDirectory)
26import Test.QuickCheck (Property, forAll, Gen, vectorOf, choose)
27import Test.QuickCheck.Monadic (monadicIO, assert, run)
29import qualified Streamly.Data.Fold as Fold
30import qualified Streamly.FileSystem.Handle as Handle
31import qualified Streamly.Internal.Data.Stream.IsStream as Stream
32import qualified Streamly.Internal.Data.Array.Storable.Foreign as Array
33import qualified Streamly.Internal.Unicode.Stream as Unicode
36import Test.Hspec.QuickCheck
39allocOverhead = 2 * sizeOf (undefined :: Int)
41defaultChunkSize :: Int
42defaultChunkSize = 32 * k - allocOverhead
46maxArrLen = defaultChunkSize * 8
51chooseWord8 :: (Word8, Word8) -> Gen Word8
54utf8ToString :: Array.Array Word8 -> String
56 runIdentity . Stream.toList . Unicode.decodeUtf8' . Array.toStream
59testData = "This is the test data for FileSystem.Handle ??`!@#$%^&*~~))`]"
61testDataLarge :: String
62testDataLarge = concat $ replicate 6000 testData
64executor :: (Handle -> SerialT IO Char) -> IO (SerialT IO Char)
66 withSystemTempDirectory "fs_handle" $ \fp -> do
67 let fpath = fp </> "tmp_read.txt"
68 writeFile fpath testDataLarge
69 h <- openFile fpath ReadMode
72readFromHandle :: IO (SerialT IO Char)
74 let f = Unicode.decodeUtf8 . Stream.unfold Handle.read
77readWithBufferFromHandle :: IO (SerialT IO Char)
78readWithBufferFromHandle =
79 let f1 = (\h -> (1024, h))
80 f2 = Unicode.decodeUtf8 . Stream.unfold Handle.readWithBufferOf . f1
83readChunksFromHandle :: IO (SerialT IO Char)
85 let f = Unicode.decodeUtf8
86 . Stream.concatMap Array.toStream
87 . Stream.unfold Handle.readChunks
90readChunksWithBuffer :: IO (SerialT IO Char)
92 let f1 = (\h -> (1024, h))
95 . Stream.concatMap Array.toStream
96 . Stream.unfold Handle.readChunksWithBufferOf
100testRead :: (IsStream t) => IO (t IO Char) -> Property
101testRead fn = monadicIO $ do
102 let v2 = Stream.fromList testDataLarge
104 res <- run $ Stream.eqBy (==) v1 v2
107testWrite :: (Handle -> Fold.Fold IO Word8 ()) -> Property
109 forAll (choose (0, maxArrLen)) $ \len ->
110 forAll (vectorOf len $ chooseWord8 (0, 255)) $ \list0 ->
112 res <- run $ go list0
118 withSystemTempDirectory "fs_handle" $ \fp -> do
119 let fpathWrite = fp </> "tmp_write.txt"
120 writeFile fpathWrite ""
121 h <- openFile fpathWrite ReadWriteMode
122 hSeek h AbsoluteSeek 0
123 Stream.fold (hfold h) $ Stream.fromList list
125 hSeek h AbsoluteSeek 0
126 ls <- Stream.toList $ Stream.unfold Handle.read h
130testWriteWithChunk :: Property
139 withSystemTempDirectory "fs_handle" $ \fp -> do
140 let fpathRead = fp </> "tmp_read.txt"
141 fpathWrite = fp </> "tmp_write.txt"
142 writeFile fpathRead testDataLarge
143 writeFile fpathWrite ""
144 hr <- openFile fpathRead ReadMode
145 hw <- openFile fpathWrite ReadWriteMode
146 hSeek hw AbsoluteSeek 0
147 Stream.fold (Handle.writeChunks hw)
148 $ Stream.unfold Handle.readChunksWithBufferOf (1024, hr)
150 hSeek hw AbsoluteSeek 0
151 ls <- Stream.toList $ Stream.unfold Handle.read hw
152 let arr = Array.fromList ls
153 return (testDataLarge == utf8ToString arr)
159 modifyMaxSuccess (const maxTestCount) $ do
160 describe "Read From Handle" $ do
161 prop "read" $ testRead readFromHandle
162 prop "readWithBufferOf" $ testRead readWithBufferFromHandle
163 prop "readChunks" $ testRead readChunksFromHandle
164 prop "readChunksWithBufferOf" $ testRead readChunksWithBuffer
165 describe "Write To Handle" $ do
166 prop "write" $ testWrite Handle.write
167 prop "writeWithBufferOf" $ testWrite $ Handle.writeWithBufferOf 1024
168 prop "writeChunks" testWriteWithChunk
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list