File: FilePath.hs

package info (click to toggle)
haskell-shake 0.13.2%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 888 kB
  • ctags: 127
  • sloc: haskell: 6,388; makefile: 35; ansic: 25; sh: 2
file content (96 lines) | stat: -rw-r--r-- 3,214 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

module Examples.Test.FilePath(main) where

import Development.Shake.FilePath
import qualified System.FilePath as Native
import qualified System.FilePath.Posix as Posix
import General.Base
import Examples.Util
import Test.QuickCheck
import Control.Monad
import Data.List
import qualified Data.ByteString.Char8 as BS
import qualified Development.Shake.ByteString as BS


main = shaken test $ \args obj -> return ()


newtype File = File String deriving Show

instance Arbitrary File where
    arbitrary = fmap File $ listOf $ oneof $ map return "abc /\\:."


test build obj = do
    let a === b = a Examples.Util.=== b -- duplicate definition in QuickCheck 2.7 and above

    let norm x =
            let s = normalise x
                b = BS.unpack (BS.normalise $ BS.pack x)
            in if s == b then s else error $ show ("Normalise functions differ",x,s,b)
    -- basic examples
    norm "" === "."
    norm "." === "."
    norm "/" === "/"
    norm "./" === "./"
    norm "/." === "/."
    norm "/./" === "/"
    norm "a/." === "a"
    norm "./a" === "a"
    norm "./a/." === "a"
    norm "./a/./" === "a/"
    norm "a/.." === "."
    norm "a/./.." === "."
    norm "a/../" === "./"
    norm "/a/../" === "/"
    norm "/a/./../" === "/"
    norm "../a" === "../a"
    norm "/../a/" === "/../a/"

    -- more realistic examples
    norm "neil//./test/moo/../bar/bob/../foo" === "neil/test/bar/foo"
    norm "bar/foo" === "bar/foo"
    norm "bar/foo/" === "bar/foo/"
    norm "../../foo" === "../../foo"
    norm "foo/../..///" === "../"
    norm "foo/bar/../../neil" === "neil"
    norm "foo/../bar/../neil" === "neil"
    norm "/foo/bar" === "/foo/bar"
    norm "//./" === (if isWindows then "//" else "/")
    norm "//foo/./bar" === (if isWindows then "//foo/bar" else "/foo/bar")
    when isWindows $ norm "c:\\foo\\bar" === "c:/foo/bar"
    Success{} <- quickCheckWithResult stdArgs{maxSuccess=1000} $ \(File x) ->
        let y = norm x
            sep = Native.isPathSeparator
            noDrive = if isWindows then drop 1 else id
            ps = [length y >= 1
                 ,null x || (sep (head x) == sep (head y) && sep (last x) == sep (last y))
                 ,not $ "/./" `isInfixOf` y
                 ,not isWindows || '\\' `notElem` y
                 ,not $ "//" `isInfixOf` noDrive y
                 ,".." `notElem` dropWhile (== "..") (splitDirectories $ dropWhile sep y)
                 ,norm y == y]
        in if and ps then True else error $ show (x, y, ps)

    dropDirectory1 "aaa/bbb" === "bbb"
    dropDirectory1 "aaa/" === ""
    dropDirectory1 "aaa" === ""
    dropDirectory1 "" === ""

    takeDirectory1 "aaa/bbb" === "aaa"
    takeDirectory1 "aaa/" === "aaa"
    takeDirectory1 "aaa" === "aaa"

    combine "." "ccc" === "ccc"
    combine "aaa/bbb" "ccc" === "aaa/bbb/ccc"
    combine "aaa/bbb" "./ccc" === "aaa/bbb/ccc"
    combine "aaa/bbb" "../ccc" === "aaa/ccc"
    combine "aaa/bbb" "../../ccc" === "ccc"
    combine ".." "aaa" === "../aaa"
    combine "../.." "aaa" === "../../aaa"
    combine "./a" "../aaa" === "aaa"
    combine ".." "../aaa" === "../../aaa"

    searchPathSeparator === Native.searchPathSeparator
    pathSeparators === Posix.pathSeparators