tpaths.nim 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. discard """
  2. matrix: "--mm:refc; --mm:orc"
  3. """
  4. import std/paths
  5. import std/assertions
  6. import pathnorm
  7. from std/private/ospaths2 {.all.} import joinPathImpl
  8. import std/[sugar, sets]
  9. proc normalizePath*(path: Path; dirSep = DirSep): Path =
  10. result = Path(pathnorm.normalizePath(path.string, dirSep))
  11. func joinPath*(parts: varargs[Path]): Path =
  12. var estimatedLen = 0
  13. var state = 0
  14. for p in parts: estimatedLen += p.string.len
  15. var res = newStringOfCap(estimatedLen)
  16. for i in 0..high(parts):
  17. joinPathImpl(res, state, parts[i].string)
  18. result = Path(res)
  19. func joinPath(head, tail: Path): Path {.inline.} =
  20. head / tail
  21. block absolutePath:
  22. doAssertRaises(ValueError): discard absolutePath(Path"a", Path"b")
  23. doAssert absolutePath(Path"a") == getCurrentDir() / Path"a"
  24. doAssert absolutePath(Path"a", Path"/b") == Path"/b" / Path"a"
  25. when defined(posix):
  26. doAssert absolutePath(Path"a", Path"/b/") == Path"/b" / Path"a"
  27. doAssert absolutePath(Path"a", Path"/b/c") == Path"/b/c" / Path"a"
  28. doAssert absolutePath(Path"/a", Path"b/") == Path"/a"
  29. block splitFile:
  30. doAssert splitFile(Path"") == (Path"", Path"", "")
  31. doAssert splitFile(Path"abc/") == (Path"abc", Path"", "")
  32. doAssert splitFile(Path"/") == (Path"/", Path"", "")
  33. doAssert splitFile(Path"./abc") == (Path".", Path"abc", "")
  34. doAssert splitFile(Path".txt") == (Path"", Path".txt", "")
  35. doAssert splitFile(Path"abc/.txt") == (Path"abc", Path".txt", "")
  36. doAssert splitFile(Path"abc") == (Path"", Path"abc", "")
  37. doAssert splitFile(Path"abc.txt") == (Path"", Path"abc", ".txt")
  38. doAssert splitFile(Path"/abc.txt") == (Path"/", Path"abc", ".txt")
  39. doAssert splitFile(Path"/foo/abc.txt") == (Path"/foo", Path"abc", ".txt")
  40. doAssert splitFile(Path"/foo/abc.txt.gz") == (Path"/foo", Path"abc.txt", ".gz")
  41. doAssert splitFile(Path".") == (Path"", Path".", "")
  42. doAssert splitFile(Path"abc/.") == (Path"abc", Path".", "")
  43. doAssert splitFile(Path"..") == (Path"", Path"..", "")
  44. doAssert splitFile(Path"a/..") == (Path"a", Path"..", "")
  45. doAssert splitFile(Path"/foo/abc....txt") == (Path"/foo", Path"abc...", ".txt")
  46. # execShellCmd is tested in tosproc
  47. block ospaths:
  48. doAssert unixToNativePath(Path"") == Path""
  49. doAssert unixToNativePath(Path".") == Path($CurDir)
  50. doAssert unixToNativePath(Path"..") == Path($ParDir)
  51. doAssert isAbsolute(unixToNativePath(Path"/"))
  52. doAssert isAbsolute(unixToNativePath(Path"/", Path"a"))
  53. doAssert isAbsolute(unixToNativePath(Path"/a"))
  54. doAssert isAbsolute(unixToNativePath(Path"/a", Path"a"))
  55. doAssert isAbsolute(unixToNativePath(Path"/a/b"))
  56. doAssert isAbsolute(unixToNativePath(Path"/a/b", Path"a"))
  57. doAssert unixToNativePath(Path"a/b") == joinPath(Path"a", Path"b")
  58. when defined(macos):
  59. doAssert unixToNativePath(Path"./") == Path":"
  60. doAssert unixToNativePath(Path"./abc") == Path":abc"
  61. doAssert unixToNativePath(Path"../abc") == Path"::abc"
  62. doAssert unixToNativePath(Path"../../abc") == Path":::abc"
  63. doAssert unixToNativePath(Path"/abc", Path"a") == Path"abc"
  64. doAssert unixToNativePath(Path"/abc/def", Path"a") == Path"abc:def"
  65. elif doslikeFileSystem:
  66. doAssert unixToNativePath(Path"./") == Path(".\\")
  67. doAssert unixToNativePath(Path"./abc") == Path(".\\abc")
  68. doAssert unixToNativePath(Path"../abc") == Path("..\\abc")
  69. doAssert unixToNativePath(Path"../../abc") == Path("..\\..\\abc")
  70. doAssert unixToNativePath(Path"/abc", Path"a") == Path("a:\\abc")
  71. doAssert unixToNativePath(Path"/abc/def", Path"a") == Path("a:\\abc\\def")
  72. else:
  73. #Tests for unix
  74. doAssert unixToNativePath(Path"./") == Path"./"
  75. doAssert unixToNativePath(Path"./abc") == Path"./abc"
  76. doAssert unixToNativePath(Path"../abc") == Path"../abc"
  77. doAssert unixToNativePath(Path"../../abc") == Path"../../abc"
  78. doAssert unixToNativePath(Path"/abc", Path"a") == Path"/abc"
  79. doAssert unixToNativePath(Path"/abc/def", Path"a") == Path"/abc/def"
  80. block extractFilenameTest:
  81. doAssert extractFilename(Path"") == Path""
  82. when defined(posix):
  83. doAssert extractFilename(Path"foo/bar") == Path"bar"
  84. doAssert extractFilename(Path"foo/bar.txt") == Path"bar.txt"
  85. doAssert extractFilename(Path"foo/") == Path""
  86. doAssert extractFilename(Path"/") == Path""
  87. when doslikeFileSystem:
  88. doAssert extractFilename(Path(r"foo\bar")) == Path"bar"
  89. doAssert extractFilename(Path(r"foo\bar.txt")) == Path"bar.txt"
  90. doAssert extractFilename(Path(r"foo\")) == Path""
  91. doAssert extractFilename(Path(r"C:\")) == Path""
  92. block lastPathPartTest:
  93. doAssert lastPathPart(Path"") == Path""
  94. when defined(posix):
  95. doAssert lastPathPart(Path"foo/bar.txt") == Path"bar.txt"
  96. doAssert lastPathPart(Path"foo/") == Path"foo"
  97. doAssert lastPathPart(Path"/") == Path""
  98. when doslikeFileSystem:
  99. doAssert lastPathPart(Path(r"foo\bar.txt")) == Path"bar.txt"
  100. doAssert lastPathPart(Path(r"foo\")) == Path"foo"
  101. template canon(x): Path = normalizePath(Path(x), '/')
  102. doAssert canon"/foo/../bar" == Path"/bar"
  103. doAssert canon"foo/../bar" == Path"bar"
  104. doAssert canon"/f/../bar///" == Path"/bar"
  105. doAssert canon"f/..////bar" == Path"bar"
  106. doAssert canon"../bar" == Path"../bar"
  107. doAssert canon"/../bar" == Path"/../bar"
  108. doAssert canon("foo/../../bar/") == Path"../bar"
  109. doAssert canon("./bla/blob/") == Path"bla/blob"
  110. doAssert canon(".hiddenFile") == Path".hiddenFile"
  111. doAssert canon("./bla/../../blob/./zoo.nim") == Path"../blob/zoo.nim"
  112. doAssert canon("C:/file/to/this/long") == Path"C:/file/to/this/long"
  113. doAssert canon("") == Path""
  114. doAssert canon("foobar") == Path"foobar"
  115. doAssert canon("f/////////") == Path"f"
  116. doAssert relativePath(Path"/foo/bar//baz.nim", Path"/foo", '/') == Path"bar/baz.nim"
  117. doAssert normalizePath(Path"./foo//bar/../baz", '/') == Path"foo/baz"
  118. doAssert relativePath(Path"/Users/me/bar/z.nim", Path"/Users/other/bad", '/') == Path"../../me/bar/z.nim"
  119. doAssert relativePath(Path"/Users/me/bar/z.nim", Path"/Users/other", '/') == Path"../me/bar/z.nim"
  120. # `//` is a UNC path, `/` is the current working directory's drive, so can't
  121. # run this test on Windows.
  122. when not doslikeFileSystem:
  123. doAssert relativePath(Path"/Users///me/bar//z.nim", Path"//Users/", '/') == Path"me/bar/z.nim"
  124. doAssert relativePath(Path"/Users/me/bar/z.nim", Path"/Users/me", '/') == Path"bar/z.nim"
  125. doAssert relativePath(Path"", Path"/users/moo", '/') == Path""
  126. doAssert relativePath(Path"foo", Path"", '/') == Path"foo"
  127. doAssert relativePath(Path"/foo", Path"/Foo", '/') == (when FileSystemCaseSensitive: Path"../foo" else: Path".")
  128. doAssert relativePath(Path"/Foo", Path"/foo", '/') == (when FileSystemCaseSensitive: Path"../Foo" else: Path".")
  129. doAssert relativePath(Path"/foo", Path"/fOO", '/') == (when FileSystemCaseSensitive: Path"../foo" else: Path".")
  130. doAssert relativePath(Path"/foO", Path"/foo", '/') == (when FileSystemCaseSensitive: Path"../foO" else: Path".")
  131. doAssert relativePath(Path"foo", Path".", '/') == Path"foo"
  132. doAssert relativePath(Path".", Path".", '/') == Path"."
  133. doAssert relativePath(Path"..", Path".", '/') == Path".."
  134. doAssert relativePath(Path"foo", Path"foo") == Path"."
  135. doAssert relativePath(Path"", Path"foo") == Path""
  136. doAssert relativePath(Path"././/foo", Path"foo//./") == Path"."
  137. doAssert relativePath(getCurrentDir() / Path"bar", Path"foo") == Path"../bar".unixToNativePath
  138. doAssert relativePath(Path"bar", getCurrentDir() / Path"foo") == Path"../bar".unixToNativePath
  139. when doslikeFileSystem:
  140. doAssert relativePath(r"c:\foo.nim".Path, r"C:\".Path) == r"foo.nim".Path
  141. doAssert relativePath(r"c:\foo\bar\baz.nim".Path, r"c:\foo".Path) == r"bar\baz.nim".Path
  142. doAssert relativePath(r"c:\foo\bar\baz.nim".Path, r"d:\foo".Path) == r"c:\foo\bar\baz.nim".Path
  143. doAssert relativePath(r"\foo\baz.nim".Path, r"\foo".Path) == r"baz.nim".Path
  144. doAssert relativePath(r"\foo\bar\baz.nim".Path, r"\bar".Path) == r"..\foo\bar\baz.nim".Path
  145. doAssert relativePath(r"\\foo\bar\baz.nim".Path, r"\\foo\bar".Path) == r"baz.nim".Path
  146. doAssert relativePath(r"\\foo\bar\baz.nim".Path, r"\\foO\bar".Path) == r"baz.nim".Path
  147. doAssert relativePath(r"\\foo\bar\baz.nim".Path, r"\\bar\bar".Path) == r"\\foo\bar\baz.nim".Path
  148. doAssert relativePath(r"\\foo\bar\baz.nim".Path, r"\\foo\car".Path) == r"\\foo\bar\baz.nim".Path
  149. doAssert relativePath(r"\\foo\bar\baz.nim".Path, r"\\goo\bar".Path) == r"\\foo\bar\baz.nim".Path
  150. doAssert relativePath(r"\\foo\bar\baz.nim".Path, r"c:\".Path) == r"\\foo\bar\baz.nim".Path
  151. doAssert relativePath(r"\\foo\bar\baz.nim".Path, r"\foo".Path) == r"\\foo\bar\baz.nim".Path
  152. doAssert relativePath(r"c:\foo.nim".Path, r"\foo".Path) == r"c:\foo.nim".Path
  153. doAssert joinPath(Path"usr", Path"") == unixToNativePath(Path"usr")
  154. doAssert joinPath(Path"usr", Path"") == (Path"usr").dup(add Path"")
  155. doAssert joinPath(Path"", Path"lib") == Path"lib"
  156. doAssert joinPath(Path"", Path"lib") == Path"".dup(add Path"lib")
  157. doAssert joinPath(Path"", Path"/lib") == unixToNativePath(Path"/lib")
  158. doAssert joinPath(Path"", Path"/lib") == unixToNativePath(Path"/lib")
  159. doAssert joinPath(Path"usr/", Path"/lib") == Path"usr/".dup(add Path"/lib")
  160. doAssert joinPath(Path"", Path"") == unixToNativePath(Path"") # issue #13455
  161. doAssert joinPath(Path"", Path"") == Path"".dup(add Path"")
  162. doAssert joinPath(Path"", Path"/") == unixToNativePath(Path"/")
  163. doAssert joinPath(Path"", Path"/") == Path"".dup(add Path"/")
  164. doAssert joinPath(Path"/", Path"/") == unixToNativePath(Path"/")
  165. doAssert joinPath(Path"/", Path"/") == Path"/".dup(add Path"/")
  166. doAssert joinPath(Path"/", Path"") == unixToNativePath(Path"/")
  167. doAssert joinPath(Path"/" / Path"") == unixToNativePath(Path"/") # weird test case...
  168. doAssert joinPath(Path"/", Path"/a/b/c") == unixToNativePath(Path"/a/b/c")
  169. doAssert joinPath(Path"foo/", Path"") == unixToNativePath(Path"foo/")
  170. doAssert joinPath(Path"foo/", Path"abc") == unixToNativePath(Path"foo/abc")
  171. doAssert joinPath(Path"foo//./", Path"abc/.//") == unixToNativePath(Path"foo/abc/")
  172. doAssert Path"foo//./".dup(add Path"abc/.//") == unixToNativePath(Path"foo/abc/")
  173. doAssert joinPath(Path"foo", Path"abc") == unixToNativePath(Path"foo/abc")
  174. doAssert Path"foo".dup(add Path"abc") == unixToNativePath(Path"foo/abc")
  175. doAssert joinPath(Path"", Path"abc") == unixToNativePath(Path"abc")
  176. doAssert joinPath(Path"zook/.", Path"abc") == unixToNativePath(Path"zook/abc")
  177. # controversial: inconsistent with `joinPath("zook/.","abc")`
  178. # on linux, `./foo` and `foo` are treated a bit differently for executables
  179. # but not `./foo/bar` and `foo/bar`
  180. doAssert joinPath(Path".", Path"/lib") == unixToNativePath(Path"./lib")
  181. doAssert joinPath(Path".", Path"abc") == unixToNativePath(Path"./abc")
  182. # cases related to issue #13455
  183. doAssert joinPath(Path"foo", Path"", Path"") == Path"foo"
  184. doAssert joinPath(Path"foo", Path"") == Path"foo"
  185. doAssert joinPath(Path"foo/", Path"") == unixToNativePath(Path"foo/")
  186. doAssert joinPath(Path"foo/", Path".") == Path"foo"
  187. doAssert joinPath(Path"foo", Path"./") == unixToNativePath(Path"foo/")
  188. doAssert joinPath(Path"foo", Path"", Path"bar/") == unixToNativePath(Path"foo/bar/")
  189. # issue #13579
  190. doAssert joinPath(Path"/foo", Path"../a") == unixToNativePath(Path"/a")
  191. doAssert joinPath(Path"/foo/", Path"../a") == unixToNativePath(Path"/a")
  192. doAssert joinPath(Path"/foo/.", Path"../a") == unixToNativePath(Path"/a")
  193. doAssert joinPath(Path"/foo/.b", Path"../a") == unixToNativePath(Path"/foo/a")
  194. doAssert joinPath(Path"/foo///", Path"..//a/") == unixToNativePath(Path"/a/")
  195. doAssert joinPath(Path"foo/", Path"../a") == unixToNativePath(Path"a")
  196. when doslikeFileSystem:
  197. doAssert joinPath(Path"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\Tools\\", Path"..\\..\\VC\\vcvarsall.bat") == r"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat".Path
  198. doAssert joinPath(Path"C:\\foo", Path"..\\a") == r"C:\a".Path
  199. doAssert joinPath(Path"C:\\foo\\", Path"..\\a") == r"C:\a".Path
  200. block: # bug #23663
  201. var s: HashSet[Path]
  202. s.incl("/a/b/c/..".Path)
  203. doAssert "/a/b/".Path in s
  204. doAssert "/a/b/c".Path notin s