diff --git a/lib/pure/os.nim b/lib/pure/os.nim index a9183e1fad..0e9610fe0c 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -875,8 +875,9 @@ iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path: var y = $x.d_name.cstring if y != "." and y != "..": var s: Stat + let path = dir / y if not relative: - y = dir / y + y = path var k = pcFile when defined(linux) or defined(macosx) or @@ -884,16 +885,16 @@ iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path: if x.d_type != DT_UNKNOWN: if x.d_type == DT_DIR: k = pcDir if x.d_type == DT_LNK: - if dirExists(y): k = pcLinkToDir + if dirExists(path): k = pcLinkToDir else: k = pcLinkToFile yield (k, y) continue - if lstat(y, s) < 0'i32: break + if lstat(path, s) < 0'i32: break if S_ISDIR(s.st_mode): k = pcDir elif S_ISLNK(s.st_mode): - k = getSymlinkFileKind(y) + k = getSymlinkFileKind(path) yield (k, y) iterator walkDirRec*(dir: string, yieldFilter = {pcFile}, diff --git a/tests/stdlib/tos.nim b/tests/stdlib/tos.nim index 2c0db69539..a8a6d1df8e 100644 --- a/tests/stdlib/tos.nim +++ b/tests/stdlib/tos.nim @@ -149,72 +149,109 @@ removeDir("../dest") # Test get/set modification times # Should support at least microsecond resolution import times -let tm = fromUnix(0) + 100.microseconds -writeFile("a", "") -setLastModificationTime("a", tm) +block modificationTime: + # Test get/set modification times + # Should support at least microsecond resolution + let tm = fromUnix(0) + 100.microseconds + writeFile("a", "") + setLastModificationTime("a", tm) -when defined(macosx): - echo "true" -else: - echo getLastModificationTime("a") == tm -removeFile("a") + when defined(macosx): + echo "true" + else: + echo getLastModificationTime("a") == tm + removeFile("a") -when defined(posix): +block walkDirRec: + createDir("walkdir_test/a/b") + open("walkdir_test/a/b/file_1", fmWrite).close() + open("walkdir_test/a/file_2", fmWrite).close() - block normalizedPath: - block relative: - doAssert normalizedPath(".") == "." - doAssert normalizedPath("..") == ".." - doAssert normalizedPath("../") == ".." - doAssert normalizedPath("../..") == "../.." - doAssert normalizedPath("../a/..") == ".." - doAssert normalizedPath("../a/../") == ".." - doAssert normalizedPath("./") == "." + for p in walkDirRec("walkdir_test"): + doAssert p.fileExists + doAssert p.startsWith("walkdir_test") - block absolute: - doAssert normalizedPath("/") == "/" - doAssert normalizedPath("/.") == "/" - doAssert normalizedPath("/..") == "/" - doAssert normalizedPath("/../") == "/" - doAssert normalizedPath("/../..") == "/" - doAssert normalizedPath("/../../") == "/" - doAssert normalizedPath("/../../../") == "/" - doAssert normalizedPath("/a/b/../../foo") == "/foo" - doAssert normalizedPath("/a/b/../../../foo") == "/foo" - doAssert normalizedPath("/./") == "/" - doAssert normalizedPath("//") == "/" - doAssert normalizedPath("///") == "/" - doAssert normalizedPath("/a//b") == "/a/b" - doAssert normalizedPath("/a///b") == "/a/b" - doAssert normalizedPath("/a/b/c/..") == "/a/b" - doAssert normalizedPath("/a/b/c/../") == "/a/b" + var s: seq[string] + for p in walkDirRec("walkdir_test", {pcFile}, {pcDir}, relative=true): + s.add(p) -else: + doAssert s.len == 2 + doAssert "a" / "b" / "file_1" in s + doAssert "a" / "file_2" in s - block normalizedPath: - block relative: - doAssert normalizedPath(".") == "." - doAssert normalizedPath("..") == ".." - doAssert normalizedPath("..\\") == ".." - doAssert normalizedPath("..\\..") == "..\\.." - doAssert normalizedPath("..\\a\\..") == ".." - doAssert normalizedPath("..\\a\\..\\") == ".." - doAssert normalizedPath(".\\") == "." + removeDir("walkdir_test") - block absolute: - doAssert normalizedPath("\\") == "\\" - doAssert normalizedPath("\\.") == "\\" - doAssert normalizedPath("\\..") == "\\" - doAssert normalizedPath("\\..\\") == "\\" - doAssert normalizedPath("\\..\\..") == "\\" - doAssert normalizedPath("\\..\\..\\") == "\\" - doAssert normalizedPath("\\..\\..\\..\\") == "\\" - doAssert normalizedPath("\\a\\b\\..\\..\\foo") == "\\foo" - doAssert normalizedPath("\\a\\b\\..\\..\\..\\foo") == "\\foo" - doAssert normalizedPath("\\.\\") == "\\" - doAssert normalizedPath("\\\\") == "\\" - doAssert normalizedPath("\\\\\\") == "\\" - doAssert normalizedPath("\\a\\\\b") == "\\a\\b" - doAssert normalizedPath("\\a\\\\\\b") == "\\a\\b" - doAssert normalizedPath("\\a\\b\\c\\..") == "\\a\\b" - doAssert normalizedPath("\\a\\b\\c\\..\\") == "\\a\\b" +when not defined(windows): + block walkDirRelative: + createDir("walkdir_test") + createSymlink(".", "walkdir_test/c") + for k, p in walkDir("walkdir_test", true): + doAssert k == pcLinkToDir + removeDir("walkdir_test") + +block normalizedPath: + doAssert normalizedPath("") == "" + block relative: + doAssert normalizedPath(".") == "." + doAssert normalizedPath("foo/..") == "." + doAssert normalizedPath("foo//../bar/.") == "bar" + doAssert normalizedPath("..") == ".." + doAssert normalizedPath("../") == ".." + doAssert normalizedPath("../..") == unixToNativePath"../.." + doAssert normalizedPath("../a/..") == ".." + doAssert normalizedPath("../a/../") == ".." + doAssert normalizedPath("./") == "." + + block absolute: + doAssert normalizedPath("/") == unixToNativePath"/" + doAssert normalizedPath("/.") == unixToNativePath"/" + doAssert normalizedPath("/..") == unixToNativePath"/.." + doAssert normalizedPath("/../") == unixToNativePath"/.." + doAssert normalizedPath("/../..") == unixToNativePath"/../.." + doAssert normalizedPath("/../../") == unixToNativePath"/../.." + doAssert normalizedPath("/../../../") == unixToNativePath"/../../.." + doAssert normalizedPath("/a/b/../../foo") == unixToNativePath"/foo" + doAssert normalizedPath("/a/b/../../../foo") == unixToNativePath"/../foo" + doAssert normalizedPath("/./") == unixToNativePath"/" + doAssert normalizedPath("//") == unixToNativePath"/" + doAssert normalizedPath("///") == unixToNativePath"/" + doAssert normalizedPath("/a//b") == unixToNativePath"/a/b" + doAssert normalizedPath("/a///b") == unixToNativePath"/a/b" + doAssert normalizedPath("/a/b/c/..") == unixToNativePath"/a/b" + doAssert normalizedPath("/a/b/c/../") == unixToNativePath"/a/b" + +block isHidden: + when defined(posix): + doAssert ".foo.txt".isHidden + doAssert "bar/.foo.ext".isHidden + doAssert: not "bar".isHidden + doAssert: not "foo/".isHidden + # Corner cases: paths are not normalized when determining `isHidden` + doAssert: not ".foo/.".isHidden + doAssert: not ".foo/..".isHidden + +block absolutePath: + doAssertRaises(ValueError): discard absolutePath("a", "b") + doAssert absolutePath("a") == getCurrentDir() / "a" + doAssert absolutePath("a", "/b") == "/b" / "a" + when defined(Posix): + doAssert absolutePath("a", "/b/") == "/b" / "a" + doAssert absolutePath("a", "/b/c") == "/b/c" / "a" + doAssert absolutePath("/a", "b/") == "/a" + +block splitFile: + doAssert splitFile("") == ("", "", "") + doAssert splitFile("abc/") == ("abc", "", "") + doAssert splitFile("/") == ("/", "", "") + doAssert splitFile("./abc") == (".", "abc", "") + doAssert splitFile(".txt") == ("", ".txt", "") + doAssert splitFile("abc/.txt") == ("abc", ".txt", "") + doAssert splitFile("abc") == ("", "abc", "") + doAssert splitFile("abc.txt") == ("", "abc", ".txt") + doAssert splitFile("/abc.txt") == ("/", "abc", ".txt") + doAssert splitFile("/foo/abc.txt") == ("/foo", "abc", ".txt") + doAssert splitFile("/foo/abc.txt.gz") == ("/foo", "abc.txt", ".gz") + doAssert splitFile(".") == ("", ".", "") + doAssert splitFile("abc/.") == ("abc", ".", "") + doAssert splitFile("..") == ("", "..", "") + doAssert splitFile("a/..") == ("a", "..", "")