path 0.8.0 → 0.9.0
raw patch · 18 files changed
+366/−308 lines, 18 filesdep ~template-haskell
Dependency ranges changed: template-haskell
Files
- CHANGELOG +5/−0
- README.md +1/−2
- path.cabal +9/−5
- src/Path/Include.hs +11/−1
- src/Path/Internal.hs +7/−136
- src/Path/Internal/Include.hs +138/−0
- src/Path/Internal/Posix.hs +4/−0
- src/Path/Internal/Windows.hs +4/−0
- test/Common.hs +0/−87
- test/Common/Include.hs +126/−0
- test/Common/Posix.hs +24/−0
- test/Common/Windows.hs +24/−0
- test/Main.hs +5/−8
- test/Path/Gen.hs +2/−2
- test/Posix.hs +2/−2
- test/TH.hs +0/−58
- test/ValidityTest.hs +2/−5
- test/Windows.hs +2/−2
CHANGELOG view
@@ -1,3 +1,8 @@+0.9.0+ * Fix inconsistencies on different platforms: [#166](https://github.com/commercialhaskell/path/issues/166)+ * `replaceProperPrefix`+ * Make it possible to use windows paths on posix and vice versa+ 0.8.0 * Rerelease of 0.7.1 with better version number
README.md view
@@ -1,7 +1,6 @@ # Path -[](https://travis-ci.org/commercialhaskell/path)-[](https://ci.appveyor.com/project/chrisdone/path)+ [](https://hackage.haskell.org/package/path) [](http://stackage.org/lts/package/path) [](http://stackage.org/nightly/package/path)
path.cabal view
@@ -1,5 +1,5 @@ name: path-version: 0.8.0+version: 0.9.0 synopsis: Support for well-typed paths description: Support for well-typed paths. license: BSD3@@ -10,10 +10,12 @@ category: System, Filesystem build-type: Simple cabal-version: 1.18-tested-with: GHC==8.6.5, GHC==8.8.3, GHC==8.10.1+tested-with: GHC==8.6.5, GHC==8.8.4, GHC==8.10.1 extra-source-files: README.md , CHANGELOG , src/Path/Include.hs+ , src/Path/Internal/Include.hs+ , test/Common/Include.hs flag dev description: Turn on development settings.@@ -23,9 +25,11 @@ library hs-source-dirs: src exposed-modules: Path- , Path.Internal , Path.Posix , Path.Windows+ , Path.Internal+ , Path.Internal.Posix+ , Path.Internal.Windows build-depends: aeson , base >= 4.12 && < 5 , deepseq@@ -50,8 +54,8 @@ main-is: Main.hs other-modules: Posix , Windows- , Common- , TH+ , Common.Posix+ , Common.Windows hs-source-dirs: test build-depends: aeson , base >= 4.12 && < 5
src/Path/Include.hs view
@@ -53,6 +53,7 @@ ,(</>) ,stripProperPrefix ,isProperPrefixOf+ ,replaceProperPrefix ,parent ,filename ,dirname@@ -108,7 +109,7 @@ import Language.Haskell.TH import Language.Haskell.TH.Syntax (lift) import Language.Haskell.TH.Quote (QuasiQuoter(..))-import Path.Internal+import Path.Internal.PLATFORM_NAME import qualified System.FilePath.PLATFORM_NAME as FilePath --------------------------------------------------------------------------------@@ -336,6 +337,15 @@ -- @since 0.6.0 isProperPrefixOf :: Path b Dir -> Path b t -> Bool isProperPrefixOf p l = isJust (stripProperPrefix p l)++-- | Change from one directory prefix to another.+--+-- Throw 'NotAProperPrefix' if the first argument is not a proper prefix of the+-- path.+--+-- >>> replaceProperPrefix $(mkRelDir "foo") $(mkRelDir "bar") $(mkRelFile "foo/file.txt") == $(mkRelFile "bar/file.txt")+replaceProperPrefix :: MonadThrow m => Path b Dir -> Path b' Dir -> Path b t -> m (Path b' t)+replaceProperPrefix src dst fp = (dst </>) <$> stripProperPrefix src fp -- | Take the parent path component from a path. --
src/Path/Internal.hs view
@@ -1,138 +1,9 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE TemplateHaskell #-}---- | Internal types and functions.--module Path.Internal- ( Path(..)- , hasParentDir- , relRootFP- , toFilePath- )- where--import Control.DeepSeq (NFData (..))-import Data.Aeson (ToJSON (..), ToJSONKey(..))-import Data.Aeson.Types (toJSONKeyText)-import qualified Data.Text as T (pack)-import GHC.Generics (Generic)-import Data.Data-import Data.Hashable-import qualified Data.List as L-import qualified Language.Haskell.TH.Syntax as TH-import qualified System.FilePath as FilePath---- | Path of some base and type.------ The type variables are:------ * @b@ — base, the base location of the path; absolute or relative.--- * @t@ — type, whether file or directory.------ Internally is a string. The string can be of two formats only:------ 1. File format: @file.txt@, @foo\/bar.txt@, @\/foo\/bar.txt@--- 2. Directory format: @foo\/@, @\/foo\/bar\/@------ All directories end in a trailing separator. There are no duplicate--- path separators @\/\/@, no @..@, no @.\/@, no @~\/@, etc.-newtype Path b t = Path FilePath- deriving (Data, Typeable, Generic)---- | String equality.------ The following property holds:------ @show x == show y ≡ x == y@-instance Eq (Path b t) where- (==) (Path x) (Path y) = x == y---- | String ordering.------ The following property holds:------ @show x \`compare\` show y ≡ x \`compare\` y@-instance Ord (Path b t) where- compare (Path x) (Path y) = compare x y---- | Normalized file path representation for the relative path root-relRootFP :: FilePath-relRootFP = '.' : [FilePath.pathSeparator]---- | Convert to a 'FilePath' type.------ All directories have a trailing slash, so if you want no trailing--- slash, you can use 'System.FilePath.dropTrailingPathSeparator' from--- the filepath package.-toFilePath :: Path b t -> FilePath-toFilePath (Path []) = relRootFP-toFilePath (Path x) = x---- | Same as 'show . Path.toFilePath'.------ The following property holds:------ @x == y ≡ show x == show y@-instance Show (Path b t) where- show = show . toFilePath--instance NFData (Path b t) where- rnf (Path x) = rnf x--instance ToJSON (Path b t) where- toJSON = toJSON . toFilePath- {-# INLINE toJSON #-}-#if MIN_VERSION_aeson(0,10,0)- toEncoding = toEncoding . toFilePath- {-# INLINE toEncoding #-}-#endif--instance ToJSONKey (Path b t) where- toJSONKey = toJSONKeyText $ T.pack . toFilePath--instance Hashable (Path b t) where- -- A "." is represented as an empty string ("") internally. Hashing ""- -- results in a hash that is the same as the salt. To produce a more- -- reasonable hash we use "toFilePath" before hashing so that a "" gets- -- converted back to a ".".- hashWithSalt n path = hashWithSalt n (toFilePath path)---- | Helper function: check if the filepath has any parent directories in it.--- This handles the logic of checking for different path separators on Windows.-hasParentDir :: FilePath -> Bool-hasParentDir filepath' =- (filepath' == "..") ||- ("/.." `L.isSuffixOf` filepath) ||- ("/../" `L.isInfixOf` filepath) ||- ("../" `L.isPrefixOf` filepath)- where- filepath =- case FilePath.pathSeparator of- '/' -> filepath'- x -> map (\y -> if x == y then '/' else y) filepath'--instance (Typeable a, Typeable b) => TH.Lift (Path a b) where- lift p@(Path str) = do- let btc = typeRepTyCon $ typeRep $ mkBaseProxy p- ttc = typeRepTyCon $ typeRep $ mkTypeProxy p- bn <- lookupTypeNameThrow $ tyConName btc- tn <- lookupTypeNameThrow $ tyConName ttc- [|Path $(return (TH.LitE (TH.StringL str))) :: Path- $(return $ TH.ConT bn)- $(return $ TH.ConT tn)- |]- where- mkBaseProxy :: Path a b -> Proxy a- mkBaseProxy _ = Proxy-- mkTypeProxy :: Path a b -> Proxy b- mkTypeProxy _ = Proxy-- lookupTypeNameThrow n = TH.lookupTypeName n- >>= maybe (fail $ "Not in scope: type constructor ‘" ++ n ++ "’") return+{-# LANGUAGE CPP #-} -#if MIN_VERSION_template_haskell(2,16,0)- liftTyped = TH.unsafeTExpCoerce . TH.lift+#if defined(mingw32_HOST_OS)+module Path.Internal(module Path.Internal.Windows) where+import Path.Internal.Windows+#else+module Path.Internal(module Path.Internal.Posix) where+import Path.Internal.Posix #endif
+ src/Path/Internal/Include.hs view
@@ -0,0 +1,138 @@+-- This template expects CPP definitions for:+-- PLATFORM_NAME = Posix | Windows+-- IS_WINDOWS = False | True++{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}++-- | Internal types and functions.++module Path.Internal.PLATFORM_NAME+ ( Path(..)+ , relRootFP+ , toFilePath+ , hasParentDir+ )+ where++import Control.DeepSeq (NFData (..))+import Data.Aeson (ToJSON (..), ToJSONKey(..))+import Data.Aeson.Types (toJSONKeyText)+import qualified Data.Text as T (pack)+import GHC.Generics (Generic)+import Data.Data+import Data.Hashable+import qualified Data.List as L+import qualified Language.Haskell.TH.Syntax as TH+import qualified System.FilePath.PLATFORM_NAME as FilePath++-- | Path of some base and type.+--+-- The type variables are:+--+-- * @b@ — base, the base location of the path; absolute or relative.+-- * @t@ — type, whether file or directory.+--+-- Internally is a string. The string can be of two formats only:+--+-- 1. File format: @file.txt@, @foo\/bar.txt@, @\/foo\/bar.txt@+-- 2. Directory format: @foo\/@, @\/foo\/bar\/@+--+-- All directories end in a trailing separator. There are no duplicate+-- path separators @\/\/@, no @..@, no @.\/@, no @~\/@, etc.+newtype Path b t = Path FilePath+ deriving (Data, Typeable, Generic)++-- | String equality.+--+-- The following property holds:+--+-- @show x == show y ≡ x == y@+instance Eq (Path b t) where+ (==) (Path x) (Path y) = x == y++-- | String ordering.+--+-- The following property holds:+--+-- @show x \`compare\` show y ≡ x \`compare\` y@+instance Ord (Path b t) where+ compare (Path x) (Path y) = compare x y++-- | Normalized file path representation for the relative path root+relRootFP :: FilePath+relRootFP = '.' : [FilePath.pathSeparator]++-- | Convert to a 'FilePath' type.+--+-- All directories have a trailing slash, so if you want no trailing+-- slash, you can use 'System.FilePath.dropTrailingPathSeparator' from+-- the filepath package.+toFilePath :: Path b t -> FilePath+toFilePath (Path []) = relRootFP+toFilePath (Path x) = x++-- | Helper function: check if the filepath has any parent directories in it.+-- This handles the logic of checking for different path separators on Windows.+hasParentDir :: FilePath -> Bool+hasParentDir filepath' =+ (filepath' == "..") ||+ ("/.." `L.isSuffixOf` filepath) ||+ ("/../" `L.isInfixOf` filepath) ||+ ("../" `L.isPrefixOf` filepath)+ where+ filepath =+ case FilePath.pathSeparator of+ '/' -> filepath'+ x -> map (\y -> if x == y then '/' else y) filepath'++-- | Same as 'show . Path.toFilePath'.+--+-- The following property holds:+--+-- @x == y ≡ show x == show y@+instance Show (Path b t) where+ show = show . toFilePath++instance NFData (Path b t) where+ rnf (Path x) = rnf x++instance ToJSON (Path b t) where+ toJSON = toJSON . toFilePath+ {-# INLINE toJSON #-}+#if MIN_VERSION_aeson(0,10,0)+ toEncoding = toEncoding . toFilePath+ {-# INLINE toEncoding #-}+#endif++instance ToJSONKey (Path b t) where+ toJSONKey = toJSONKeyText $ T.pack . toFilePath++instance Hashable (Path b t) where+ -- A "." is represented as an empty string ("") internally. Hashing ""+ -- results in a hash that is the same as the salt. To produce a more+ -- reasonable hash we use "toFilePath" before hashing so that a "" gets+ -- converted back to a ".".+ hashWithSalt n path = hashWithSalt n (toFilePath path)++instance forall b t. (Typeable b, Typeable t) => TH.Lift (Path b t) where+ lift (Path str) = do+ let b = TH.ConT $ getTCName (Proxy :: Proxy b)+ t = TH.ConT $ getTCName (Proxy :: Proxy t)+ [|Path $(pure (TH.LitE (TH.StringL str))) :: Path $(pure b) $(pure t) |]+ where+ getTCName :: Typeable a => proxy a -> TH.Name+ getTCName a = TH.Name occ flav+ where+ tc = typeRepTyCon (typeRep a)+ occ = TH.OccName (tyConName tc)+ flav = TH.NameG TH.TcClsName (TH.PkgName (tyConPackage tc)) (TH.ModName (tyConModule tc))++#if MIN_VERSION_template_haskell(2,17,0)+ liftTyped = TH.unsafeCodeCoerce . TH.lift+#elif MIN_VERSION_template_haskell(2,16,0)+ liftTyped = TH.unsafeTExpCoerce . TH.lift+#endif
+ src/Path/Internal/Posix.hs view
@@ -0,0 +1,4 @@+{-# LANGUAGE CPP #-}+#define PLATFORM_NAME Posix+#define IS_WINDOWS False+#include "Include.hs"
+ src/Path/Internal/Windows.hs view
@@ -0,0 +1,4 @@+{-# LANGUAGE CPP #-}+#define PLATFORM_NAME Windows+#define IS_WINDOWS True+#include "Include.hs"
− test/Common.hs
@@ -1,87 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}---- | Test functions that are common to Posix and Windows--module Common (extensionOperations) where--import Control.Monad-import Path-import System.FilePath (pathSeparator)-import Test.Hspec--validExtensionsSpec :: String -> Path b File -> Path b File -> Spec-validExtensionsSpec ext file fext = do- let f = show $ toFilePath file- let fx = show $ toFilePath fext-- it ("addExtension " ++ show ext ++ " " ++ f ++ " == " ++ fx) $- addExtension ext file `shouldReturn` fext-- it ("fileExtension " ++ fx ++ " == " ++ ext) $- fileExtension fext `shouldReturn` ext-- it ("replaceExtension " ++ show ext ++ " " ++ fx ++ " == " ++ fx) $- replaceExtension ext fext `shouldReturn` fext--extensionOperations :: String -> Spec-extensionOperations rootDrive = do- let ext = ".foo"- let extensions = ext : [".foo.", ".foo.."]-- -- Only filenames and extensions- forM_ extensions (\x ->- forM_ filenames $ \f -> do- let Just file = parseRelFile f- let Just fext = parseRelFile (f ++ x)- (validExtensionsSpec x file fext))-- -- Relative dir paths- forM_ dirnames (\d -> do- forM_ filenames (\f -> do- let f1 = d ++ [pathSeparator] ++ f- let Just file = parseRelFile f1- let Just fext = parseRelFile (f1 ++ ext)- validExtensionsSpec ext file fext))-- -- Absolute dir paths- forM_ dirnames (\d -> do- forM_ filenames (\f -> do- let f1 = rootDrive ++ d ++ [pathSeparator] ++ f- let Just file = parseAbsFile f1- let Just fext = parseAbsFile (f1 ++ ext)- validExtensionsSpec ext file fext))-- -- Invalid extensions- forM_ invalidExtensions $ \x -> do- it ("throws InvalidExtension when extension is [" ++ x ++ "]") $- addExtension x $(mkRelFile "name")- `shouldThrow` (== InvalidExtension x)-- where-- filenames =- [ "name"- , "name."- , "name.."- , ".name"- , "..name"- , "name.name"- , "name..name"- , "..."- ]- dirnames = filenames ++ ["."]- invalidExtensions =- [ ""- , "."- , "x"- , ".."- , "..."- , "xy"- , "foo"- , "foo."- , "foo.."- , "..foo"- , "...foo"- , ".foo.bar"- , ".foo" ++ [pathSeparator] ++ "bar"- ]
+ test/Common/Include.hs view
@@ -0,0 +1,126 @@+-- This template expects CPP definitions for:+-- PLATFORM_NAME = Posix | Windows+-- IS_WINDOWS = False | True++{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}++-- | Test functions that are common to Posix and Windows++module Common.PLATFORM_NAME (extensionOperations) where++import Control.Monad+import qualified Language.Haskell.TH.Syntax as TH+import Path.Internal.PLATFORM_NAME+import Path.PLATFORM_NAME+import System.FilePath.PLATFORM_NAME (pathSeparator)+import Test.Hspec++class Foo a b where+ foo :: Path a b -> FilePath+ foo = toFilePath++instance Foo Abs Dir+instance Foo Abs File+instance Foo Rel Dir+instance Foo Rel File++qqRelDir :: FilePath+qqRelDir = foo [reldir|foo/|]++qqRelFile :: FilePath+qqRelFile = foo [relfile|foo|]++thRelDir :: FilePath+thRelDir = foo $(mkRelDir "foo/")++thRelFile :: FilePath+thRelFile = foo $(mkRelFile "foo")++liftRelDir :: FilePath+liftRelDir = foo $(TH.lift (Path "foo/" :: Path Rel Dir))++liftRelFile :: FilePath+liftRelFile = foo $(TH.lift (Path "foo" :: Path Rel File))++validExtensionsSpec :: String -> Path b File -> Path b File -> Spec+validExtensionsSpec ext file fext = do+ let f = show $ toFilePath file+ let fx = show $ toFilePath fext++ it ("addExtension " ++ show ext ++ " " ++ f ++ " == " ++ fx) $+ addExtension ext file `shouldReturn` fext++ it ("fileExtension " ++ fx ++ " == " ++ ext) $+ fileExtension fext `shouldReturn` ext++ it ("replaceExtension " ++ show ext ++ " " ++ fx ++ " == " ++ fx) $+ replaceExtension ext fext `shouldReturn` fext++extensionOperations :: String -> Spec+extensionOperations rootDrive = do+ let extension = ".foo"+ let extensions = extension : [".foo.", ".foo.."]++ describe "Only filenames and extensions" $+ forM_ extensions $ \ext ->+ forM_ filenames $ \f -> do+ runTests parseRelFile f ext++ describe "Relative dir paths" $+ forM_ dirnames $ \d -> do+ forM_ filenames $ \f -> do+ let f1 = d ++ [pathSeparator] ++ f+ runTests parseRelFile f1 extension++ describe "Absolute dir paths" $+ forM_ dirnames $ \d -> do+ forM_ filenames $ \f -> do+ let f1 = rootDrive ++ d ++ [pathSeparator] ++ f+ runTests parseAbsFile f1 extension++ -- Invalid extensions+ forM_ invalidExtensions $ \ext -> do+ it ("throws InvalidExtension when extension is [" ++ ext ++ "]") $+ addExtension ext $(mkRelFile "name")+ `shouldThrow` (== InvalidExtension ext)++ where++ runTests parse file ext = do+ let maybePathFile = parse file+ let maybePathFileWithExt = parse (file ++ ext)+ case (maybePathFile, maybePathFileWithExt) of+ (Just pathFile, Just pathFileWithExt) -> validExtensionsSpec ext pathFile pathFileWithExt+ _ -> it ("Files " ++ show file ++ " and/or " ++ show (file ++ ext) ++ " should parse successfully.") $+ expectationFailure $+ show file ++ " parsed to " ++ show maybePathFile ++ ", "+ ++ show (file ++ ext) ++ " parsed to " ++ show maybePathFileWithExt++ filenames =+ [ "name"+ , "name."+ , "name.."+ , ".name"+ , "..name"+ , "name.name"+ , "name..name"+ , "..."+ ]+ dirnames = filenames ++ ["."]+ invalidExtensions =+ [ ""+ , "."+ , "x"+ , ".."+ , "..."+ , "xy"+ , "foo"+ , "foo."+ , "foo.."+ , "..foo"+ , "...foo"+ , ".foo.bar"+ , ".foo" ++ [pathSeparator] ++ "bar"+ ]
+ test/Common/Posix.hs view
@@ -0,0 +1,24 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE QuasiQuotes #-}++#define PLATFORM_NAME Posix+#define IS_WINDOWS False+#include "Include.hs"++qqAbsDir :: FilePath+qqAbsDir = foo [absdir|/foo/|]++qqAbsFile :: FilePath+qqAbsFile = foo [absdir|/foo|]++thAbsDir :: FilePath+thAbsDir = foo $(mkAbsDir "/foo/")++thAbsFile :: FilePath+thAbsFile = foo $(mkAbsFile "/foo")++liftAbsDir :: FilePath+liftAbsDir = foo $(TH.lift (Path "/foo/" :: Path Abs Dir))++liftAbsFile :: FilePath+liftAbsFile = foo $(TH.lift (Path "/foo" :: Path Abs File))
+ test/Common/Windows.hs view
@@ -0,0 +1,24 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE QuasiQuotes #-}+#define PLATFORM_NAME Windows+#define IS_WINDOWS True+#include "Include.hs"++qqAbsDir :: FilePath+qqAbsDir = foo [absdir|C:\foo\|]++qqAbsFile :: FilePath+qqAbsFile = foo [absdir|C:\foo|]++thAbsDir :: FilePath+thAbsDir = foo $(mkAbsDir "C:\\foo\\")++thAbsFile :: FilePath+thAbsFile = foo $(mkAbsFile "C:\\foo")++liftAbsDir :: FilePath+liftAbsDir = foo $(TH.lift (Path "C:\\foo\\" :: Path Abs Dir))++liftAbsFile :: FilePath+liftAbsFile = foo $(TH.lift (Path "C:\\foo" :: Path Abs File))+
test/Main.hs view
@@ -1,15 +1,12 @@-{-# LANGUAGE CPP #-}- module Main (main) where -#ifdef mingw32_HOST_OS-import Windows (spec)-#else-import Posix (spec)-#endif+import qualified Windows+import qualified Posix import Test.Hspec -- | Test suite entry point, returns exit failure if any test fails. main :: IO ()-main = hspec spec+main = hspec $ do+ describe "Path.Windows" Windows.spec+ describe "Path.Posix" Posix.spec
test/Path/Gen.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TemplateHaskell #-}+{-# OPTIONS_GHC -fno-warn-orphans #-} module Path.Gen where @@ -12,9 +13,8 @@ import qualified System.FilePath as FilePath import Data.GenValidity-import Data.List (isInfixOf, isSuffixOf)+import Data.List (isSuffixOf) import Data.Maybe (isJust, mapMaybe)-import Data.Validity import Test.QuickCheck
test/Posix.hs view
@@ -13,10 +13,10 @@ import qualified Data.ByteString.Lazy.Char8 as LBS import Data.Maybe import Path.Posix-import Path.Internal+import Path.Internal.Posix import Test.Hspec -import Common (extensionOperations)+import Common.Posix (extensionOperations) -- | Test suite (Posix version). spec :: Spec
− test/TH.hs
@@ -1,58 +0,0 @@-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}--module TH where--import qualified Language.Haskell.TH.Syntax as TH-import Path-import Path.Internal----class Foo a b where- foo :: Path a b -> FilePath- foo = toFilePath--instance Foo Abs Dir-instance Foo Abs File-instance Foo Rel Dir-instance Foo Rel File----qqAbsDir :: FilePath-qqAbsDir = foo [absdir|/foo/|]--qqAbsFile :: FilePath-qqAbsFile = foo [absfile|/foo|]--qqRelDir :: FilePath-qqRelDir = foo [reldir|foo/|]--qqRelFile :: FilePath-qqRelFile = foo [relfile|foo|]--thAbsDir :: FilePath-thAbsDir = foo $(mkAbsDir "/foo/")--thAbsFile :: FilePath-thAbsFile = foo $(mkAbsFile "/foo")--thRelDir :: FilePath-thRelDir = foo $(mkRelDir "foo/")--thRelFile :: FilePath-thRelFile = foo $(mkRelFile "foo")--liftAbsDir :: FilePath-liftAbsDir = foo $(TH.lift (Path "/foo/" :: Path Abs Dir))--liftAbsFile :: FilePath-liftAbsFile = foo $(TH.lift (Path "/foo" :: Path Abs File))--liftRelDir :: FilePath-liftRelDir = foo $(TH.lift (Path "foo/" :: Path Rel Dir))--liftRelFile :: FilePath-liftRelFile = foo $(TH.lift (Path "foo" :: Path Rel File))
test/ValidityTest.hs view
@@ -2,14 +2,11 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeApplications #-}+{-# OPTIONS_GHC -fno-warn-name-shadowing #-} -- | Test suite. module Main where -import Control.Applicative-import Control.Monad-import Data.Aeson-import qualified Data.ByteString.Lazy.Char8 as LBS import Data.Maybe import Path import Path.Internal@@ -170,7 +167,7 @@ addExtGensValidFile p = case addExtension p $(mkRelFile "x") of Nothing -> True- Just x ->+ Just _ -> case parseRelFile p of Nothing -> False _ -> True
test/Windows.hs view
@@ -13,10 +13,10 @@ import qualified Data.ByteString.Lazy.Char8 as LBS import Data.Maybe import Path.Windows-import Path.Internal+import Path.Internal.Windows import Test.Hspec -import Common (extensionOperations)+import Common.Windows (extensionOperations) -- | Test suite (Windows version). spec :: Spec