tos.nim 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. discard """
  2. output: '''
  3. All:
  4. __really_obscure_dir_name/are.x
  5. __really_obscure_dir_name/created
  6. __really_obscure_dir_name/dirs
  7. __really_obscure_dir_name/files.q
  8. __really_obscure_dir_name/some
  9. __really_obscure_dir_name/test
  10. __really_obscure_dir_name/testing.r
  11. __really_obscure_dir_name/these.txt
  12. Files:
  13. __really_obscure_dir_name/are.x
  14. __really_obscure_dir_name/files.q
  15. __really_obscure_dir_name/testing.r
  16. __really_obscure_dir_name/these.txt
  17. Dirs:
  18. __really_obscure_dir_name/created
  19. __really_obscure_dir_name/dirs
  20. __really_obscure_dir_name/some
  21. __really_obscure_dir_name/test
  22. Raises
  23. Raises
  24. '''
  25. """
  26. # test os path creation, iteration, and deletion
  27. import os, strutils, pathnorm
  28. block fileOperations:
  29. let files = @["these.txt", "are.x", "testing.r", "files.q"]
  30. let dirs = @["some", "created", "test", "dirs"]
  31. let dname = "__really_obscure_dir_name"
  32. createDir(dname)
  33. doAssert dirExists(dname)
  34. block: # copyFile, copyFileToDir
  35. doAssertRaises(OSError): copyFile(dname/"nonexistant.txt", dname/"nonexistant.txt")
  36. let fname = "D20201009T112235"
  37. let fname2 = "D20201009T112235.2"
  38. writeFile(dname/fname, "foo")
  39. let sub = "sub"
  40. doAssertRaises(OSError): copyFile(dname/fname, dname/sub/fname2)
  41. doAssertRaises(OSError): copyFileToDir(dname/fname, dname/sub)
  42. doAssertRaises(ValueError): copyFileToDir(dname/fname, "")
  43. copyFile(dname/fname, dname/fname2)
  44. doAssert fileExists(dname/fname2)
  45. createDir(dname/sub)
  46. copyFileToDir(dname/fname, dname/sub)
  47. doAssert fileExists(dname/sub/fname)
  48. removeDir(dname/sub)
  49. doAssert not dirExists(dname/sub)
  50. removeFile(dname/fname)
  51. removeFile(dname/fname2)
  52. # Test creating files and dirs
  53. for dir in dirs:
  54. createDir(dname/dir)
  55. doAssert dirExists(dname/dir)
  56. for file in files:
  57. let fh = open(dname/file, fmReadWrite)
  58. fh.close()
  59. doAssert fileExists(dname/file)
  60. echo "All:"
  61. template norm(x): untyped =
  62. (when defined(windows): x.replace('\\', '/') else: x)
  63. for path in walkPattern(dname/"*"):
  64. echo path.norm
  65. echo "Files:"
  66. for path in walkFiles(dname/"*"):
  67. echo path.norm
  68. echo "Dirs:"
  69. for path in walkDirs(dname/"*"):
  70. echo path.norm
  71. # Test removal of files dirs
  72. for dir in dirs:
  73. removeDir(dname/dir)
  74. doAssert: not dirExists(dname/dir)
  75. for file in files:
  76. removeFile(dname/file)
  77. doAssert: not fileExists(dname/file)
  78. removeDir(dname)
  79. doAssert: not dirExists(dname)
  80. # createDir should create recursive directories
  81. createDir(dirs[0] / dirs[1])
  82. doAssert dirExists(dirs[0] / dirs[1]) # true
  83. removeDir(dirs[0])
  84. # createDir should properly handle trailing separator
  85. createDir(dname / "")
  86. doAssert dirExists(dname) # true
  87. removeDir(dname)
  88. # createDir should raise IOError if the path exists
  89. # and is not a directory
  90. open(dname, fmWrite).close
  91. try:
  92. createDir(dname)
  93. except IOError:
  94. echo "Raises"
  95. removeFile(dname)
  96. # removeFile should not remove directory
  97. createDir(dname)
  98. try:
  99. removeFile(dname)
  100. except OSError:
  101. echo "Raises"
  102. removeDir(dname)
  103. # test copyDir:
  104. createDir("a/b")
  105. open("a/b/file.txt", fmWrite).close
  106. createDir("a/b/c")
  107. open("a/b/c/fileC.txt", fmWrite).close
  108. copyDir("a", "../dest/a")
  109. removeDir("a")
  110. doAssert dirExists("../dest/a/b")
  111. doAssert fileExists("../dest/a/b/file.txt")
  112. doAssert fileExists("../dest/a/b/c/fileC.txt")
  113. removeDir("../dest")
  114. # test copyDir:
  115. # if separator at the end of a path
  116. createDir("a/b")
  117. open("a/file.txt", fmWrite).close
  118. copyDir("a/", "../dest/a/")
  119. removeDir("a")
  120. doAssert dirExists("../dest/a/b")
  121. doAssert fileExists("../dest/a/file.txt")
  122. removeDir("../dest")
  123. import times
  124. block modificationTime:
  125. # Test get/set modification times
  126. # Should support at least microsecond resolution
  127. let tm = fromUnix(0) + 100.microseconds
  128. writeFile("a", "")
  129. setLastModificationTime("a", tm)
  130. when defined(macosx):
  131. doAssert true
  132. else:
  133. doAssert getLastModificationTime("a") == tm
  134. removeFile("a")
  135. block walkDirRec:
  136. createDir("walkdir_test/a/b")
  137. open("walkdir_test/a/b/file_1", fmWrite).close()
  138. open("walkdir_test/a/file_2", fmWrite).close()
  139. for p in walkDirRec("walkdir_test"):
  140. doAssert p.fileExists
  141. doAssert p.startsWith("walkdir_test")
  142. var s: seq[string]
  143. for p in walkDirRec("walkdir_test", {pcFile}, {pcDir}, relative=true):
  144. s.add(p)
  145. doAssert s.len == 2
  146. doAssert "a" / "b" / "file_1" in s
  147. doAssert "a" / "file_2" in s
  148. removeDir("walkdir_test")
  149. block: # walkDir
  150. doAssertRaises(OSError):
  151. for a in walkDir("nonexistant", checkDir = true): discard
  152. doAssertRaises(OSError):
  153. for p in walkDirRec("nonexistant", checkDir = true): discard
  154. when not defined(windows):
  155. block walkDirRelative:
  156. createDir("walkdir_test")
  157. createSymlink(".", "walkdir_test/c")
  158. for k, p in walkDir("walkdir_test", true):
  159. doAssert k == pcLinkToDir
  160. removeDir("walkdir_test")
  161. block normalizedPath:
  162. doAssert normalizedPath("") == ""
  163. block relative:
  164. doAssert normalizedPath(".") == "."
  165. doAssert normalizedPath("foo/..") == "."
  166. doAssert normalizedPath("foo//../bar/.") == "bar"
  167. doAssert normalizedPath("..") == ".."
  168. doAssert normalizedPath("../") == ".."
  169. doAssert normalizedPath("../..") == unixToNativePath"../.."
  170. doAssert normalizedPath("../a/..") == ".."
  171. doAssert normalizedPath("../a/../") == ".."
  172. doAssert normalizedPath("./") == "."
  173. block absolute:
  174. doAssert normalizedPath("/") == unixToNativePath"/"
  175. doAssert normalizedPath("/.") == unixToNativePath"/"
  176. doAssert normalizedPath("/..") == unixToNativePath"/.."
  177. doAssert normalizedPath("/../") == unixToNativePath"/.."
  178. doAssert normalizedPath("/../..") == unixToNativePath"/../.."
  179. doAssert normalizedPath("/../../") == unixToNativePath"/../.."
  180. doAssert normalizedPath("/../../../") == unixToNativePath"/../../.."
  181. doAssert normalizedPath("/a/b/../../foo") == unixToNativePath"/foo"
  182. doAssert normalizedPath("/a/b/../../../foo") == unixToNativePath"/../foo"
  183. doAssert normalizedPath("/./") == unixToNativePath"/"
  184. doAssert normalizedPath("//") == unixToNativePath"/"
  185. doAssert normalizedPath("///") == unixToNativePath"/"
  186. doAssert normalizedPath("/a//b") == unixToNativePath"/a/b"
  187. doAssert normalizedPath("/a///b") == unixToNativePath"/a/b"
  188. doAssert normalizedPath("/a/b/c/..") == unixToNativePath"/a/b"
  189. doAssert normalizedPath("/a/b/c/../") == unixToNativePath"/a/b"
  190. block isHidden:
  191. when defined(posix):
  192. doAssert ".foo.txt".isHidden
  193. doAssert "bar/.foo.ext".isHidden
  194. doAssert not "bar".isHidden
  195. doAssert not "foo/".isHidden
  196. doAssert ".foo/.".isHidden
  197. # Corner cases: `isHidden` is not yet `..` aware
  198. doAssert not ".foo/..".isHidden
  199. block absolutePath:
  200. doAssertRaises(ValueError): discard absolutePath("a", "b")
  201. doAssert absolutePath("a") == getCurrentDir() / "a"
  202. doAssert absolutePath("a", "/b") == "/b" / "a"
  203. when defined(Posix):
  204. doAssert absolutePath("a", "/b/") == "/b" / "a"
  205. doAssert absolutePath("a", "/b/c") == "/b/c" / "a"
  206. doAssert absolutePath("/a", "b/") == "/a"
  207. block splitFile:
  208. doAssert splitFile("") == ("", "", "")
  209. doAssert splitFile("abc/") == ("abc", "", "")
  210. doAssert splitFile("/") == ("/", "", "")
  211. doAssert splitFile("./abc") == (".", "abc", "")
  212. doAssert splitFile(".txt") == ("", ".txt", "")
  213. doAssert splitFile("abc/.txt") == ("abc", ".txt", "")
  214. doAssert splitFile("abc") == ("", "abc", "")
  215. doAssert splitFile("abc.txt") == ("", "abc", ".txt")
  216. doAssert splitFile("/abc.txt") == ("/", "abc", ".txt")
  217. doAssert splitFile("/foo/abc.txt") == ("/foo", "abc", ".txt")
  218. doAssert splitFile("/foo/abc.txt.gz") == ("/foo", "abc.txt", ".gz")
  219. doAssert splitFile(".") == ("", ".", "")
  220. doAssert splitFile("abc/.") == ("abc", ".", "")
  221. doAssert splitFile("..") == ("", "..", "")
  222. doAssert splitFile("a/..") == ("a", "..", "")
  223. doAssert splitFile("/foo/abc....txt") == ("/foo", "abc...", ".txt")
  224. # execShellCmd is tested in tosproc
  225. block ospaths:
  226. doAssert unixToNativePath("") == ""
  227. doAssert unixToNativePath(".") == $CurDir
  228. doAssert unixToNativePath("..") == $ParDir
  229. doAssert isAbsolute(unixToNativePath("/"))
  230. doAssert isAbsolute(unixToNativePath("/", "a"))
  231. doAssert isAbsolute(unixToNativePath("/a"))
  232. doAssert isAbsolute(unixToNativePath("/a", "a"))
  233. doAssert isAbsolute(unixToNativePath("/a/b"))
  234. doAssert isAbsolute(unixToNativePath("/a/b", "a"))
  235. doAssert unixToNativePath("a/b") == joinPath("a", "b")
  236. when defined(macos):
  237. doAssert unixToNativePath("./") == ":"
  238. doAssert unixToNativePath("./abc") == ":abc"
  239. doAssert unixToNativePath("../abc") == "::abc"
  240. doAssert unixToNativePath("../../abc") == ":::abc"
  241. doAssert unixToNativePath("/abc", "a") == "abc"
  242. doAssert unixToNativePath("/abc/def", "a") == "abc:def"
  243. elif doslikeFileSystem:
  244. doAssert unixToNativePath("./") == ".\\"
  245. doAssert unixToNativePath("./abc") == ".\\abc"
  246. doAssert unixToNativePath("../abc") == "..\\abc"
  247. doAssert unixToNativePath("../../abc") == "..\\..\\abc"
  248. doAssert unixToNativePath("/abc", "a") == "a:\\abc"
  249. doAssert unixToNativePath("/abc/def", "a") == "a:\\abc\\def"
  250. else:
  251. #Tests for unix
  252. doAssert unixToNativePath("./") == "./"
  253. doAssert unixToNativePath("./abc") == "./abc"
  254. doAssert unixToNativePath("../abc") == "../abc"
  255. doAssert unixToNativePath("../../abc") == "../../abc"
  256. doAssert unixToNativePath("/abc", "a") == "/abc"
  257. doAssert unixToNativePath("/abc/def", "a") == "/abc/def"
  258. block extractFilenameTest:
  259. doAssert extractFilename("") == ""
  260. when defined(posix):
  261. doAssert extractFilename("foo/bar") == "bar"
  262. doAssert extractFilename("foo/bar.txt") == "bar.txt"
  263. doAssert extractFilename("foo/") == ""
  264. doAssert extractFilename("/") == ""
  265. when doslikeFileSystem:
  266. doAssert extractFilename(r"foo\bar") == "bar"
  267. doAssert extractFilename(r"foo\bar.txt") == "bar.txt"
  268. doAssert extractFilename(r"foo\") == ""
  269. doAssert extractFilename(r"C:\") == ""
  270. block lastPathPartTest:
  271. doAssert lastPathPart("") == ""
  272. when defined(posix):
  273. doAssert lastPathPart("foo/bar.txt") == "bar.txt"
  274. doAssert lastPathPart("foo/") == "foo"
  275. doAssert lastPathPart("/") == ""
  276. when doslikeFileSystem:
  277. doAssert lastPathPart(r"foo\bar.txt") == "bar.txt"
  278. doAssert lastPathPart(r"foo\") == "foo"
  279. template canon(x): untyped = normalizePath(x, '/')
  280. doAssert canon"/foo/../bar" == "/bar"
  281. doAssert canon"foo/../bar" == "bar"
  282. doAssert canon"/f/../bar///" == "/bar"
  283. doAssert canon"f/..////bar" == "bar"
  284. doAssert canon"../bar" == "../bar"
  285. doAssert canon"/../bar" == "/../bar"
  286. doAssert canon("foo/../../bar/") == "../bar"
  287. doAssert canon("./bla/blob/") == "bla/blob"
  288. doAssert canon(".hiddenFile") == ".hiddenFile"
  289. doAssert canon("./bla/../../blob/./zoo.nim") == "../blob/zoo.nim"
  290. doAssert canon("C:/file/to/this/long") == "C:/file/to/this/long"
  291. doAssert canon("") == ""
  292. doAssert canon("foobar") == "foobar"
  293. doAssert canon("f/////////") == "f"
  294. doAssert relativePath("/foo/bar//baz.nim", "/foo", '/') == "bar/baz.nim"
  295. doAssert normalizePath("./foo//bar/../baz", '/') == "foo/baz"
  296. doAssert relativePath("/Users/me/bar/z.nim", "/Users/other/bad", '/') == "../../me/bar/z.nim"
  297. doAssert relativePath("/Users/me/bar/z.nim", "/Users/other", '/') == "../me/bar/z.nim"
  298. doAssert relativePath("/Users///me/bar//z.nim", "//Users/", '/') == "me/bar/z.nim"
  299. doAssert relativePath("/Users/me/bar/z.nim", "/Users/me", '/') == "bar/z.nim"
  300. doAssert relativePath("", "/users/moo", '/') == ""
  301. doAssert relativePath("foo", "", '/') == "foo"
  302. doAssert relativePath("/foo", "/Foo", '/') == (when FileSystemCaseSensitive: "../foo" else: ".")
  303. doAssert relativePath("/Foo", "/foo", '/') == (when FileSystemCaseSensitive: "../Foo" else: ".")
  304. doAssert relativePath("/foo", "/fOO", '/') == (when FileSystemCaseSensitive: "../foo" else: ".")
  305. doAssert relativePath("/foO", "/foo", '/') == (when FileSystemCaseSensitive: "../foO" else: ".")
  306. doAssert relativePath("foo", ".", '/') == "foo"
  307. doAssert relativePath(".", ".", '/') == "."
  308. doAssert relativePath("..", ".", '/') == ".."
  309. doAssert relativePath("foo", "foo") == "."
  310. doAssert relativePath("", "foo") == ""
  311. doAssert relativePath("././/foo", "foo//./") == "."
  312. doAssert relativePath(getCurrentDir() / "bar", "foo") == "../bar".unixToNativePath
  313. doAssert relativePath("bar", getCurrentDir() / "foo") == "../bar".unixToNativePath
  314. when doslikeFileSystem:
  315. doAssert relativePath(r"c:\foo.nim", r"C:\") == r"foo.nim"
  316. doAssert relativePath(r"c:\foo\bar\baz.nim", r"c:\foo") == r"bar\baz.nim"
  317. doAssert relativePath(r"c:\foo\bar\baz.nim", r"d:\foo") == r"c:\foo\bar\baz.nim"
  318. doAssert relativePath(r"\foo\baz.nim", r"\foo") == r"baz.nim"
  319. doAssert relativePath(r"\foo\bar\baz.nim", r"\bar") == r"..\foo\bar\baz.nim"
  320. doAssert relativePath(r"\\foo\bar\baz.nim", r"\\foo\bar") == r"baz.nim"
  321. doAssert relativePath(r"\\foo\bar\baz.nim", r"\\foO\bar") == r"baz.nim"
  322. doAssert relativePath(r"\\foo\bar\baz.nim", r"\\bar\bar") == r"\\foo\bar\baz.nim"
  323. doAssert relativePath(r"\\foo\bar\baz.nim", r"\\foo\car") == r"\\foo\bar\baz.nim"
  324. doAssert relativePath(r"\\foo\bar\baz.nim", r"\\goo\bar") == r"\\foo\bar\baz.nim"
  325. doAssert relativePath(r"\\foo\bar\baz.nim", r"c:\") == r"\\foo\bar\baz.nim"
  326. doAssert relativePath(r"\\foo\bar\baz.nim", r"\foo") == r"\\foo\bar\baz.nim"
  327. doAssert relativePath(r"c:\foo.nim", r"\foo") == r"c:\foo.nim"
  328. doAssert joinPath("usr", "") == unixToNativePath"usr"
  329. doAssert joinPath("", "lib") == "lib"
  330. doAssert joinPath("", "/lib") == unixToNativePath"/lib"
  331. doAssert joinPath("usr/", "/lib") == unixToNativePath"usr/lib"
  332. doAssert joinPath("", "") == unixToNativePath"" # issue #13455
  333. doAssert joinPath("", "/") == unixToNativePath"/"
  334. doAssert joinPath("/", "/") == unixToNativePath"/"
  335. doAssert joinPath("/", "") == unixToNativePath"/"
  336. doAssert joinPath("/" / "") == unixToNativePath"/" # weird test case...
  337. doAssert joinPath("/", "/a/b/c") == unixToNativePath"/a/b/c"
  338. doAssert joinPath("foo/","") == unixToNativePath"foo/"
  339. doAssert joinPath("foo/","abc") == unixToNativePath"foo/abc"
  340. doAssert joinPath("foo//./","abc/.//") == unixToNativePath"foo/abc/"
  341. doAssert joinPath("foo","abc") == unixToNativePath"foo/abc"
  342. doAssert joinPath("","abc") == unixToNativePath"abc"
  343. doAssert joinPath("gook/.","abc") == unixToNativePath"gook/abc"
  344. # controversial: inconsistent with `joinPath("gook/.","abc")`
  345. # on linux, `./foo` and `foo` are treated a bit differently for executables
  346. # but not `./foo/bar` and `foo/bar`
  347. doAssert joinPath(".", "/lib") == unixToNativePath"./lib"
  348. doAssert joinPath(".","abc") == unixToNativePath"./abc"
  349. # cases related to issue #13455
  350. doAssert joinPath("foo", "", "") == "foo"
  351. doAssert joinPath("foo", "") == "foo"
  352. doAssert joinPath("foo/", "") == unixToNativePath"foo/"
  353. doAssert joinPath("foo/", ".") == "foo"
  354. doAssert joinPath("foo", "./") == unixToNativePath"foo/"
  355. doAssert joinPath("foo", "", "bar/") == unixToNativePath"foo/bar/"
  356. # issue #13579
  357. doAssert joinPath("/foo", "../a") == unixToNativePath"/a"
  358. doAssert joinPath("/foo/", "../a") == unixToNativePath"/a"
  359. doAssert joinPath("/foo/.", "../a") == unixToNativePath"/a"
  360. doAssert joinPath("/foo/.b", "../a") == unixToNativePath"/foo/a"
  361. doAssert joinPath("/foo///", "..//a/") == unixToNativePath"/a/"
  362. doAssert joinPath("foo/", "../a") == unixToNativePath"a"
  363. when doslikeFileSystem:
  364. doAssert joinPath("C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\Tools\\", "..\\..\\VC\\vcvarsall.bat") == r"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"
  365. doAssert joinPath("C:\\foo", "..\\a") == r"C:\a"
  366. doAssert joinPath("C:\\foo\\", "..\\a") == r"C:\a"
  367. block getTempDir:
  368. block TMPDIR:
  369. # TMPDIR env var is not used if either of these are defined.
  370. when not (defined(tempDir) or defined(windows) or defined(android)):
  371. if existsEnv("TMPDIR"):
  372. let origTmpDir = getEnv("TMPDIR")
  373. putEnv("TMPDIR", "/mytmp")
  374. doAssert getTempDir() == "/mytmp/"
  375. delEnv("TMPDIR")
  376. doAssert getTempDir() == "/tmp/"
  377. putEnv("TMPDIR", origTmpDir)
  378. else:
  379. doAssert getTempDir() == "/tmp/"
  380. block osenv:
  381. block delEnv:
  382. const dummyEnvVar = "DUMMY_ENV_VAR" # This env var wouldn't be likely to exist to begin with
  383. doAssert existsEnv(dummyEnvVar) == false
  384. putEnv(dummyEnvVar, "1")
  385. doAssert existsEnv(dummyEnvVar) == true
  386. delEnv(dummyEnvVar)
  387. doAssert existsEnv(dummyEnvVar) == false
  388. delEnv(dummyEnvVar) # deleting an already deleted env var
  389. doAssert existsEnv(dummyEnvVar) == false
  390. block isRelativeTo:
  391. doAssert isRelativeTo("/foo", "/")
  392. doAssert isRelativeTo("/foo/bar", "/foo")
  393. doAssert isRelativeTo("foo/bar", "foo")
  394. doAssert isRelativeTo("/foo/bar.nim", "/foo/bar.nim")
  395. doAssert isRelativeTo("./foo/", "foo")
  396. doAssert isRelativeTo("foo", "./foo/")
  397. doAssert isRelativeTo(".", ".")
  398. doAssert isRelativeTo("foo/bar", ".")
  399. doAssert not isRelativeTo("foo/bar.nims", "foo/bar.nim")
  400. doAssert not isRelativeTo("/foo2", "/foo")
  401. block: # quoteShellWindows
  402. assert quoteShellWindows("aaa") == "aaa"
  403. assert quoteShellWindows("aaa\"") == "aaa\\\""
  404. assert quoteShellWindows("") == "\"\""
  405. block: # quoteShellWindows
  406. assert quoteShellPosix("aaa") == "aaa"
  407. assert quoteShellPosix("aaa a") == "'aaa a'"
  408. assert quoteShellPosix("") == "''"
  409. assert quoteShellPosix("a'a") == "'a'\"'\"'a'"
  410. block: # quoteShell
  411. when defined(posix):
  412. assert quoteShell("") == "''"
  413. block: # normalizePathEnd
  414. # handle edge cases correctly: shouldn't affect whether path is
  415. # absolute/relative
  416. doAssert "".normalizePathEnd(true) == ""
  417. doAssert "".normalizePathEnd(false) == ""
  418. doAssert "/".normalizePathEnd(true) == $DirSep
  419. doAssert "/".normalizePathEnd(false) == $DirSep
  420. when defined(posix):
  421. doAssert "//".normalizePathEnd(false) == "/"
  422. doAssert "foo.bar//".normalizePathEnd == "foo.bar"
  423. doAssert "bar//".normalizePathEnd(trailingSep = true) == "bar/"
  424. when defined(Windows):
  425. doAssert r"C:\foo\\".normalizePathEnd == r"C:\foo"
  426. doAssert r"C:\foo".normalizePathEnd(trailingSep = true) == r"C:\foo\"
  427. # this one is controversial: we could argue for returning `D:\` instead,
  428. # but this is simplest.
  429. doAssert r"D:\".normalizePathEnd == r"D:"
  430. doAssert r"E:/".normalizePathEnd(trailingSep = true) == r"E:\"
  431. doAssert "/".normalizePathEnd == r"\"
  432. block: # isValidFilename
  433. # Negative Tests.
  434. doAssert not isValidFilename("abcd", maxLen = 2)
  435. doAssert not isValidFilename("0123456789", maxLen = 8)
  436. doAssert not isValidFilename("con")
  437. doAssert not isValidFilename("aux")
  438. doAssert not isValidFilename("prn")
  439. doAssert not isValidFilename("OwO|UwU")
  440. doAssert not isValidFilename(" foo")
  441. doAssert not isValidFilename("foo ")
  442. doAssert not isValidFilename("foo.")
  443. doAssert not isValidFilename("con.txt")
  444. doAssert not isValidFilename("aux.bat")
  445. doAssert not isValidFilename("prn.exe")
  446. doAssert not isValidFilename("nim>.nim")
  447. doAssert not isValidFilename(" foo.log")
  448. # Positive Tests.
  449. doAssert isValidFilename("abcd", maxLen = 42.Positive)
  450. doAssert isValidFilename("c0n")
  451. doAssert isValidFilename("foo.aux")
  452. doAssert isValidFilename("bar.prn")
  453. doAssert isValidFilename("OwO_UwU")
  454. doAssert isValidFilename("cron")
  455. doAssert isValidFilename("ux.bat")
  456. doAssert isValidFilename("nim.nim")
  457. doAssert isValidFilename("foo.log")
  458. import sugar
  459. block: # normalizeExe
  460. doAssert "".dup(normalizeExe) == ""
  461. when defined(posix):
  462. doAssert "foo".dup(normalizeExe) == "./foo"
  463. doAssert "foo/../bar".dup(normalizeExe) == "foo/../bar"
  464. when defined(windows):
  465. doAssert "foo".dup(normalizeExe) == "foo"