system-filepath 0.4.10 → 0.4.11
raw patch · 11 files changed
+820/−798 lines, 11 filesdep +QuickCheckdep +chelldep +chell-quickcheckdep ~basedep ~bytestringdep ~text
Dependencies added: QuickCheck, chell, chell-quickcheck, system-filepath
Dependency ranges changed: base, bytestring, text
Files
- lib/Filesystem/Path.hs +7/−4
- lib/Filesystem/Path/Internal.hs +9/−4
- lib/Filesystem/Path/Rules.hs +88/−25
- scripts/common.bash +0/−23
- scripts/run-benchmarks +0/−21
- scripts/run-coverage +0/−21
- scripts/run-tests +0/−17
- system-filepath.cabal +20/−12
- tests/FilesystemPathTests.hs +696/−0
- tests/Tests.hs +0/−642
- tests/system-filepath-tests.cabal +0/−29
lib/Filesystem/Path.hs view
@@ -150,8 +150,10 @@ absolute :: FilePath -> Bool absolute p = case pathRoot p of Just RootPosix -> True- Just (RootWindowsVolume _) -> True- _ -> False+ Just RootWindowsVolume{} -> True+ Just RootWindowsCurrentVolume -> False+ Just RootWindowsUnc{} -> True+ Nothing -> False -- | Test whether a path is relative. relative :: FilePath -> Bool@@ -169,10 +171,11 @@ append x y = cased where cased = case pathRoot y of Just RootPosix -> y- Just (RootWindowsVolume _) -> y+ Just RootWindowsVolume{} -> y Just RootWindowsCurrentVolume -> case pathRoot x of- Just (RootWindowsVolume _) -> y { pathRoot = pathRoot x }+ Just RootWindowsVolume{} -> y { pathRoot = pathRoot x } _ -> y+ Just RootWindowsUnc{} -> y Nothing -> xy xy = y { pathRoot = pathRoot x
lib/Filesystem/Path/Internal.hs view
@@ -38,9 +38,10 @@ data Root = RootPosix- | RootWindowsVolume Char+ | RootWindowsVolume Char Bool | RootWindowsCurrentVolume- deriving (Eq, Ord, Data, Typeable)+ | RootWindowsUnc String String Bool+ deriving (Eq, Ord, Data, Typeable, Show) data FilePath = FilePath { pathRoot :: Maybe Root@@ -62,7 +63,8 @@ )) instance NFData Root where- rnf (RootWindowsVolume c) = rnf c+ rnf (RootWindowsVolume c extended) = rnf c `seq` rnf extended+ rnf (RootWindowsUnc host share extended) = rnf host `seq` rnf share `seq` rnf extended rnf _ = () instance NFData FilePath where@@ -88,8 +90,11 @@ rootChunk :: Maybe Root -> Chunk rootChunk r = flip (maybe "") r $ \r' -> case r' of RootPosix -> "/"- RootWindowsVolume c -> c : ":\\"+ RootWindowsVolume c False -> c : ":\\"+ RootWindowsVolume c True -> "\\\\?\\" ++ (c : ":\\") RootWindowsCurrentVolume -> "\\"+ RootWindowsUnc host share False -> "\\\\" ++ host ++ "\\" ++ share+ RootWindowsUnc host share True -> "\\\\?\\UNC\\" ++ host ++ "\\" ++ share rootText :: Maybe Root -> T.Text rootText = T.pack . rootChunk
lib/Filesystem/Path/Rules.hs view
@@ -265,41 +265,99 @@ } winToText :: FilePath -> T.Text-winToText p = T.concat (root : chunks) where+winToText p = case pathRoot p of+ Just RootWindowsUnc{} -> uncToText p+ _ -> dosToText p++dosToText :: FilePath -> T.Text+dosToText p = T.concat (root : chunks) where root = rootText (pathRoot p) chunks = intersperse (T.pack "\\") (map unescape' (directoryChunks p)) +uncToText :: FilePath -> T.Text+uncToText p = T.concat (root : chunks) where+ root = if all T.null chunks+ then rootText (pathRoot p)+ else rootText (pathRoot p) `T.append` T.pack "\\"+ chunks = intersperse (T.pack "\\") (filter (not . T.null) (map unescape' (directoryChunks p)))+ winFromText :: T.Text -> FilePath winFromText text = if T.null text then empty else path where path = FilePath root directories basename exts - split = textSplitBy (\c -> c == '/' || c == '\\') text- - (root, pastRoot) = let- head' = head split- tail' = tail split- in if T.null head'- then (Just RootWindowsCurrentVolume, tail')- else if T.any (== ':') head'- then (Just (parseDrive head'), tail')- else (Nothing, split)- - parseDrive = RootWindowsVolume . toUpper . T.head+ -- Windows has various types of absolute paths:+ --+ -- * C:\foo\bar -> DOS-style absolute path+ -- * \\?\C:\foo\bar -> extended-length absolute path+ -- * \\host\share\foo\bar -> UNC path+ -- * \\?\UNC\host\share\foo\bar -> extended-length UNC path+ --+ -- \foo\bar looks like an absolute path, but is actually a path+ -- relative to the current DOS drive.+ --+ -- http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx+ (root, pastRoot) = if T.isPrefixOf (T.pack "\\\\") text+ then case stripUncasedPrefix (T.pack "\\\\?\\UNC\\") text of+ Just stripped -> parseUncRoot stripped True+ Nothing -> case T.stripPrefix (T.pack "\\\\?\\") text of+ Just stripped -> parseDosRoot stripped True+ Nothing -> case T.stripPrefix (T.pack "\\\\") text of+ Just stripped -> parseUncRoot stripped False+ Nothing -> parseDosRoot text False+ else parseDosRoot text False (directories, filename)- | P.null pastRoot = ([], "")+ | P.null pastRoot = ([], Nothing) | otherwise = case last pastRoot of- fn | fn == T.pack "." -> (goodDirs pastRoot, "")- fn | fn == T.pack ".." -> (goodDirs pastRoot, "")- fn -> (goodDirs (init pastRoot), escape fn)+ fn | fn == T.pack "." -> (goodDirs pastRoot, Just "")+ fn | fn == T.pack ".." -> (goodDirs pastRoot, Just "")+ fn -> (goodDirs (init pastRoot), Just (escape fn)) goodDirs :: [T.Text] -> [Chunk] goodDirs = map escape . filter (not . T.null) - (basename, exts) = parseFilename filename+ (basename, exts) = case filename of+ Just fn -> parseFilename fn+ Nothing -> (Nothing, []) +stripUncasedPrefix :: T.Text -> T.Text -> Maybe T.Text+stripUncasedPrefix prefix text = if T.toCaseFold prefix == T.toCaseFold (T.take (T.length prefix) text)+ then Just (T.drop (T.length prefix) text)+ else Nothing++parseDosRoot :: T.Text -> Bool -> (Maybe Root, [T.Text])+parseDosRoot text extended = parsed where+ split = textSplitBy (\c -> c == '/' || c == '\\') text+ + head' = head split+ tail' = tail split+ parsed = if T.null head'+ then (Just RootWindowsCurrentVolume, tail')+ else if T.any (== ':') head'+ then (Just (parseDrive head'), tail')+ else (Nothing, split)+ + parseDrive c = RootWindowsVolume (toUpper (T.head c)) extended++parseUncRoot :: T.Text -> Bool -> (Maybe Root, [T.Text])+parseUncRoot text extended = parsed where+ (host, pastHost) = T.break (== '\\') text+ (share, pastShare) = T.break (== '\\') (T.drop 1 pastHost)+ split = if T.null pastShare+ then []+ else textSplitBy (== '\\') pastShare+ parsed = (Just (RootWindowsUnc (T.unpack host) (T.unpack share) extended), split)+ winValid :: FilePath -> Bool-winValid p = validRoot && noReserved && validCharacters where+winValid p = case pathRoot p of+ Nothing -> dosValid p+ Just RootWindowsCurrentVolume -> dosValid p+ Just (RootWindowsVolume v _) -> elem v ['A'..'Z'] && dosValid p+ Just (RootWindowsUnc host share _) -> uncValid p host share+ Just RootPosix -> False++dosValid :: FilePath -> Bool+dosValid p = noReserved && validCharacters where reservedChars = map chr [0..0x1F] ++ "/\\?*:|\"<>" reservedNames = [ "AUX", "CLOCK$", "COM1", "COM2", "COM3", "COM4"@@ -308,18 +366,23 @@ , "LPT7", "LPT8", "LPT9", "NUL", "PRN" ] - validRoot = case pathRoot p of- Nothing -> True- Just RootWindowsCurrentVolume -> True- Just (RootWindowsVolume v) -> elem v ['A'..'Z']- _ -> False- noExt = p { pathExtensions = [] } noReserved = flip all (directoryChunks noExt) $ \fn -> notElem (map toUpper fn) reservedNames validCharacters = flip all (directoryChunks p) $ not . any (`elem` reservedChars)++uncValid :: FilePath -> String -> String -> Bool+uncValid _ "" _ = False+uncValid _ _ "" = False+uncValid p host share = ok host && ok share && all ok (dropWhileEnd P.null (directoryChunks p)) where+ ok "" = False+ ok c = not (any invalidChar c)+ invalidChar c = c == '\x00' || c == '\\'++dropWhileEnd :: (a -> Bool) -> [a] -> [a]+dropWhileEnd p = foldr (\x xs -> if p x && P.null xs then [] else x : xs) [] winSplit :: T.Text -> [FilePath] winSplit = map winFromText . filter (not . T.null) . textSplitBy (== ';')
− scripts/common.bash
@@ -1,23 +0,0 @@-PATH="$PATH:$PWD/cabal-dev/bin/"--VERSION=$(awk '/^version:/{print $2}' system-filepath.cabal)--CABAL_DEV=$(which cabal-dev)-XZ=$(which xz)--require_cabal_dev()-{- if [ -z "$CABAL_DEV" ]; then- echo "Can't find 'cabal-dev' executable; make sure it exists on your "'$PATH'- echo "Cowardly refusing to fuck with the global package database"- exit 1- fi-}--clean_dev_install()-{- require_cabal_dev- - rm -rf dist- $CABAL_DEV install || exit 1-}
− scripts/run-benchmarks
@@ -1,21 +0,0 @@-#!/bin/bash-if [ ! -f 'system-filepath.cabal' ]; then- echo -n "Can't find system-filepath.cabal; please run this script as"- echo -n " ./scripts/run-benchmarks from within the system-filepath source"- echo " directory"- exit 1-fi--. scripts/common.bash--require_cabal_dev--rm -rf dist-cabal-dev install || exit 1--pushd benchmarks-rm -rf dist-$CABAL_DEV -s ../cabal-dev install || exit 1-popd--cabal-dev/bin/system-filepath_benchmarks $@
− scripts/run-coverage
@@ -1,21 +0,0 @@-#!/bin/bash-if [ ! -f 'system-filepath.cabal' ]; then- echo -n "Can't find system-filepath.cabal; please run this script as"- echo -n " ./scripts/run-coverage from within the system-filepath source"- echo " directory"- exit 1-fi--. scripts/common.bash--require_cabal_dev--pushd tests-$CABAL_DEV -s ../cabal-dev install --flags="coverage" || exit 1-popd--rm -f system-filepath_tests.tix-cabal-dev/bin/system-filepath_tests $@--hpc markup --srcdir=src --srcdir=tests/ system-filepath_tests.tix --destdir=hpc-markup --exclude=Main-hpc report --srcdir=src --srcdir=tests/ system-filepath_tests.tix --exclude=Main
− scripts/run-tests
@@ -1,17 +0,0 @@-#!/bin/bash-if [ ! -f 'system-filepath.cabal' ]; then- echo -n "Can't find system-filepath.cabal; please run this script as"- echo -n " ./scripts/run-tests from within the system-filepath source"- echo " directory"- exit 1-fi--. scripts/common.bash--require_cabal_dev--pushd tests-$CABAL_DEV -s ../cabal-dev install || exit 1-popd--cabal-dev/bin/system-filepath_tests $@
system-filepath.cabal view
@@ -1,5 +1,5 @@ name: system-filepath-version: 0.4.10+version: 0.4.11 synopsis: High-level, byte-based file and directory path manipulations license: MIT license-file: license.txt@@ -7,21 +7,12 @@ maintainer: John Millikin <jmillikin@gmail.com> copyright: John Millikin 2010-2012 build-type: Custom-cabal-version: >= 1.6+cabal-version: >= 1.8 category: System stability: experimental homepage: https://john-millikin.com/software/haskell-filesystem/ bug-reports: mailto:jmillikin@gmail.com -extra-source-files:- scripts/common.bash- scripts/run-benchmarks- scripts/run-coverage- scripts/run-tests- --- tests/system-filepath-tests.cabal- tests/Tests.hs- source-repository head type: git location: https://john-millikin.com/code/haskell-filesystem/@@ -29,7 +20,7 @@ source-repository this type: git location: https://john-millikin.com/code/haskell-filesystem/- tag: system-filepath_0.4.10+ tag: system-filepath_0.4.11 library ghc-options: -Wall -O2@@ -54,3 +45,20 @@ other-modules: Filesystem.Path.Internal++test-suite filesystem_path_tests+ type: exitcode-stdio-1.0+ main-is: FilesystemPathTests.hs++ ghc-options: -Wall -O2+ cc-options: -Wall+ hs-source-dirs: tests++ build-depends:+ base > 4.0 && < 5.0+ , bytestring+ , chell >= 0.4 && < 0.5+ , chell-quickcheck >= 0.2 && < 0.3+ , QuickCheck+ , system-filepath+ , text
+ tests/FilesystemPathTests.hs view
@@ -0,0 +1,696 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE OverloadedStrings #-}++module Main (tests, main) where++import Prelude hiding (FilePath)++import qualified Data.ByteString.Char8 as B8+import Data.Char (toUpper)+import Data.List (intercalate)+import qualified Data.Text as T+import Test.Chell+import Test.Chell.QuickCheck+import Test.QuickCheck hiding (property)++import qualified Filesystem.Path as P+import Filesystem.Path (FilePath, (</>), relative, stripPrefix, absolute, basename, empty)+import Filesystem.Path.CurrentOS ()+import Filesystem.Path.Rules++main :: IO ()+main = Test.Chell.defaultMain [tests]++tests :: Suite+tests = suite "tests" $+ -- Basic properties+ [ test_Empty+ , test_Root+ , test_Directory+ , test_Parent+ , test_Filename+ , test_Dirname+ , test_Basename+ , test_Absolute+ , test_Relative+ + , test_LeadingDotSpecialCases+ + -- Basic operations+ , test_Append+ , test_CommonPrefix+ , test_StripPrefix+ , property "stripPrefix" prop_StripPrefix+ , test_SplitExtension+ , test_Collapse+ , test_SplitDirectories+ , test_InvalidUtf8InDirectoryComponent+ , test_Utf8CharInGhcEscapeArea+ + , test_SplitSearchPath+ , test_Parsing+ , test_EqualsIgnoresPosixEncoding+ , test_ShowRules+ ] ++ suiteTests suite_EncodeString+ ++ suiteTests suite_DecodeString+ ++ suiteTests suite_SplitSearchPathString+ ++ suiteTests (suite "to-from-bytes"+ [ test_Identity "posix" posix posixPaths+ , test_Identity "windows" windows windowsPaths+ , test_MixedValidityToBytes+ ])+ ++ suiteTests (suite "to-from-text"+ [ test_ToText+ , test_FromText+ ])+ ++ suiteTests (suite "validity"+ [ property "posix" (forAll posixPaths (valid posix))+ , property "windows" (forAll windowsPaths (valid windows))+ , test_UncValidity+ ])++test_Empty :: Test+test_Empty = assertions "empty" $ do+ $expect $ P.null empty+ $expect $ equal (toChar8 empty) ""+ $expect $ equal (toString empty) ""++test_Root :: Test+test_Root = assertions "root" $ do+ let root x = toChar8 (P.root (fromChar8 x))+ + $expect $ equal (root "") ""+ $expect $ equal (root "/") "/"+ $expect $ equal (root "foo") ""+ $expect $ equal (root "/foo") "/"++test_Directory :: Test+test_Directory = assertions "directory" $ do+ let directory x = toChar8 (P.directory (fromChar8 x))+ + $expect $ equal (directory "") "./"+ $expect $ equal (directory "/") "/"+ $expect $ equal (directory "/foo/bar") "/foo/"+ $expect $ equal (directory "/foo/bar/") "/foo/bar/"+ $expect $ equal (directory ".") "./"+ $expect $ equal (directory "..") "../"+ $expect $ equal (directory "../foo") "../"+ $expect $ equal (directory "../foo/") "../foo/"+ $expect $ equal (directory "foo") "./"+ $expect $ equal (directory "foo/bar") "foo/"++test_Parent :: Test+test_Parent = assertions "parent" $ do+ let parent x = toChar8 (P.parent (fromChar8 x))+ + $expect $ equal (parent "") "./"+ $expect $ equal (parent "/") "/"+ $expect $ equal (parent "/foo/bar") "/foo/"+ $expect $ equal (parent "/foo/bar/") "/foo/"+ $expect $ equal (parent ".") "./"+ $expect $ equal (parent "..") "./"+ $expect $ equal (parent "../foo/bar") "../foo/"+ $expect $ equal (parent "../foo/bar") "../foo/"+ $expect $ equal (parent "foo") "./"+ $expect $ equal (parent "foo/bar") "./foo/"++test_Filename :: Test+test_Filename = assertions "filename" $ do+ let filename x = toChar8 (P.filename (fromChar8 x))+ + $expect $ equal (filename "") ""+ $expect $ equal (filename "/") ""+ $expect $ equal (filename "/foo/") ""+ $expect $ equal (filename "/foo/bar") "bar"+ $expect $ equal (filename "/foo/bar.txt") "bar.txt"++test_Dirname :: Test+test_Dirname = assertions "dirname" $ do+ let dirname x = toChar8 (P.dirname (fromChar8 x))+ + $expect $ equal (dirname "") ""+ $expect $ equal (dirname "/") ""+ $expect $ equal (dirname "foo") ""+ $expect $ equal (dirname "foo/bar") "foo"+ $expect $ equal (dirname "foo/bar/") "bar"+ $expect $ equal (dirname "foo/bar/baz.txt") "bar"+ + -- the directory name will be re-parsed to a file name.+ let dirnameExts x = P.extensions (P.dirname (fromChar8 x))+ $expect $ equal (dirnameExts "foo.d/bar") ["d"]+ + -- reparsing preserves good/bad encoding state+ $expect $ equal (dirnameExts "foo.\xB1.\xDD\xAA/bar") ["\xB1", "\x76A"]++test_Basename :: Test+test_Basename = assertions "basename" $ do+ let basename_posix x = toChar8 (basename (fromChar8 x))+ let basename_windows x = toString (basename (fromString x))+ + $expect $ equal (basename_posix "/foo/bar") "bar"+ $expect $ equal (basename_posix "/foo/bar.txt") "bar"+ + $expect $ equal (basename_windows "c:\\foo\\bar") "bar"+ $expect $ equal (basename_windows "c:\\foo\\bar.txt") "bar"++test_Absolute :: Test+test_Absolute = assertions "absolute" $ do+ $expect $ absolute (fromChar8 "/")+ $expect $ absolute (fromChar8 "/foo/bar")+ $expect . not $ absolute (fromChar8 "")+ $expect . not $ absolute (fromChar8 "foo/bar")+ + $expect $ absolute (fromString "c:\\")+ $expect $ absolute (fromString "c:\\foo\\bar")+ $expect . not $ absolute (fromString "")+ $expect . not $ absolute (fromString "foo\\bar")+ $expect . not $ absolute (fromString "\\foo\\bar")++test_Relative :: Test+test_Relative = assertions "relative" $ do+ $expect . not $ relative (fromChar8 "/")+ $expect . not $ relative (fromChar8 "/foo/bar")+ $expect $ relative (fromChar8 "")+ $expect $ relative (fromChar8 "foo/bar")+ + $expect . not $ relative (fromString "c:\\")+ $expect . not $ relative (fromString "c:\\foo\\bar")+ $expect $ relative (fromString "")+ $expect $ relative (fromString "foo\\bar")+ $expect . not $ relative (fromString "\\foo\\bar")++test_LeadingDotSpecialCases :: Test+test_LeadingDotSpecialCases = assertions "leading-dot-special-cases" $ do+ let components_posix x = let p = fromChar8 x in+ (toChar8 (P.directory p), toChar8 (basename p), P.extensions p)+ let components_windows x = let p = fromString x in+ (toString (P.directory p), toString (basename p), P.extensions p)+ + -- The filenames "." and ".." are always considered to be directory+ -- elements, because they are links to either the current or parent+ -- directories.+ --+ -- On POSIX, filenames starting with '.' are hidden files and have+ -- a basename starting with '.'.+ --+ -- On Windows there is no history of similar naming patterns. The case+ -- could be made that a filename like ".txt.gz" ought to have a+ -- basename of "", but different basename behavior in POSIX and Windows+ -- would greatly complicate the implementation of 'dirname'.+ $expect $ equal (components_posix ".") ("./", "", [])+ $expect $ equal (components_posix "..") ("../", "", [])+ $expect $ equal (components_posix "/foo/.") ("/foo/./", "", [])+ $expect $ equal (components_posix "/foo/..") ("/foo/../", "", [])+ $expect $ equal (components_posix "/foo/.foo.txt") ("/foo/", ".foo", ["txt"])+ + $expect $ equal (components_windows ".") (".\\", "", [])+ $expect $ equal (components_windows "..") ("..\\", "", [])+ $expect $ equal (components_windows "\\foo\\.") ("\\foo\\.\\", "", [])+ $expect $ equal (components_windows "\\foo\\..") ("\\foo\\..\\", "", [])+ $expect $ equal (components_windows "\\foo\\.foo.txt") ("\\foo\\", ".foo", ["txt"])++test_Identity :: String -> Rules a -> Gen FilePath -> Test+test_Identity name r gen = property name $ forAll gen $ \p -> p == decode r (encode r p)++test_MixedValidityToBytes :: Test+test_MixedValidityToBytes = assertions "mixed-validity-to-bytes" $ do+ let p = fromChar8+ + $expect $ equal (encode posix (p "\xB1.\xDD\xAA")) (B8.pack "\xB1.\xDD\xAA")+ $expect $ equal (encode posix (p "\xB1.\xDD\xAA" </> p "foo")) (B8.pack "\xB1.\xDD\xAA/foo")++test_ToText :: Test+test_ToText = assertions "toText" $ do+ let p = fromChar8+ + $expect $ equal (toText posix (p "")) (Right (T.pack ""))+ $expect $ equal (toText posix (p "ascii")) (Right (T.pack "ascii"))+ $expect $ equal (toText posix (p "\xF0\x9D\x84\x9E")) (Right (T.pack "\x1D11E"))+ $expect $ equal (toText posix (p "\xED\xA0\x80")) (Left (T.pack "\xED\xA0\x80"))+ $expect $ equal (toText posix (p "\xF0\x9D\x84\x9E/\xED\xA0\x80")) (Left (T.pack "\x1D11E/\xED\xA0\x80"))+ $expect $ equal (toText posix (p "\xED.\xF0\x9D\x84\x9E.\xA0\x80")) (Left (T.pack "\xED.\x1D11E.\xA0\x80"))+ $expect $ equal (toText posix (p "\xB1.\xDD\xAA")) (Left (T.pack "\xB1.\x76A"))+ $expect $ equal (toText posix (p "\xB1.\xDD\xAA" </> p "foo")) (Left (T.pack "\xB1.\x76A/foo"))++test_FromText :: Test+test_FromText = assertions "fromText" $ do+ let pt x = fromText posix (T.pack x)+ let p = fromChar8+ + $expect $ equal (pt "") (p "")+ $expect $ equal (pt "\x1D11E") (p "\xF0\x9D\x84\x9E")+ $expect $ equal (pt "\xED\xA0\x80") (p "\xC3\xAD\xC2\xA0\xC2\x80")++test_Append :: Test+test_Append = assertions "append" $ do+ let appendP x y = toChar8 (P.append (fromChar8 x) (fromChar8 y))+ let appendW x y = toString (P.append (fromString x) (fromString y))+ + $expect $ equal (appendP "" "") ""+ $expect $ equal (appendP "" "b/") "b/"+ + -- Relative to a directory+ $expect $ equal (appendP "a/" "") "a/"+ $expect $ equal (appendP "a/" "b/") "a/b/"+ $expect $ equal (appendP "a/" "b.txt") "a/b.txt"+ $expect $ equal (appendP "a.txt" "b.txt") "a.txt/b.txt"+ $expect $ equal (appendP "." "a") "./a"+ + -- Relative to a file+ $expect $ equal (appendP "a" "") "a/"+ $expect $ equal (appendP "a" "b/") "a/b/"+ $expect $ equal (appendP "a/b" "c") "a/b/c"+ + -- Absolute+ $expect $ equal (appendP "/a/" "") "/a/"+ $expect $ equal (appendP "/a/" "b") "/a/b"+ $expect $ equal (appendP "/a/" "b/") "/a/b/"+ + -- Second parameter is absolute+ $expect $ equal (appendP "/a/" "/") "/"+ $expect $ equal (appendP "/a/" "/b") "/b"+ $expect $ equal (appendP "/a/" "/b/") "/b/"+ + -- Windows: volume handling+ $expect $ equal (appendW "c:\\" "") "C:\\"+ $expect $ equal (appendW "c:\\foo" "bar\\baz") "C:\\foo\\bar\\baz"+ $expect $ equal (appendW "c:\\foo" "d:\\bar") "D:\\bar"+ $expect $ equal (appendW "c:\\foo" "\\bar") "C:\\bar"+ $expect $ equal (appendW "foo\\bar" "\\baz") "\\baz"++test_CommonPrefix :: Test+test_CommonPrefix = assertions "commonPrefix" $ do+ let commonPrefix xs = toChar8 (P.commonPrefix (map (fromChar8) xs))+ + $expect $ equal (commonPrefix ["", ""]) ""+ $expect $ equal (commonPrefix ["/", ""]) ""+ $expect $ equal (commonPrefix ["/", "/"]) "/"+ $expect $ equal (commonPrefix ["foo/", "/foo/"]) ""+ $expect $ equal (commonPrefix ["/foo", "/foo/"]) "/"+ $expect $ equal (commonPrefix ["/foo/", "/foo/"]) "/foo/"+ $expect $ equal (commonPrefix ["/foo/bar/baz.txt.gz", "/foo/bar/baz.txt.gz.bar"]) "/foo/bar/baz.txt.gz"++test_StripPrefix :: Test+test_StripPrefix = assertions "stripPrefix" $ do+ let stripPrefix x y = fmap (toChar8) (P.stripPrefix (fromChar8 x) (fromChar8 y))+ + $expect $ equal (stripPrefix "" "") (Just "")+ $expect $ equal (stripPrefix "" "/") (Just "/")+ $expect $ equal (stripPrefix "/" "/") (Just "")+ $expect $ equal (stripPrefix "/" "/foo") (Just "foo")+ $expect $ equal (stripPrefix "/" "/foo/bar") (Just "foo/bar")+ $expect $ equal (stripPrefix "/foo/" "/foo/bar") (Just "bar")+ $expect $ equal (stripPrefix "/foo/" "/foo/bar/baz") (Just "bar/baz")+ $expect $ equal (stripPrefix "/foo/bar" "/foo/bar.txt") (Just ".txt")+ $expect $ equal (stripPrefix "/foo/bar.txt" "/foo/bar.txt.gz") (Just ".gz")+ + -- Test ignoring non-matching prefixes+ $expect $ equal (stripPrefix "/foo" "/foo/bar") Nothing+ $expect $ equal (stripPrefix "/foo/bar/baz" "/foo") Nothing+ $expect $ equal (stripPrefix "/foo/baz/" "/foo/bar/qux") Nothing+ $expect $ equal (stripPrefix "/foo/bar/baz" "/foo/bar/qux") Nothing+ $expect $ equal (stripPrefix "/foo/bar/baz" "/foo/bar/qux") Nothing++prop_StripPrefix :: Property+prop_StripPrefix =+ forAll posixPaths $ \x ->+ forAll posixPaths $ \suffix ->+ let prefix = x </> "" in+ let full = fromChar8 (toChar8 prefix ++ toChar8 suffix) in+ case stripPrefix prefix full of+ Nothing -> False+ Just stripped -> prefix </> stripped == full++test_SplitExtension :: Test+test_SplitExtension = assertions "splitExtension" $ do+ let splitExtension x = (toChar8 base, ext) where+ (base, ext) = P.splitExtension (fromChar8 x)+ + $expect $ equal (splitExtension "") ("", Nothing)+ $expect $ equal (splitExtension "foo") ("foo", Nothing)+ $expect $ equal (splitExtension "foo.") ("foo", Just (T.pack ""))+ $expect $ equal (splitExtension "foo.a") ("foo", Just (T.pack "a"))+ $expect $ equal (splitExtension "foo.a/") ("foo.a/", Nothing)+ $expect $ equal (splitExtension "foo.a/bar") ("foo.a/bar", Nothing)+ $expect $ equal (splitExtension "foo.a/bar.b") ("foo.a/bar", Just (T.pack "b"))+ $expect $ equal (splitExtension "foo.a/bar.b.c") ("foo.a/bar.b", Just (T.pack "c"))++test_Collapse :: Test+test_Collapse = assertions "collapse" $ do+ let collapse x = toChar8 (P.collapse (fromChar8 x))+ + $expect $ equal (collapse "./") "./"+ $expect $ equal (collapse "././") "./"+ $expect $ equal (collapse "../") "../"+ $expect $ equal (collapse ".././") "../"+ $expect $ equal (collapse "./../") "../"+ $expect $ equal (collapse "../../") "../../"+ $expect $ equal (collapse "parent/foo/baz/../bar") "parent/foo/bar"+ $expect $ equal (collapse "parent/foo/baz/../../bar") "parent/bar"+ $expect $ equal (collapse "parent/foo/..") "parent/"+ $expect $ equal (collapse "/parent/foo/../../../bar") "/bar"+ $expect $ equal (collapse "/./parent/foo") "/parent/foo"++test_SplitDirectories :: Test+test_SplitDirectories = assertions "splitDirectories" $ do+ let splitDirectories x = map toChar8 (P.splitDirectories (fromChar8 x))+ + $expect $ equal (splitDirectories "") []+ $expect $ equal (splitDirectories "/") ["/"]+ $expect $ equal (splitDirectories "/a") ["/", "a"]+ $expect $ equal (splitDirectories "/ab/cd") ["/", "ab", "cd"]+ $expect $ equal (splitDirectories "/ab/cd/") ["/", "ab", "cd"]+ $expect $ equal (splitDirectories "ab/cd") ["ab", "cd"]+ $expect $ equal (splitDirectories "ab/cd/") ["ab", "cd"]+ $expect $ equal (splitDirectories "ab/cd.txt") ["ab", "cd.txt"]+ $expect $ equal (splitDirectories "ab/cd/.txt") ["ab", "cd", ".txt"]+ $expect $ equal (splitDirectories "ab/./cd") ["ab", ".", "cd"]++test_InvalidUtf8InDirectoryComponent :: Test+test_InvalidUtf8InDirectoryComponent = assertions "invalid-utf8-in-directory-component" $ do+ $expect $ equal (toText posix (fromChar8 "/\218\130.\137\141")) (Left (T.pack "/\1666.\137\141"))+ $expect $ equal (encode posix (fromChar8 "/\218\130.\137\141")) (B8.pack "/\218\130.\137\141")+ + $expect $ equal (toText posix (fromChar8 "/\218\130.\137\141/")) (Left (T.pack "/\1666.\137\141/"))+ $expect $ equal (encode posix (fromChar8 "/\218\130.\137\141/")) (B8.pack "/\218\130.\137\141/")+ + $expect $ equal (toText posix (fromChar8 "/\218\130.\137\141//baz")) (Left (T.pack "/\1666.\137\141/baz"))+ $expect $ equal (encode posix (fromChar8 "/\218\130.\137\141//baz")) (B8.pack "/\218\130.\137\141/baz")++test_Utf8CharInGhcEscapeArea :: Test+test_Utf8CharInGhcEscapeArea = assertions "utf8-char-in-ghc-escape-area" $ do+ let chars = "/a/\238\189\178/b"+ let path = fromChar8 chars+ $expect (equal (toChar8 path) chars)+ $expect (equal (toText posix path) (Right (T.pack "/a/\61298/b")))+ + let chars = "/a/\xEE\xBC\x80/b"+ let path = fromChar8 chars+ $expect (equal (toChar8 path) chars)+ $expect (equal (toText posix path) (Right (T.pack "/a/\61184/b")))++test_Parsing :: Test+test_Parsing = assertions "parsing" $ do+ let p x = toChar8 (fromChar8 x)+ let w x = toString (fromString x)+ + $expect $ equal (p "") ""+ $expect $ equal (p "/") "/"+ $expect $ equal (p "/a") "/a"+ $expect $ equal (p "/a/") "/a/"+ $expect $ equal (p "a") "a"+ $expect $ equal (p "a/") "a/"+ $expect $ equal (p "a/b") "a/b"+ $expect $ equal (p "a//b") "a/b"+ $expect $ equal (p "a/./b") "a/./b"+ $expect $ equal (p ".") "./"+ $expect $ equal (p "./") "./"+ $expect $ equal (p "..") "../"+ $expect $ equal (p "../") "../"+ + $expect $ equal (w "") ""+ $expect $ equal (w "c:\\") "C:\\"+ $expect $ equal (w "c:\\a") "C:\\a"+ $expect $ equal (w "c:\\a\\") "C:\\a\\"+ $expect $ equal (w "a") "a"+ $expect $ equal (w "a/") "a\\"+ $expect $ equal (w "a\\") "a\\"+ $expect $ equal (w "a\\b") "a\\b"+ $expect $ equal (w "a\\\\b") "a\\b"+ $expect $ equal (w "a\\.\\b") "a\\.\\b"+ $expect $ equal (w ".") ".\\"+ $expect $ equal (w ".\\") ".\\"+ $expect $ equal (w "..") "..\\"+ $expect $ equal (w "..\\") "..\\"+ + -- extended-length+ $expect $ equal (w "\\\\?\\C:\\") "\\\\?\\C:\\"+ $expect $ equal (w "\\\\?\\C:\\a") "\\\\?\\C:\\a"+ + -- UNC+ $expect $ equal (w "\\\\server\\share") "\\\\server\\share"+ $expect $ equal (w "\\\\server\\share\\") "\\\\server\\share"+ $expect $ equal (w "\\\\server\\share\\a") "\\\\server\\share\\a"+ $expect $ equal (w "\\\\server\\share\\.") "\\\\server\\share\\."+ $expect $ equal (w "\\\\server\\share\\..") "\\\\server\\share\\.."+ $expect $ equal (w "\\\\server\\share\\a\\") "\\\\server\\share\\a"+ + -- extended-length UNC+ $expect $ equal (w "\\\\?\\unc\\server\\share") "\\\\?\\UNC\\server\\share"+ $expect $ equal (w "\\\\?\\UNC\\server\\share") "\\\\?\\UNC\\server\\share"+ $expect $ equal (w "\\\\?\\UNC\\server\\share\\a") "\\\\?\\UNC\\server\\share\\a"+ + -- magical \??\ and \\.\ Windows prefixes+ $expect $ equal (w "\\??\\Volume{12345}") "\\??\\Volume{12345}"+ $expect $ equal (w "\\\\.\\PhysicalDrive0") "\\\\.\\PhysicalDrive0"++test_UncValidity :: Test+test_UncValidity = assertions "unc-validity" $ do+ let invalid rules = not . valid rules+ $expect $ invalid windows (fromString "\\\\server")+ $expect $ invalid windows (fromString "\\\\server\\")+ $expect $ valid windows (fromString "\\\\server\\share")+ $expect $ valid windows (fromString "\\\\server\\share\\")+ $expect $ valid windows (fromString "\\\\server\\share\\a")+ $expect $ valid windows (fromString "\\??\\Volume{12345}")+ $expect $ valid windows (fromString "\\\\.\\PhysicalDrive0")++test_SplitSearchPath :: Test+test_SplitSearchPath = assertions "splitSearchPath" $ do+ let p x = map toChar8 (splitSearchPath posix (B8.pack x))+ let w x = map toString (splitSearchPath windows (T.pack x))+ + $expect $ equal (p "a:b:c") ["a", "b", "c"]+ $expect $ equal (p "a::b:c") ["a", "./", "b", "c"]+ $expect $ equal (w "a;b;c") ["a", "b", "c"]+ $expect $ equal (w "a;;b;c") ["a", "b", "c"]++suite_SplitSearchPathString :: Suite+suite_SplitSearchPathString = suite "splitSearchPathString"+ [ test_SplitSearchPathString_Posix+ , test_SplitSearchPathString_Posix_Ghc702+ , test_SplitSearchPathString_Posix_Ghc704+ , test_SplitSearchPathString_Darwin+ , test_SplitSearchPathString_Darwin_Ghc702+ , test_SplitSearchPathString_Win32+ ]++test_SplitSearchPathString_Posix :: Test+test_SplitSearchPathString_Posix = assertions "posix" $ do+ let split x = map (toText posix) (splitSearchPathString posix x)+ $expect $ equal (split "a::\xC2\xA1\xC2\xA2:\xA1\xA2") [Right "a", Right "./", Right "\xA1\xA2", Left "\xA1\xA2"]++test_SplitSearchPathString_Posix_Ghc702 :: Test+test_SplitSearchPathString_Posix_Ghc702 = assertions "posix_ghc702" $ do+ let split x = map (toText posix) (splitSearchPathString posix_ghc702 x)+ $expect $ equal (split "a::\xA1\xA2:\xEFA1\xEFA2") [Right "a", Right "./", Right "\xA1\xA2", Left "\xA1\xA2"]++test_SplitSearchPathString_Posix_Ghc704 :: Test+test_SplitSearchPathString_Posix_Ghc704 = assertions "posix_ghc704" $ do+ let split x = map (toText posix) (splitSearchPathString posix_ghc704 x)+ $expect $ equal (split "a::\xA1\xA2:\xDCA1\xDCA2") [Right "a", Right "./", Right "\xA1\xA2", Left "\xA1\xA2"]++test_SplitSearchPathString_Darwin :: Test+test_SplitSearchPathString_Darwin = assertions "darwin" $ do+ let split x = map (toText darwin) (splitSearchPathString darwin x)+ $expect $ equal (split "a::\xC2\xA1\xC2\xA2") [Right "a", Right "./", Right "\xA1\xA2"]++test_SplitSearchPathString_Darwin_Ghc702 :: Test+test_SplitSearchPathString_Darwin_Ghc702 = assertions "darwin_ghc702" $ do+ let split x = map (toText darwin) (splitSearchPathString darwin_ghc702 x)+ $expect $ equal (split "a::\xA1\xA2") [Right "a", Right "./", Right "\xA1\xA2"]++test_SplitSearchPathString_Win32 :: Test+test_SplitSearchPathString_Win32 = assertions "win32" $ do+ let split x = map (toText windows) (splitSearchPathString windows x)+ $expect $ equal (split "a;;\xA1\xA2") [Right "a", Right "\xA1\xA2"]++suite_EncodeString :: Suite+suite_EncodeString = suite "encodeString"+ [ test_EncodeString_Posix+ , test_EncodeString_Posix_Ghc702+ , test_EncodeString_Posix_Ghc704+ , test_EncodeString_Win32+ ]++test_EncodeString_Posix :: Test+test_EncodeString_Posix = assertions "posix" $ do+ let enc = encodeString posix+ $expect $ equal (enc (fromChar8 "test")) "test"+ $expect $ equal (enc (fromChar8 "test\xC2\xA1\xC2\xA2")) "test\xC2\xA1\xC2\xA2"+ $expect $ equal (enc (fromChar8 "test\xA1\xA2")) "test\xA1\xA2"+ $expect $ equal (enc (fromChar8 "\xC2\xA1\xC2\xA2/test\xA1\xA2")) "\xC2\xA1\xC2\xA2/test\xA1\xA2"+ $expect $ equal (enc (fromText posix "test\xA1\xA2")) "test\xC2\xA1\xC2\xA2"++test_EncodeString_Posix_Ghc702 :: Test+test_EncodeString_Posix_Ghc702 = assertions "posix_ghc702" $ do+ let enc = encodeString posix_ghc702+ $expect $ equal (enc (fromChar8 "test")) "test"+ $expect $ equal (enc (fromChar8 "test\xA1\xA2")) "test\xEFA1\xEFA2"+ $expect $ equal (enc (fromChar8 "\xC2\xA1\xC2\xA2/test\xA1\xA2")) "\xA1\xA2/test\xEFA1\xEFA2"+ $expect $ equal (enc (fromText posix_ghc702 "test\xA1\xA2")) "test\xA1\xA2"++test_EncodeString_Posix_Ghc704 :: Test+test_EncodeString_Posix_Ghc704 = assertions "posix_ghc704" $ do+ let enc = encodeString posix_ghc704+ $expect $ equal (enc (fromChar8 "test")) "test"+ $expect $ equal (enc (fromChar8 "test\xA1\xA2")) "test\xDCA1\xDCA2"+ $expect $ equal (enc (fromChar8 "\xC2\xA1\xC2\xA2/test\xA1\xA2")) "\xA1\xA2/test\xDCA1\xDCA2"+ $expect $ equal (enc (fromText posix_ghc704 "test\xA1\xA2")) "test\xA1\xA2"++test_EncodeString_Win32 :: Test+test_EncodeString_Win32 = assertions "windows" $ do+ let enc = encodeString windows+ $expect $ equal (enc (fromString "test")) "test"+ $expect $ equal (enc (fromString "test\xA1\xA2")) "test\xA1\xA2"+ $expect $ equal (enc (fromText windows "test\xA1\xA2")) "test\xA1\xA2"++suite_DecodeString :: Suite+suite_DecodeString = suite "decodeString"+ [ test_DecodeString_Posix+ , test_DecodeString_Posix_Ghc702+ , test_DecodeString_Posix_Ghc704+ , test_DecodeString_Darwin+ , test_DecodeString_Darwin_Ghc702+ , test_DecodeString_Win32+ ]++test_DecodeString_Posix :: Test+test_DecodeString_Posix = assertions "posix" $ do+ let r = posix+ let dec = decodeString+ $expect $ equal (dec r "test") (fromText r "test")+ $expect $ equal (dec r "test\xC2\xA1\xC2\xA2") (fromText r "test\xA1\xA2")+ $expect $ equal (dec r "test\xA1\xA2") (fromText r "test\xA1\xA2")++test_DecodeString_Posix_Ghc702 :: Test+test_DecodeString_Posix_Ghc702 = assertions "posix_ghc702" $ do+ let r = posix_ghc702+ let dec = decodeString+ $expect $ equal (dec r "test") (fromText r "test")+ $expect $ equal (dec r "test\xC2\xA1\xC2\xA2") (fromText r "test\xC2\xA1\xC2\xA2")+ $expect $ equal (dec r "test\xA1\xA2") (fromText r "test\xA1\xA2")+ $expect $ equal (dec r "test\xEFA1\xEFA2") (fromChar8 "test\xA1\xA2")+ $expect $ equal+ (toText r (dec r "test\xEFA1\xEFA2"))+ (Left "test\xA1\xA2")++test_DecodeString_Posix_Ghc704 :: Test+test_DecodeString_Posix_Ghc704 = assertions "posix_ghc704" $ do+ let r = posix_ghc704+ let dec = decodeString+ $expect $ equal (dec r "test") (fromText r "test")+ $expect $ equal (dec r "test\xC2\xA1\xC2\xA2") (fromText r "test\xC2\xA1\xC2\xA2")+ $expect $ equal (dec r "test\xA1\xA2") (fromText r "test\xA1\xA2")+ $expect $ equal (dec r "test\xDCA1\xDCA2") (fromChar8 "test\xA1\xA2")+ $expect $ equal+ (toText r (dec r "test\xDCA1\xDCA2"))+ (Left "test\xA1\xA2")++test_DecodeString_Darwin :: Test+test_DecodeString_Darwin = assertions "darwin" $ do+ let r = darwin+ let dec = decodeString+ $expect $ equal (dec r "test\xC2\xA1\xC2\xA2") (fromText r "test\xA1\xA2")++test_DecodeString_Darwin_Ghc702 :: Test+test_DecodeString_Darwin_Ghc702 = assertions "darwin_ghc702" $ do+ let r = darwin_ghc702+ let dec = decodeString+ $expect $ equal (dec r "test\xC2\xA1\xC2\xA2") (fromText r "test\xC2\xA1\xC2\xA2")+ $expect $ equal (dec r "test\xA1\xA2") (fromText r "test\xA1\xA2")++test_DecodeString_Win32 :: Test+test_DecodeString_Win32 = assertions "windows" $ do+ let r = windows+ let dec = decodeString+ $expect $ equal (dec r "test") (fromText r "test")+ $expect $ equal (dec r "test\xC2\xA1\xC2\xA2") (fromText r "test\xC2\xA1\xC2\xA2")+ $expect $ equal (dec r "test\xA1\xA2") (fromText r "test\xA1\xA2")++test_EqualsIgnoresPosixEncoding :: Test+test_EqualsIgnoresPosixEncoding = assertions "equals-ignores-posix-encoding" $ do+ $expect $ equal+ (fromChar8 "test\xA1\xA2")+ (fromText posix "test\xA1\xA2")++test_ShowRules :: Test+test_ShowRules = assertions "show-rules" $ do+ $expect $ equal (showsPrec 11 darwin "") "(Rules \"Darwin\")"+ $expect $ equal (showsPrec 11 darwin_ghc702 "") "(Rules \"Darwin (GHC 7.2)\")"+ $expect $ equal (showsPrec 11 posix "") "(Rules \"POSIX\")"+ $expect $ equal (showsPrec 11 posix_ghc702 "") "(Rules \"POSIX (GHC 7.2)\")"+ $expect $ equal (showsPrec 11 windows "") "(Rules \"Windows\")"++posixPaths :: Gen FilePath+posixPaths = sized $ fmap merge . genComponents where+ merge = fromChar8 . intercalate "/"+ validChar c = not $ elem c ['\x00', '/']+ component = do+ size <- choose (0, 10)+ vectorOf size $ arbitrary `suchThat` validChar+ genComponents n = do+ cs <- vectorOf n component+ frequency [(1, return cs), (9, return ([""] ++ cs))]++windowsPaths :: Gen FilePath+windowsPaths = oneof [dosPaths, uncPaths]++dosPaths :: Gen FilePath+dosPaths = sized $ \n -> genComponents n >>= merge where+ merge cs = do+ root <- genRoot+ let path = intercalate "\\" cs+ return $ fromString $ root ++ path+ + reserved = ['\x00'..'\x1F'] ++ ['/', '\\', '?', '*', ':', '|', '"', '<', '>']+ reservedNames =+ [ "AUX", "CLOCK$", "COM1", "COM2", "COM3", "COM4"+ , "COM5", "COM6", "COM7", "COM8", "COM9", "CON"+ , "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6"+ , "LPT7", "LPT8", "LPT9", "NUL", "PRN"+ ]+ validChar c = not (elem c reserved)+ validComponent c = not (elem (map toUpper c) reservedNames)+ component = do+ size <- choose (1, 10)+ vectorOf size $ arbitrary `suchThat` validChar+ genComponents n = vectorOf n (component `suchThat` validComponent)+ + genRoot = do+ let upperChar = elements ['A'..'Z']+ label <- frequency [(1, return Nothing), (9, fmap Just upperChar)]+ return $ case label of+ Just c -> [c, ':', '\\']+ Nothing -> "\\"++uncPaths :: Gen FilePath+uncPaths = sized $ \n -> genComponents n >>= merge where+ merge cs = do+ root <- genRoot+ let path = intercalate "\\" cs+ return $ case cs of+ [] -> fromString (root ++ path)+ _ -> fromString (root ++ "\\" ++ path)+ validChar c = c /= '\x00' && c /= '\\'+ component = do+ size <- choose (1, 10)+ vectorOf size (arbitrary `suchThat` validChar)+ genComponents n = vectorOf n component+ + genRoot = do+ host <- component+ share <- component+ return ("\\\\" ++ host ++ "\\" ++ share)++toChar8 :: FilePath -> String+toChar8 = B8.unpack . encode posix++fromChar8 :: String -> FilePath+fromChar8 = decode posix . B8.pack++toString :: FilePath -> String+toString = T.unpack . encode windows++fromString :: String -> FilePath+fromString = decode windows . T.pack
− tests/Tests.hs
@@ -1,642 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE OverloadedStrings #-}--module Main (tests, main) where--import Prelude hiding (FilePath)--import qualified Data.ByteString.Char8 as B8-import Data.Char (toUpper)-import Data.List (intercalate)-import qualified Data.Text as T-import Test.Chell-import Test.Chell.QuickCheck-import Test.QuickCheck hiding (property)--import Filesystem.Path as P-import Filesystem.Path.CurrentOS ()-import Filesystem.Path.Rules--main :: IO ()-main = Test.Chell.defaultMain [tests]--tests :: Suite-tests = suite "tests"- -- Basic properties- test_Empty- test_Root- test_Directory- test_Parent- test_Filename- test_Dirname- test_Basename- test_Absolute- test_Relative- - test_LeadingDotSpecialCases- - -- Basic operations- test_Append- test_CommonPrefix- test_StripPrefix- (property "stripPrefix" prop_StripPrefix)- test_SplitExtension- test_Collapse- test_SplitDirectories- test_InvalidUtf8InDirectoryComponent- test_Utf8CharInGhcEscapeArea- - (suite "to-from-bytes"- (test_Identity "posix" posix posixPaths)- (test_Identity "windows" windows windowsPaths)- test_MixedValidityToBytes- :: Suite)- - (suite "to-from-text"- test_ToText- test_FromText- :: Suite)- - (suite "validity"- (property "posix" (forAll posixPaths (valid posix)))- (property "windows" (forAll windowsPaths (valid windows)))- :: Suite)- - test_SplitSearchPath- test_SplitSearchPathString- test_Parsing- test_EncodeString- test_DecodeString- test_EqualsIgnoresPosixEncoding- test_ShowRules--test_Empty :: Test-test_Empty = assertions "empty" $ do- $expect $ P.null empty- $expect $ equal (toChar8 empty) ""- $expect $ equal (toString empty) ""--test_Root :: Test-test_Root = assertions "root" $ do- let root x = toChar8 (P.root (fromChar8 x))- - $expect $ equal (root "") ""- $expect $ equal (root "/") "/"- $expect $ equal (root "foo") ""- $expect $ equal (root "/foo") "/"--test_Directory :: Test-test_Directory = assertions "directory" $ do- let directory x = toChar8 (P.directory (fromChar8 x))- - $expect $ equal (directory "") "./"- $expect $ equal (directory "/") "/"- $expect $ equal (directory "/foo/bar") "/foo/"- $expect $ equal (directory "/foo/bar/") "/foo/bar/"- $expect $ equal (directory ".") "./"- $expect $ equal (directory "..") "../"- $expect $ equal (directory "../foo") "../"- $expect $ equal (directory "../foo/") "../foo/"- $expect $ equal (directory "foo") "./"- $expect $ equal (directory "foo/bar") "foo/"--test_Parent :: Test-test_Parent = assertions "parent" $ do- let parent x = toChar8 (P.parent (fromChar8 x))- - $expect $ equal (parent "") "./"- $expect $ equal (parent "/") "/"- $expect $ equal (parent "/foo/bar") "/foo/"- $expect $ equal (parent "/foo/bar/") "/foo/"- $expect $ equal (parent ".") "./"- $expect $ equal (parent "..") "./"- $expect $ equal (parent "../foo/bar") "../foo/"- $expect $ equal (parent "../foo/bar") "../foo/"- $expect $ equal (parent "foo") "./"- $expect $ equal (parent "foo/bar") "./foo/"--test_Filename :: Test-test_Filename = assertions "filename" $ do- let filename x = toChar8 (P.filename (fromChar8 x))- - $expect $ equal (filename "") ""- $expect $ equal (filename "/") ""- $expect $ equal (filename "/foo/") ""- $expect $ equal (filename "/foo/bar") "bar"- $expect $ equal (filename "/foo/bar.txt") "bar.txt"--test_Dirname :: Test-test_Dirname = assertions "dirname" $ do- let dirname x = toChar8 (P.dirname (fromChar8 x))- - $expect $ equal (dirname "") ""- $expect $ equal (dirname "/") ""- $expect $ equal (dirname "foo") ""- $expect $ equal (dirname "foo/bar") "foo"- $expect $ equal (dirname "foo/bar/") "bar"- $expect $ equal (dirname "foo/bar/baz.txt") "bar"- - -- the directory name will be re-parsed to a file name.- let dirnameExts x = P.extensions (P.dirname (fromChar8 x))- $expect $ equal (dirnameExts "foo.d/bar") ["d"]- - -- reparsing preserves good/bad encoding state- $expect $ equal (dirnameExts "foo.\xB1.\xDD\xAA/bar") ["\xB1", "\x76A"]--test_Basename :: Test-test_Basename = assertions "basename" $ do- let basename_posix x = toChar8 (basename (fromChar8 x))- let basename_windows x = toString (basename (fromString x))- - $expect $ equal (basename_posix "/foo/bar") "bar"- $expect $ equal (basename_posix "/foo/bar.txt") "bar"- - $expect $ equal (basename_windows "c:\\foo\\bar") "bar"- $expect $ equal (basename_windows "c:\\foo\\bar.txt") "bar"--test_Absolute :: Test-test_Absolute = assertions "absolute" $ do- $expect $ absolute (fromChar8 "/")- $expect $ absolute (fromChar8 "/foo/bar")- $expect . not $ absolute (fromChar8 "")- $expect . not $ absolute (fromChar8 "foo/bar")- - $expect $ absolute (fromString "c:\\")- $expect $ absolute (fromString "c:\\foo\\bar")- $expect . not $ absolute (fromString "")- $expect . not $ absolute (fromString "foo\\bar")- $expect . not $ absolute (fromString "\\foo\\bar")--test_Relative :: Test-test_Relative = assertions "relative" $ do- $expect . not $ relative (fromChar8 "/")- $expect . not $ relative (fromChar8 "/foo/bar")- $expect $ relative (fromChar8 "")- $expect $ relative (fromChar8 "foo/bar")- - $expect . not $ relative (fromString "c:\\")- $expect . not $ relative (fromString "c:\\foo\\bar")- $expect $ relative (fromString "")- $expect $ relative (fromString "foo\\bar")- $expect . not $ relative (fromString "\\foo\\bar")--test_LeadingDotSpecialCases :: Test-test_LeadingDotSpecialCases = assertions "leading-dot-special-cases" $ do- let components_posix x = let p = fromChar8 x in- (toChar8 (P.directory p), toChar8 (basename p), P.extensions p)- let components_windows x = let p = fromString x in- (toString (P.directory p), toString (basename p), P.extensions p)- - -- The filenames "." and ".." are always considered to be directory- -- elements, because they are links to either the current or parent- -- directories.- --- -- On POSIX, filenames starting with '.' are hidden files and have- -- a basename starting with '.'.- --- -- On Windows there is no history of similar naming patterns. The case- -- could be made that a filename like ".txt.gz" ought to have a- -- basename of "", but different basename behavior in POSIX and Windows- -- would greatly complicate the implementation of 'dirname'.- $expect $ equal (components_posix ".") ("./", "", [])- $expect $ equal (components_posix "..") ("../", "", [])- $expect $ equal (components_posix "/foo/.") ("/foo/./", "", [])- $expect $ equal (components_posix "/foo/..") ("/foo/../", "", [])- $expect $ equal (components_posix "/foo/.foo.txt") ("/foo/", ".foo", ["txt"])- - $expect $ equal (components_windows ".") (".\\", "", [])- $expect $ equal (components_windows "..") ("..\\", "", [])- $expect $ equal (components_windows "\\foo\\.") ("\\foo\\.\\", "", [])- $expect $ equal (components_windows "\\foo\\..") ("\\foo\\..\\", "", [])- $expect $ equal (components_windows "\\foo\\.foo.txt") ("\\foo\\", ".foo", ["txt"])--test_Identity :: String -> Rules a -> Gen FilePath -> Test-test_Identity name r gen = property name $ forAll gen $ \p -> p == decode r (encode r p)--test_MixedValidityToBytes :: Test-test_MixedValidityToBytes = assertions "mixed-validity-to-bytes" $ do- let p = fromChar8- - $expect $ equal (encode posix (p "\xB1.\xDD\xAA")) (B8.pack "\xB1.\xDD\xAA")- $expect $ equal (encode posix (p "\xB1.\xDD\xAA" </> p "foo")) (B8.pack "\xB1.\xDD\xAA/foo")--test_ToText :: Test-test_ToText = assertions "toText" $ do- let p = fromChar8- - $expect $ equal (toText posix (p "")) (Right (T.pack ""))- $expect $ equal (toText posix (p "ascii")) (Right (T.pack "ascii"))- $expect $ equal (toText posix (p "\xF0\x9D\x84\x9E")) (Right (T.pack "\x1D11E"))- $expect $ equal (toText posix (p "\xED\xA0\x80")) (Left (T.pack "\xED\xA0\x80"))- $expect $ equal (toText posix (p "\xF0\x9D\x84\x9E/\xED\xA0\x80")) (Left (T.pack "\x1D11E/\xED\xA0\x80"))- $expect $ equal (toText posix (p "\xED.\xF0\x9D\x84\x9E.\xA0\x80")) (Left (T.pack "\xED.\x1D11E.\xA0\x80"))- $expect $ equal (toText posix (p "\xB1.\xDD\xAA")) (Left (T.pack "\xB1.\x76A"))- $expect $ equal (toText posix (p "\xB1.\xDD\xAA" </> p "foo")) (Left (T.pack "\xB1.\x76A/foo"))--test_FromText :: Test-test_FromText = assertions "fromText" $ do- let pt x = fromText posix (T.pack x)- let p = fromChar8- - $expect $ equal (pt "") (p "")- $expect $ equal (pt "\x1D11E") (p "\xF0\x9D\x84\x9E")- $expect $ equal (pt "\xED\xA0\x80") (p "\xC3\xAD\xC2\xA0\xC2\x80")--test_Append :: Test-test_Append = assertions "append" $ do- let appendP x y = toChar8 (P.append (fromChar8 x) (fromChar8 y))- let appendW x y = toString (P.append (fromString x) (fromString y))- - $expect $ equal (appendP "" "") ""- $expect $ equal (appendP "" "b/") "b/"- - -- Relative to a directory- $expect $ equal (appendP "a/" "") "a/"- $expect $ equal (appendP "a/" "b/") "a/b/"- $expect $ equal (appendP "a/" "b.txt") "a/b.txt"- $expect $ equal (appendP "a.txt" "b.txt") "a.txt/b.txt"- $expect $ equal (appendP "." "a") "./a"- - -- Relative to a file- $expect $ equal (appendP "a" "") "a/"- $expect $ equal (appendP "a" "b/") "a/b/"- $expect $ equal (appendP "a/b" "c") "a/b/c"- - -- Absolute- $expect $ equal (appendP "/a/" "") "/a/"- $expect $ equal (appendP "/a/" "b") "/a/b"- $expect $ equal (appendP "/a/" "b/") "/a/b/"- - -- Second parameter is absolute- $expect $ equal (appendP "/a/" "/") "/"- $expect $ equal (appendP "/a/" "/b") "/b"- $expect $ equal (appendP "/a/" "/b/") "/b/"- - -- Windows: volume handling- $expect $ equal (appendW "c:\\" "") "C:\\"- $expect $ equal (appendW "c:\\foo" "bar\\baz") "C:\\foo\\bar\\baz"- $expect $ equal (appendW "c:\\foo" "d:\\bar") "D:\\bar"- $expect $ equal (appendW "c:\\foo" "\\bar") "C:\\bar"- $expect $ equal (appendW "foo\\bar" "\\baz") "\\baz"--test_CommonPrefix :: Test-test_CommonPrefix = assertions "commonPrefix" $ do- let commonPrefix xs = toChar8 (P.commonPrefix (map (fromChar8) xs))- - $expect $ equal (commonPrefix ["", ""]) ""- $expect $ equal (commonPrefix ["/", ""]) ""- $expect $ equal (commonPrefix ["/", "/"]) "/"- $expect $ equal (commonPrefix ["foo/", "/foo/"]) ""- $expect $ equal (commonPrefix ["/foo", "/foo/"]) "/"- $expect $ equal (commonPrefix ["/foo/", "/foo/"]) "/foo/"- $expect $ equal (commonPrefix ["/foo/bar/baz.txt.gz", "/foo/bar/baz.txt.gz.bar"]) "/foo/bar/baz.txt.gz"--test_StripPrefix :: Test-test_StripPrefix = assertions "stripPrefix" $ do- let stripPrefix x y = fmap (toChar8) (P.stripPrefix (fromChar8 x) (fromChar8 y))- - $expect $ equal (stripPrefix "" "") (Just "")- $expect $ equal (stripPrefix "" "/") (Just "/")- $expect $ equal (stripPrefix "/" "/") (Just "")- $expect $ equal (stripPrefix "/" "/foo") (Just "foo")- $expect $ equal (stripPrefix "/" "/foo/bar") (Just "foo/bar")- $expect $ equal (stripPrefix "/foo/" "/foo/bar") (Just "bar")- $expect $ equal (stripPrefix "/foo/" "/foo/bar/baz") (Just "bar/baz")- $expect $ equal (stripPrefix "/foo/bar" "/foo/bar.txt") (Just ".txt")- $expect $ equal (stripPrefix "/foo/bar.txt" "/foo/bar.txt.gz") (Just ".gz")- - -- Test ignoring non-matching prefixes- $expect $ equal (stripPrefix "/foo" "/foo/bar") Nothing- $expect $ equal (stripPrefix "/foo/bar/baz" "/foo") Nothing- $expect $ equal (stripPrefix "/foo/baz/" "/foo/bar/qux") Nothing- $expect $ equal (stripPrefix "/foo/bar/baz" "/foo/bar/qux") Nothing- $expect $ equal (stripPrefix "/foo/bar/baz" "/foo/bar/qux") Nothing--prop_StripPrefix :: Property-prop_StripPrefix =- forAll posixPaths $ \x ->- forAll posixPaths $ \suffix ->- let prefix = x </> "" in- let full = fromChar8 (toChar8 prefix ++ toChar8 suffix) in- case stripPrefix prefix full of- Nothing -> False- Just stripped -> prefix </> stripped == full--test_SplitExtension :: Test-test_SplitExtension = assertions "splitExtension" $ do- let splitExtension x = (toChar8 base, ext) where- (base, ext) = P.splitExtension (fromChar8 x)- - $expect $ equal (splitExtension "") ("", Nothing)- $expect $ equal (splitExtension "foo") ("foo", Nothing)- $expect $ equal (splitExtension "foo.") ("foo", Just (T.pack ""))- $expect $ equal (splitExtension "foo.a") ("foo", Just (T.pack "a"))- $expect $ equal (splitExtension "foo.a/") ("foo.a/", Nothing)- $expect $ equal (splitExtension "foo.a/bar") ("foo.a/bar", Nothing)- $expect $ equal (splitExtension "foo.a/bar.b") ("foo.a/bar", Just (T.pack "b"))- $expect $ equal (splitExtension "foo.a/bar.b.c") ("foo.a/bar.b", Just (T.pack "c"))--test_Collapse :: Test-test_Collapse = assertions "collapse" $ do- let collapse x = toChar8 (P.collapse (fromChar8 x))- - $expect $ equal (collapse "./") "./"- $expect $ equal (collapse "././") "./"- $expect $ equal (collapse "../") "../"- $expect $ equal (collapse ".././") "../"- $expect $ equal (collapse "./../") "../"- $expect $ equal (collapse "../../") "../../"- $expect $ equal (collapse "parent/foo/baz/../bar") "parent/foo/bar"- $expect $ equal (collapse "parent/foo/baz/../../bar") "parent/bar"- $expect $ equal (collapse "parent/foo/..") "parent/"- $expect $ equal (collapse "/parent/foo/../../../bar") "/bar"- $expect $ equal (collapse "/./parent/foo") "/parent/foo"--test_SplitDirectories :: Test-test_SplitDirectories = assertions "splitDirectories" $ do- let splitDirectories x = map toChar8 (P.splitDirectories (fromChar8 x))- - $expect $ equal (splitDirectories "") []- $expect $ equal (splitDirectories "/") ["/"]- $expect $ equal (splitDirectories "/a") ["/", "a"]- $expect $ equal (splitDirectories "/ab/cd") ["/", "ab", "cd"]- $expect $ equal (splitDirectories "/ab/cd/") ["/", "ab", "cd"]- $expect $ equal (splitDirectories "ab/cd") ["ab", "cd"]- $expect $ equal (splitDirectories "ab/cd/") ["ab", "cd"]- $expect $ equal (splitDirectories "ab/cd.txt") ["ab", "cd.txt"]- $expect $ equal (splitDirectories "ab/cd/.txt") ["ab", "cd", ".txt"]- $expect $ equal (splitDirectories "ab/./cd") ["ab", ".", "cd"]--test_InvalidUtf8InDirectoryComponent :: Test-test_InvalidUtf8InDirectoryComponent = assertions "invalid-utf8-in-directory-component" $ do- $expect $ equal (toText posix (fromChar8 "/\218\130.\137\141")) (Left (T.pack "/\1666.\137\141"))- $expect $ equal (encode posix (fromChar8 "/\218\130.\137\141")) (B8.pack "/\218\130.\137\141")- - $expect $ equal (toText posix (fromChar8 "/\218\130.\137\141/")) (Left (T.pack "/\1666.\137\141/"))- $expect $ equal (encode posix (fromChar8 "/\218\130.\137\141/")) (B8.pack "/\218\130.\137\141/")- - $expect $ equal (toText posix (fromChar8 "/\218\130.\137\141//baz")) (Left (T.pack "/\1666.\137\141/baz"))- $expect $ equal (encode posix (fromChar8 "/\218\130.\137\141//baz")) (B8.pack "/\218\130.\137\141/baz")--test_Utf8CharInGhcEscapeArea :: Test-test_Utf8CharInGhcEscapeArea = assertions "utf8-char-in-ghc-escape-area" $ do- let chars = "/a/\238\189\178/b"- let path = fromChar8 chars- $expect (equal (toChar8 path) chars)- $expect (equal (toText posix path) (Right (T.pack "/a/\61298/b")))- - let chars = "/a/\xEE\xBC\x80/b"- let path = fromChar8 chars- $expect (equal (toChar8 path) chars)- $expect (equal (toText posix path) (Right (T.pack "/a/\61184/b")))--test_Parsing :: Test-test_Parsing = assertions "parsing" $ do- let p x = toChar8 (fromChar8 x)- let w x = toString (fromString x)- - $expect $ equal (p "") ""- $expect $ equal (p "/") "/"- $expect $ equal (p "/a") "/a"- $expect $ equal (p "/a/") "/a/"- $expect $ equal (p "a") "a"- $expect $ equal (p "a/") "a/"- $expect $ equal (p "a/b") "a/b"- $expect $ equal (p "a//b") "a/b"- $expect $ equal (p "a/./b") "a/./b"- $expect $ equal (p ".") "./"- $expect $ equal (p "./") "./"- $expect $ equal (p "..") "../"- $expect $ equal (p "../") "../"- - $expect $ equal (w "") ""- $expect $ equal (w "c:\\") "C:\\"- $expect $ equal (w "c:\\a") "C:\\a"- $expect $ equal (w "c:\\a\\") "C:\\a\\"- $expect $ equal (w "a") "a"- $expect $ equal (w "a/") "a\\"- $expect $ equal (w "a\\") "a\\"- $expect $ equal (w "a\\b") "a\\b"- $expect $ equal (w "a\\\\b") "a\\b"- $expect $ equal (w "a\\.\\b") "a\\.\\b"- $expect $ equal (w ".") ".\\"- $expect $ equal (w ".\\") ".\\"- $expect $ equal (w "..") "..\\"- $expect $ equal (w "..\\") "..\\"--test_SplitSearchPath :: Test-test_SplitSearchPath = assertions "splitSearchPath" $ do- let p x = map toChar8 (splitSearchPath posix (B8.pack x))- let w x = map toString (splitSearchPath windows (T.pack x))- - $expect $ equal (p "a:b:c") ["a", "b", "c"]- $expect $ equal (p "a::b:c") ["a", "./", "b", "c"]- $expect $ equal (w "a;b;c") ["a", "b", "c"]- $expect $ equal (w "a;;b;c") ["a", "b", "c"]--test_SplitSearchPathString :: Suite-test_SplitSearchPathString = suite "splitSearchPathString"- test_SplitSearchPathString_Posix- test_SplitSearchPathString_Posix_Ghc702- test_SplitSearchPathString_Posix_Ghc704- test_SplitSearchPathString_Darwin- test_SplitSearchPathString_Darwin_Ghc702- test_SplitSearchPathString_Win32--test_SplitSearchPathString_Posix :: Test-test_SplitSearchPathString_Posix = assertions "posix" $ do- let split x = map (toText posix) (splitSearchPathString posix x)- $expect $ equal (split "a::\xC2\xA1\xC2\xA2:\xA1\xA2") [Right "a", Right "./", Right "\xA1\xA2", Left "\xA1\xA2"]--test_SplitSearchPathString_Posix_Ghc702 :: Test-test_SplitSearchPathString_Posix_Ghc702 = assertions "posix_ghc702" $ do- let split x = map (toText posix) (splitSearchPathString posix_ghc702 x)- $expect $ equal (split "a::\xA1\xA2:\xEFA1\xEFA2") [Right "a", Right "./", Right "\xA1\xA2", Left "\xA1\xA2"]--test_SplitSearchPathString_Posix_Ghc704 :: Test-test_SplitSearchPathString_Posix_Ghc704 = assertions "posix_ghc704" $ do- let split x = map (toText posix) (splitSearchPathString posix_ghc704 x)- $expect $ equal (split "a::\xA1\xA2:\xDCA1\xDCA2") [Right "a", Right "./", Right "\xA1\xA2", Left "\xA1\xA2"]--test_SplitSearchPathString_Darwin :: Test-test_SplitSearchPathString_Darwin = assertions "darwin" $ do- let split x = map (toText darwin) (splitSearchPathString darwin x)- $expect $ equal (split "a::\xC2\xA1\xC2\xA2") [Right "a", Right "./", Right "\xA1\xA2"]--test_SplitSearchPathString_Darwin_Ghc702 :: Test-test_SplitSearchPathString_Darwin_Ghc702 = assertions "darwin_ghc702" $ do- let split x = map (toText darwin) (splitSearchPathString darwin_ghc702 x)- $expect $ equal (split "a::\xA1\xA2") [Right "a", Right "./", Right "\xA1\xA2"]--test_SplitSearchPathString_Win32 :: Test-test_SplitSearchPathString_Win32 = assertions "win32" $ do- let split x = map (toText windows) (splitSearchPathString windows x)- $expect $ equal (split "a;;\xA1\xA2") [Right "a", Right "\xA1\xA2"]--test_EncodeString :: Suite-test_EncodeString = suite "encodeString"- test_EncodeString_Posix- test_EncodeString_Posix_Ghc702- test_EncodeString_Posix_Ghc704- test_EncodeString_Win32--test_EncodeString_Posix :: Test-test_EncodeString_Posix = assertions "posix" $ do- let enc = encodeString posix- $expect $ equal (enc (fromChar8 "test")) "test"- $expect $ equal (enc (fromChar8 "test\xC2\xA1\xC2\xA2")) "test\xC2\xA1\xC2\xA2"- $expect $ equal (enc (fromChar8 "test\xA1\xA2")) "test\xA1\xA2"- $expect $ equal (enc (fromChar8 "\xC2\xA1\xC2\xA2/test\xA1\xA2")) "\xC2\xA1\xC2\xA2/test\xA1\xA2"- $expect $ equal (enc (fromText posix "test\xA1\xA2")) "test\xC2\xA1\xC2\xA2"--test_EncodeString_Posix_Ghc702 :: Test-test_EncodeString_Posix_Ghc702 = assertions "posix_ghc702" $ do- let enc = encodeString posix_ghc702- $expect $ equal (enc (fromChar8 "test")) "test"- $expect $ equal (enc (fromChar8 "test\xA1\xA2")) "test\xEFA1\xEFA2"- $expect $ equal (enc (fromChar8 "\xC2\xA1\xC2\xA2/test\xA1\xA2")) "\xA1\xA2/test\xEFA1\xEFA2"- $expect $ equal (enc (fromText posix_ghc702 "test\xA1\xA2")) "test\xA1\xA2"--test_EncodeString_Posix_Ghc704 :: Test-test_EncodeString_Posix_Ghc704 = assertions "posix_ghc704" $ do- let enc = encodeString posix_ghc704- $expect $ equal (enc (fromChar8 "test")) "test"- $expect $ equal (enc (fromChar8 "test\xA1\xA2")) "test\xDCA1\xDCA2"- $expect $ equal (enc (fromChar8 "\xC2\xA1\xC2\xA2/test\xA1\xA2")) "\xA1\xA2/test\xDCA1\xDCA2"- $expect $ equal (enc (fromText posix_ghc704 "test\xA1\xA2")) "test\xA1\xA2"--test_EncodeString_Win32 :: Test-test_EncodeString_Win32 = assertions "windows" $ do- let enc = encodeString windows- $expect $ equal (enc (fromString "test")) "test"- $expect $ equal (enc (fromString "test\xA1\xA2")) "test\xA1\xA2"- $expect $ equal (enc (fromText windows "test\xA1\xA2")) "test\xA1\xA2"--test_DecodeString :: Suite-test_DecodeString = suite "decodeString"- test_DecodeString_Posix- test_DecodeString_Posix_Ghc702- test_DecodeString_Posix_Ghc704- test_DecodeString_Darwin- test_DecodeString_Darwin_Ghc702- test_DecodeString_Win32--test_DecodeString_Posix :: Test-test_DecodeString_Posix = assertions "posix" $ do- let r = posix- let dec = decodeString- $expect $ equal (dec r "test") (fromText r "test")- $expect $ equal (dec r "test\xC2\xA1\xC2\xA2") (fromText r "test\xA1\xA2")- $expect $ equal (dec r "test\xA1\xA2") (fromText r "test\xA1\xA2")--test_DecodeString_Posix_Ghc702 :: Test-test_DecodeString_Posix_Ghc702 = assertions "posix_ghc702" $ do- let r = posix_ghc702- let dec = decodeString- $expect $ equal (dec r "test") (fromText r "test")- $expect $ equal (dec r "test\xC2\xA1\xC2\xA2") (fromText r "test\xC2\xA1\xC2\xA2")- $expect $ equal (dec r "test\xA1\xA2") (fromText r "test\xA1\xA2")- $expect $ equal (dec r "test\xEFA1\xEFA2") (fromChar8 "test\xA1\xA2")- $expect $ equal- (toText r (dec r "test\xEFA1\xEFA2"))- (Left "test\xA1\xA2")--test_DecodeString_Posix_Ghc704 :: Test-test_DecodeString_Posix_Ghc704 = assertions "posix_ghc704" $ do- let r = posix_ghc704- let dec = decodeString- $expect $ equal (dec r "test") (fromText r "test")- $expect $ equal (dec r "test\xC2\xA1\xC2\xA2") (fromText r "test\xC2\xA1\xC2\xA2")- $expect $ equal (dec r "test\xA1\xA2") (fromText r "test\xA1\xA2")- $expect $ equal (dec r "test\xDCA1\xDCA2") (fromChar8 "test\xA1\xA2")- $expect $ equal- (toText r (dec r "test\xDCA1\xDCA2"))- (Left "test\xA1\xA2")--test_DecodeString_Darwin :: Test-test_DecodeString_Darwin = assertions "darwin" $ do- let r = darwin- let dec = decodeString- $expect $ equal (dec r "test\xC2\xA1\xC2\xA2") (fromText r "test\xA1\xA2")--test_DecodeString_Darwin_Ghc702 :: Test-test_DecodeString_Darwin_Ghc702 = assertions "darwin_ghc702" $ do- let r = darwin_ghc702- let dec = decodeString- $expect $ equal (dec r "test\xC2\xA1\xC2\xA2") (fromText r "test\xC2\xA1\xC2\xA2")- $expect $ equal (dec r "test\xA1\xA2") (fromText r "test\xA1\xA2")--test_DecodeString_Win32 :: Test-test_DecodeString_Win32 = assertions "windows" $ do- let r = windows- let dec = decodeString- $expect $ equal (dec r "test") (fromText r "test")- $expect $ equal (dec r "test\xC2\xA1\xC2\xA2") (fromText r "test\xC2\xA1\xC2\xA2")- $expect $ equal (dec r "test\xA1\xA2") (fromText r "test\xA1\xA2")--test_EqualsIgnoresPosixEncoding :: Test-test_EqualsIgnoresPosixEncoding = assertions "equals-ignores-posix-encoding" $ do- $expect $ equal- (fromChar8 "test\xA1\xA2")- (fromText posix "test\xA1\xA2")--test_ShowRules :: Test-test_ShowRules = assertions "show-rules" $ do- $expect $ equal (showsPrec 11 darwin "") "(Rules \"Darwin\")"- $expect $ equal (showsPrec 11 darwin_ghc702 "") "(Rules \"Darwin (GHC 7.2)\")"- $expect $ equal (showsPrec 11 posix "") "(Rules \"POSIX\")"- $expect $ equal (showsPrec 11 posix_ghc702 "") "(Rules \"POSIX (GHC 7.2)\")"- $expect $ equal (showsPrec 11 windows "") "(Rules \"Windows\")"--posixPaths :: Gen FilePath-posixPaths = sized $ fmap merge . genComponents where- merge = fromChar8 . intercalate "/"- validChar c = not $ elem c ['\x00', '/']- component = do- size <- choose (0, 10)- vectorOf size $ arbitrary `suchThat` validChar- genComponents n = do- cs <- vectorOf n component- frequency [(1, return cs), (9, return ([""] ++ cs))]--windowsPaths :: Gen FilePath-windowsPaths = sized $ \n -> genComponents n >>= merge where- merge cs = do- root <- genRoot- let path = intercalate "\\" cs- return $ fromString $ root ++ path- - reserved = ['\x00'..'\x1F'] ++ ['/', '\\', '?', '*', ':', '|', '"', '<', '>']- reservedNames =- [ "AUX", "CLOCK$", "COM1", "COM2", "COM3", "COM4"- , "COM5", "COM6", "COM7", "COM8", "COM9", "CON"- , "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6"- , "LPT7", "LPT8", "LPT9", "NUL", "PRN"- ]- validChar c = not (elem c reserved)- validComponent c = not (elem (map toUpper c) reservedNames)- component = do- size <- choose (0, 10)- vectorOf size $ arbitrary `suchThat` validChar- genComponents n = do- cs <- vectorOf n (component `suchThat` validComponent)- frequency [(1, return cs), (9, return ([""] ++ cs))]- - genRoot = do- let upperChar = elements ['A'..'Z']- label <- frequency [(1, return Nothing), (9, fmap Just upperChar)]- return $ case label of- Just c -> [c, ':', '\\']- Nothing -> "\\"--toChar8 :: FilePath -> String-toChar8 = B8.unpack . encode posix--fromChar8 :: String -> FilePath-fromChar8 = decode posix . B8.pack--toString :: FilePath -> String-toString = T.unpack . encode windows--fromString :: String -> FilePath-fromString = decode windows . T.pack
− tests/system-filepath-tests.cabal
@@ -1,29 +0,0 @@-name: system-filepath-tests-version: 0-build-type: Simple-cabal-version: >= 1.6--flag coverage- default: False- manual: True--executable system-filepath_tests- main-is: Tests.hs- ghc-options: -Wall- hs-source-dirs: ../lib,.-- -- http://hackage.haskell.org/trac/ghc/ticket/5395- if impl(ghc < 7.2)- ghc-options: -fcontext-stack=200-- if flag(coverage)- ghc-options: -fhpc-- build-depends:- base > 4.0 && < 5.0- , bytestring- , chell >= 0.3 && < 0.4- , chell-quickcheck >= 0.2 && < 0.3- , deepseq >= 1.1 && < 1.4- , QuickCheck- , text