Skip to content

Commit 91d748d

Browse files
authored
Merge pull request #72 from input-output-hk/jdral/71-fspath
Only generate valid names for `FsPath` tests
2 parents 47879aa + c8998df commit 91d748d

File tree

3 files changed

+34
-7
lines changed

3 files changed

+34
-7
lines changed

fs-api/CHANGELOG.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,8 @@
2929

3030
### Patch
3131

32-
* Add a clarification in the documentation of `fsPathFromList` that each path
33-
component should be non-empty, because directories/files with empty names are
34-
not valid! Also, add an `assert`ion to `fsPathFromList` for this precondition.
32+
* Add a clarification in the documentation of `FsPath` that the user is
33+
responsible for picking sensible directory/file names.
3534

3635
## 0.2.0.1 -- 2023-10-30
3736

fs-api/src/System/FS/API/Types.hs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,34 @@ allowExisting openMode = case openMode of
101101
-------------------------------------------------------------------------------}
102102

103103
-- | A relative path.
104+
--
105+
-- === Invariant
106+
--
107+
-- The user of this library is tasked with picking sensible names of
108+
-- directories/files on a path. Amongst others, the following should hold:
109+
--
110+
-- * Names are non-empty
111+
--
112+
-- * Names are monotonic, i.e., they are not equal to @..@
113+
--
114+
-- * Names should not contain path separators or drive letters
115+
--
116+
-- In particular, names that satisfy these invariants should result in an
117+
-- 'FsPath' that remains relative to the HasFS instance root. For example, an
118+
-- @'FsPath' ["/"]@ would try to access the root folder, which is most likely
119+
-- outside of the scope of the HasFS instance.
120+
--
121+
-- \"@..@\" should not be used because @fs-sim@ will not be able to follow these
122+
-- types of back-links. @fs-sim@ will interpret \"@..@\" as a directory name
123+
-- instead.
104124
newtype FsPath = UnsafeFsPath { fsPathToList :: [Strict.Text] }
105125
deriving (Eq, Ord, Generic)
106126
deriving newtype NFData
107127

108128
-- | Create a path from a list of directory/file names. All of the names should
109129
-- be non-empty.
110130
fsPathFromList :: [Strict.Text] -> FsPath
111-
fsPathFromList xs = assert (not (any Strict.null xs)) $ UnsafeFsPath (force xs)
131+
fsPathFromList xs = UnsafeFsPath (force xs)
112132

113133
instance Show FsPath where
114134
show = intercalate "/" . map Strict.unpack . fsPathToList

fs-api/test/Test/System/FS/API/FsPath.hs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,16 @@ tests = testGroup "Test.System.FS.API.FsPath" [
1919

2020
-- | Orphan instance that generates a __non-empty__ text!
2121
instance Arbitrary Text where
22-
arbitrary = Text.pack <$> (arbitrary `suchThat` (not . null))
23-
shrink x = [Text.pack x'' | let x' = Text.unpack x, x'' <- shrink x']
22+
arbitrary = Text.pack <$> QC.listOf (QC.elements validChars) `suchThat` (not . null)
23+
shrink x = [ x''' | let x' = Text.unpack x
24+
, x'' <- shrink x'
25+
, not (null x'')
26+
, let x''' = Text.pack x'' ]
27+
28+
-- | We pick a small subset of characters to use in directory/file names, so
29+
-- that we don't break the invariant of 'FsPath'.
30+
validChars :: [Char]
31+
validChars = concat [['a'..'z'], ['A'..'Z'], ['0'..'9']]
2432

2533
-- | Commutativity property for 'FS.</>' and 'FilePath.</>'.
2634
--
@@ -65,7 +73,7 @@ prop_addExtensionCommutes mnt path ext =
6573
.&&. FilePath.makeValid lhs === FilePath.makeValid rhs
6674
where
6775
mnt' = filePathFromList mnt
68-
mnt'' = FS.MountPoint (filePathFromList mnt)
76+
mnt'' = FS.MountPoint mnt'
6977
fsp = FS.fsPathFromList path FS.<.> ext
7078
lhs = FS.fsToFilePath mnt'' fsp
7179
rhs = mnt' FilePath.</> filePathFromList path FilePath.<.> ext

0 commit comments

Comments
 (0)