@@ -6,14 +6,14 @@ module Test.FS (tests) where
66import Control.Concurrent.Class.MonadSTM (MonadSTM (atomically ))
77import Control.Concurrent.Class.MonadSTM.Strict.TMVar
88import Control.Monad
9+ import Control.Monad.Class.MonadThrow
910import Control.Monad.IOSim (runSimOrThrow )
1011import Control.Monad.ST (runST )
1112import Data.Bit (cloneFromByteString , cloneToByteString , flipBit )
1213import Data.ByteString (ByteString )
1314import qualified Data.ByteString as BS
14- import Data.Char (isAsciiLower , isAsciiUpper )
15- import qualified Data.List as List
16- import qualified Data.Text as Text
15+ import Data.Set (Set )
16+ import qualified Data.Set as Set
1717import Data.Vector.Unboxed (thaw , unsafeFreeze )
1818import GHC.Generics (Generic )
1919import System.FS.API
@@ -49,43 +49,16 @@ tests = testGroup "Test.FS" [
4949 Simulated file system properties
5050-------------------------------------------------------------------------------}
5151
52- newtype Path = Path FsPath
53- deriving stock (Show , Eq )
54-
55- newtype UniqueList a = UniqueList [a ]
56- deriving stock Show
57-
58- instance (Arbitrary a , Eq a ) => Arbitrary (UniqueList a ) where
59- arbitrary = do
60- xs <- arbitrary
61- pure (UniqueList (List. nub xs))
62- shrink (UniqueList [] ) = []
63- shrink (UniqueList xs) = UniqueList . List. nub <$> shrink xs
64-
65- instance Arbitrary Path where
66- arbitrary = Path . mkFsPath . (: [] ) <$> ((:) <$> genChar <*> listOf genChar)
67- where
68- genChar = elements ([' A' .. ' Z' ] ++ [' a' .. ' z' ])
69- shrink (Path p) = case fsPathToList p of
70- [] -> []
71- t: _ -> [
72- Path p'
73- | t' <- shrink t
74- , let t'' = Text. filter (\ c -> isAsciiUpper c || isAsciiLower c) t'
75- , not (Text. null t'')
76- , let p' = fsPathFromList [t']
77- ]
78-
7952-- | Sanity check for 'propNoOpenHandles' and 'propNumOpenHandles'
80- prop_numOpenHandles :: UniqueList Path -> Property
81- prop_numOpenHandles (UniqueList paths) = runSimOrThrow $
53+ prop_numOpenHandles :: Set FsPathComponent -> Property
54+ prop_numOpenHandles (Set. toList -> paths) = runSimOrThrow $
8255 withSimHasFS propTrivial MockFS. empty $ \ hfs fsVar -> do
8356 -- No open handles initially
8457 fs <- atomically $ readTMVar fsVar
8558 let prop = propNoOpenHandles fs
8659
8760 -- Open n handles
88- hs <- forM paths $ \ (Path p) -> hOpen hfs p (WriteMode MustBeNew )
61+ hs <- forM paths $ \ (fsPathComponentFsPath -> p) -> hOpen hfs p (WriteMode MustBeNew )
8962
9063 -- Now there should be precisely n open handles
9164 fs' <- atomically $ readTMVar fsVar
@@ -103,8 +76,12 @@ prop_numOpenHandles (UniqueList paths) = runSimOrThrow $
10376 n = length paths
10477
10578-- | Sanity check for 'propNoDirEntries' and 'propNumDirEntries'
106- prop_numDirEntries :: Path -> InfiniteList Bool -> UniqueList Path -> Property
107- prop_numDirEntries (Path dir) isFiles (UniqueList paths) = runSimOrThrow $
79+ prop_numDirEntries ::
80+ FsPathComponent
81+ -> InfiniteList Bool
82+ -> Set FsPathComponent
83+ -> Property
84+ prop_numDirEntries (fsPathComponentFsPath -> dir) isFiles (Set. toList -> paths) = runSimOrThrow $
10885 withSimHasFS propTrivial MockFS. empty $ \ hfs fsVar -> do
10986 createDirectoryIfMissing hfs False dir
11087
@@ -113,17 +90,17 @@ prop_numDirEntries (Path dir) isFiles (UniqueList paths) = runSimOrThrow $
11390 let prop = propNoDirEntries dir fs
11491
11592 -- Create n entries
116- forM_ xs $ \ (isFile, Path p) ->
93+ forM_ xs $ \ (isFile, fsPathComponentFsPath -> p) ->
11794 if isFile
118- then withFile hfs (dir </> p) ( WriteMode MustBeNew ) $ \ _ -> pure ( )
95+ then createFile hfs (dir </> p)
11996 else createDirectory hfs (dir </> p)
12097
12198 -- Now there should be precisely n entries
12299 fs' <- atomically $ readTMVar fsVar
123100 let prop' = propNumDirEntries dir n fs'
124101
125102 -- Remove n entries
126- forM_ xs $ \ (isFile, Path p) ->
103+ forM_ xs $ \ (isFile, fsPathComponentFsPath -> p) ->
127104 if isFile
128105 then removeFile hfs (dir </> p)
129106 else removeDirectoryRecursive hfs (dir </> p)
@@ -137,6 +114,9 @@ prop_numDirEntries (Path dir) isFiles (UniqueList paths) = runSimOrThrow $
137114 n = length paths
138115 xs = zip (getInfiniteList isFiles) paths
139116
117+ createFile :: MonadThrow m => HasFS m h -> FsPath -> m ()
118+ createFile hfs p = withFile hfs p (WriteMode MustBeNew ) $ \ _ -> pure ()
119+
140120{- ------------------------------------------------------------------------------
141121 Corruption
142122-------------------------------------------------------------------------------}
0 commit comments