mirror of
https://github.com/JuliaLang/julia.git
synced 2026-05-28 03:10:33 +08:00
- path: add homedir(username) method for looking up other users' home dirs - path: overhaul expanduser and contractuser for cross-platform support - REPL: unify shell mode and backtick command completion escaping - shell: expand tildes in backtick commands with REPL completion support
496 lines
26 KiB
Julia
496 lines
26 KiB
Julia
# This file is a part of Julia. License is MIT: https://julialang.org/license
|
||
using Random: randstring
|
||
isdefined(Main, :samepath) || @eval Main include("testhelpers/samepath.jl")
|
||
using Main: samepath
|
||
|
||
@testset "basic path functions for $S" for S in (String, SubString, GenericString)
|
||
dir = pwd()
|
||
sep = Base.Filesystem.path_separator
|
||
@testset "isabspath and abspath" begin
|
||
@test abspath(S("foo")) == "$dir$(sep)foo"
|
||
@test abspath(S("foo"), S("bar")) == "$dir$(sep)foo$(sep)bar"
|
||
@test isabspath(S(homedir()))
|
||
@test !isabspath(S("foo"))
|
||
end
|
||
if Sys.iswindows()
|
||
@testset "issue #38491" begin
|
||
pwd_drive = uppercase(splitdrive(pwd())[1])
|
||
drive = (pwd_drive == "X:") ? "Y:" : "X:"
|
||
@test abspath("$(lowercase(drive))a\\b\\c") == "$(lowercase(drive))\\a\\b\\c"
|
||
@test abspath("$(uppercase(drive))a\\b\\c") == "$(uppercase(drive))\\a\\b\\c"
|
||
@test abspath("$(lowercase(drive))a") == "$(lowercase(drive))\\a"
|
||
@test abspath("$(uppercase(drive))a") == "$(uppercase(drive))\\a"
|
||
@test abspath(lowercase(drive)) == "$(lowercase(drive))\\"
|
||
@test abspath(uppercase(drive)) == "$(uppercase(drive))\\"
|
||
|
||
@test lowercase(abspath("$(pwd_drive)a\\b\\c")) == lowercase(joinpath(pwd(), "a\\b\\c"))
|
||
@test lowercase(abspath("$(pwd_drive)a")) == lowercase(joinpath(pwd(), "a"))
|
||
@test lowercase(abspath(lowercase(pwd_drive))) == lowercase("$(pwd())\\")
|
||
@test lowercase(abspath(uppercase(pwd_drive))) == lowercase("$(pwd())\\")
|
||
end
|
||
end
|
||
@test basename(S("foo$(sep)bar")) == "bar"
|
||
@test dirname(S("foo$(sep)bar")) == "foo"
|
||
|
||
@testset "expanduser" begin
|
||
@test expanduser(S("")) == ""
|
||
@test expanduser(S("x")) == "x"
|
||
@test expanduser(S("~")) == homedir()
|
||
@test expanduser(S("~$(Base.Filesystem.path_separator)foo")) == joinpath(homedir(), "foo")
|
||
if Sys.iswindows()
|
||
# expanduser preserves the separator from the input path
|
||
home = homedir()
|
||
@test expanduser(S("~/foo")) == replace(home, '\\' => '/') * "/foo"
|
||
@test expanduser(S("~\\foo")) == replace(home, '/' => '\\') * "\\foo"
|
||
end
|
||
if !Sys.iswindows()
|
||
# ~username expansion (Unix only)
|
||
me = Sys.username()
|
||
@test samepath(expanduser(S("~$me")), homedir(me))
|
||
@test samepath(expanduser(S("~$me/bar")), joinpath(homedir(me), "bar"))
|
||
# unknown user is left unexpanded
|
||
nouser = "nouser_" * randstring(12)
|
||
@test expanduser(S("~$nouser")) == "~$nouser"
|
||
end
|
||
end
|
||
@testset "contractuser" begin
|
||
# contractuser is left-inverse of expanduser
|
||
@test contractuser(S(homedir())) == "~"
|
||
@test contractuser(S(joinpath(homedir(), "x"))) == "~$(sep)x"
|
||
if !Sys.iswindows()
|
||
@test contractuser(S("/foo/bar")) == "/foo/bar"
|
||
me = Sys.username()
|
||
# current user's home contracts to ~ or ~username via stat
|
||
result = contractuser(S(homedir()))
|
||
@test result == "~" || result == "~$me"
|
||
end
|
||
# round-trip: expanduser(contractuser(p)) == p for home-relative paths
|
||
p = joinpath(homedir(), "some", "path")
|
||
@test expanduser(contractuser(S(p))) == p
|
||
end
|
||
@testset "isdirpath" begin
|
||
@test !isdirpath(S("foo"))
|
||
@test isdirpath(S("foo$sep"))
|
||
@test isdirpath(S(""))
|
||
@test isdirpath(S("."))
|
||
@test isdirpath(S(".."))
|
||
|
||
# After https://github.com/JuliaLang/julia/pull/60677, paths
|
||
# with "\n", ".\n" or "..\n" after the last separator are
|
||
# not accepted as directories.
|
||
@test !isdirpath("\n")
|
||
@test !isdirpath(".\n")
|
||
@test !isdirpath("..\n")
|
||
@test !isdirpath("a/\n")
|
||
@test !isdirpath("a/.\n")
|
||
@test !isdirpath("a/..\n")
|
||
end
|
||
@testset "joinpath" begin
|
||
@test joinpath(S("")) == ""
|
||
@test joinpath(S("foo")) == "foo"
|
||
@test joinpath(S("foo"), S("bar")) == "foo$(sep)bar"
|
||
@test joinpath(S("foo"), S("bar"), S("baz")) == "foo$(sep)bar$(sep)baz"
|
||
@test joinpath(S("foo"), S(""), S("baz")) == "foo$(sep)baz"
|
||
@test joinpath(S("foo"), S(""), S("")) == "foo$(sep)"
|
||
@test joinpath(S("foo"), S(""), S(""), S("bar")) == "foo$(sep)bar"
|
||
|
||
@test joinpath(S("foo"), S(homedir())) == homedir()
|
||
@test joinpath(S(abspath("foo")), S(homedir())) == homedir()
|
||
|
||
for str in map(S, [sep, "a$(sep)b", "a$(sep)b$(sep)c", "a$(sep)b$(sep)c$(sep)d"])
|
||
@test str == joinpath(splitpath(str))
|
||
@test joinpath(splitpath(str)) == joinpath(splitpath(str)...)
|
||
end
|
||
|
||
if Sys.iswindows()
|
||
@test joinpath(S("foo"),S("D:bar")) == "D:bar"
|
||
@test joinpath(S("C:"),S("foo"),S("D:"),S("bar")) == "D:bar"
|
||
@test joinpath(S("C:"),S("foo"),S("D:bar"),S("baz")) == "D:bar$(sep)baz"
|
||
|
||
# relative folders and case-insensitive drive letters
|
||
@test joinpath(S("C:\\a\\b"), S("c:c\\e")) == "C:\\a\\b\\c\\e"
|
||
|
||
# UNC paths
|
||
@test joinpath(S("\\\\server"), S("share")) == "\\\\server\\share"
|
||
@test joinpath(S("\\\\server"), S("share"), S("a")) == "\\\\server\\share\\a"
|
||
@test joinpath(S("\\\\server\\"), S("share"), S("a")) == "\\\\server\\share\\a"
|
||
@test joinpath(S("\\\\server"), S("share"), S("a"), S("b")) == "\\\\server\\share\\a\\b"
|
||
@test joinpath(S("\\\\server\\share"),S("a")) == "\\\\server\\share\\a"
|
||
@test joinpath(S("\\\\server\\share\\"), S("a")) == "\\\\server\\share\\a"
|
||
|
||
for str in map(S, ["c:\\", "c:\\a", "c:\\a\\b", "c:\\a\\b\\c", "c:\\a\\b\\c\\d"])
|
||
@test str == joinpath(splitpath(str))
|
||
@test joinpath(splitpath(str)) == joinpath(splitpath(str)...)
|
||
end
|
||
|
||
elseif Sys.isunix()
|
||
@test joinpath(S("foo"),S("bar:baz")) == "foo$(sep)bar:baz"
|
||
@test joinpath(S("C:"),S("foo"),S("D:"),S("bar")) == "C:$(sep)foo$(sep)D:$(sep)bar"
|
||
@test joinpath(S("C:"),S("foo"),S("D:"),S("bar"),S("baz")) == "C:$(sep)foo$(sep)D:$(sep)bar$(sep)baz"
|
||
end
|
||
end
|
||
@testset "normpath" begin
|
||
@test normpath(S(joinpath("."))) == "."
|
||
@test normpath(S(joinpath(".."))) == ".."
|
||
@test normpath(S(joinpath("..","."))) == ".."
|
||
@test normpath(S(joinpath(".",".."))) == ".."
|
||
@test normpath(S(joinpath("..",".."))) == "..$(sep).."
|
||
@test normpath(S(joinpath(".","..",".."))) == "..$(sep).."
|
||
@test normpath(S(joinpath("..",".",".."))) == "..$(sep).."
|
||
@test normpath(S(joinpath("..","..","."))) == "..$(sep).."
|
||
|
||
@test normpath(S(joinpath("foo","."))) == "foo$sep"
|
||
@test normpath(S(joinpath("foo",".."))) == "."
|
||
@test normpath(S(joinpath("foo","..","."))) == "."
|
||
@test normpath(S(joinpath("foo",".",".."))) == "."
|
||
@test normpath(S(joinpath("foo","..",".."))) == ".."
|
||
@test normpath(S(joinpath("foo",".","..",".."))) == ".."
|
||
@test normpath(S(joinpath("foo","..",".",".."))) == ".."
|
||
@test normpath(S(joinpath("foo","..","..","."))) == ".."
|
||
|
||
@test normpath(S(joinpath(".","bar"))) == "bar"
|
||
@test normpath(S(joinpath("..","bar"))) == "..$(sep)bar"
|
||
@test normpath(S(joinpath("..",".","bar"))) == "..$(sep)bar"
|
||
@test normpath(S(joinpath(".","..","bar"))) == "..$(sep)bar"
|
||
@test normpath(S(joinpath("..","..","bar"))) == "..$(sep)..$(sep)bar"
|
||
@test normpath(S(joinpath(".","..","..","bar"))) == "..$(sep)..$(sep)bar"
|
||
@test normpath(S(joinpath("..",".","..","bar"))) == "..$(sep)..$(sep)bar"
|
||
@test normpath(S(joinpath("..","..",".","bar"))) == "..$(sep)..$(sep)bar"
|
||
|
||
@test normpath(S(joinpath("foo",".","bar"))) == "foo$(sep)bar"
|
||
@test normpath(S(joinpath("foo","..","bar"))) == "bar"
|
||
@test normpath(S(joinpath("foo","..",".","bar"))) == "bar"
|
||
@test normpath(S(joinpath("foo",".","..","bar"))) == "bar"
|
||
@test normpath(S(joinpath("foo","..","..","bar"))) == "..$(sep)bar"
|
||
@test normpath(S(joinpath("foo",".","..","..","bar"))) == "..$(sep)bar"
|
||
@test normpath(S(joinpath("foo","..",".","..","bar"))) == "..$(sep)bar"
|
||
@test normpath(S(joinpath("foo","..","..",".","bar"))) == "..$(sep)bar"
|
||
@test normpath(normpath(S(joinpath("a", "..", "b", ".", "c")))) == normpath(S(joinpath("a", "..", "b", ".", "c")))
|
||
end
|
||
@test relpath(S(joinpath("foo","bar")), S("foo")) == "bar"
|
||
|
||
@testset "splitpath" begin
|
||
@test splitpath(S(joinpath("a","b","c"))) == ["a", "b", "c"]
|
||
@test splitpath("") == [""]
|
||
|
||
@test splitpath(S(joinpath("cats are", "gr8t"))) == ["cats are", "gr8t"]
|
||
@test splitpath(S(joinpath(" ", " "))) == [" ", " "]
|
||
|
||
# Unix-style paths are understood by all systems.
|
||
@test splitpath(S("/a/b")) == ["/", "a", "b"]
|
||
@test splitpath(S("/")) == ["/"]
|
||
@test splitpath(S("a/")) == ["a"]
|
||
@test splitpath(S("a/b/")) == ["a", "b"]
|
||
@test splitpath(S("a.dir/b.txt")) == ["a.dir", "b.txt"]
|
||
@test splitpath(S("///")) == ["/"]
|
||
@test splitpath(S("///a///b///")) == ["/", "a", "b"]
|
||
|
||
if Sys.iswindows()
|
||
@test splitpath(S("C:\\\\a\\b\\c")) == ["C:\\", "a", "b", "c"]
|
||
@test splitpath(S("C:\\\\")) == ["C:\\"]
|
||
@test splitpath(S("J:\\")) == ["J:\\"]
|
||
@test splitpath(S("C:")) == ["C:"]
|
||
@test splitpath(S("C:a")) == ["C:a"]
|
||
@test splitpath(S("C:a\\b")) == ["C:a", "b"]
|
||
|
||
@test splitpath(S("a\\")) == ["a"]
|
||
@test splitpath(S("a\\\\b\\\\")) == ["a","b"]
|
||
@test splitpath(S("a.dir\\b.txt")) == ["a.dir", "b.txt"]
|
||
@test splitpath(S("\\a\\b\\")) == ["\\", "a","b"]
|
||
@test splitpath(S("\\\\a\\b")) == ["\\\\a\\b"] # This is actually a valid drive name in windows.
|
||
|
||
@test splitpath(S("/a/b\\c/d\\\\e")) == ["/", "a", "b", "c", "d", "e"]
|
||
@test splitpath(S("/\\/\\")) == ["/"]
|
||
@test splitpath(S("\\/\\a/\\//b")) == ["\\","a","b"]
|
||
end
|
||
end
|
||
|
||
@testset "splitdir, splitdrive, splitext" begin
|
||
@test joinpath(splitdir(S(homedir()))...) == homedir()
|
||
@test string(splitdrive(S(homedir()))...) == homedir()
|
||
@test splitdrive("a\nb") == ("", "a\nb")
|
||
|
||
@test splitdir("a/\xfe/\n/b/c.ext") == ("a/\xfe/\n/b", "c.ext")
|
||
@test splitext("a/\xfe/\n/b/c.ext") == ("a/\xfe/\n/b/c", ".ext")
|
||
|
||
if Sys.iswindows()
|
||
@test splitdrive(S("\\\\servername\\hello.world\\filename.ext")) ==
|
||
("\\\\servername\\hello.world","\\filename.ext")
|
||
@test splitdrive(S("\\\\servername.com\\hello.world\\filename.ext")) ==
|
||
("\\\\servername.com\\hello.world","\\filename.ext")
|
||
@test splitdrive(S("C:\\foo\\bar")) ==
|
||
("C:","\\foo\\bar")
|
||
# only single characters followed by a colon are drives
|
||
@test splitdrive(S("foo:bar")) ==
|
||
("", "foo:bar")
|
||
|
||
# unicode
|
||
@test splitdrive(S("\\\\α\\β\\γ")) == ("\\\\α\\β", "\\γ")
|
||
@test splitdrive(S("\\\\?\\UNC\\α\\β\\γ")) == ("\\\\?\\UNC\\α\\β", "\\γ")
|
||
|
||
# splitdrive currently allows any single codeunit char except separators as drive letters
|
||
# while isabspath does not allow this. FIXME?
|
||
@test splitdrive(S("::")) == ("::", "")
|
||
@test splitdrive(S("🍎:")) != ("🍎:", "")
|
||
# The behavior is different for long baths, where he drive letter can
|
||
# contain multiple codeunits (such as unicode chars or multiple chars)
|
||
# if it is followed by a delimiter, because it is then captured as a
|
||
# UNC path with the server name ?. FIXME?
|
||
@test splitdrive(S("\\\\?\\🍎:\\foobar")) == ("\\\\?\\🍎:", "\\foobar")
|
||
@test splitdrive(S("\\\\?\\CC:\\foobar")) == ("\\\\?\\CC:", "\\foobar")
|
||
# If the path contains no delimiters after the path however,
|
||
# everything goes into the drive
|
||
@test splitdrive("\\\\?\\🍎:foobar") == ("\\\\?\\🍎:foobar", "")
|
||
end
|
||
|
||
@test splitdir(S("foo")) == ("", "foo")
|
||
@test splitdir(S("foo/")) == ("foo", "")
|
||
@test splitdir(S("/foo")) == ("/", "foo")
|
||
@test splitdir(S("/foo/")) == ("/foo", "")
|
||
@test splitdir(S("foo/bar")) == ("foo", "bar")
|
||
@test splitdir(S("/foo/bar")) == ("/foo", "bar")
|
||
@test splitdir(S("/foo/bar/")) == ("/foo/bar", "")
|
||
@test splitdir(S("/foo/bar/baz")) == ("/foo/bar", "baz")
|
||
@test splitdir(S("/foo/bar/baz/")) == ("/foo/bar/baz", "")
|
||
@test splitdir(S("foo/bar/baz/")) == ("foo/bar/baz", "")
|
||
# Multiple leading separators are reduced to one only when
|
||
# all separators are at the beginning. FIXME?
|
||
@test splitdir(S("///foo")) == ("/", "foo") # why not ("///", "foo") ?
|
||
@test splitdir(S("///foo/bar")) == ("///foo", "bar")
|
||
if Sys.iswindows()
|
||
@test splitdir(S("/\\foo")) == ("/", "foo") # why not ("/\\", "foo") ?
|
||
@test splitdir(S("\\/foo")) == ("\\", "foo") # why not ("\\/", "foo") ?
|
||
@test splitdir(S("/\\/foo/bar")) == ("/\\/foo", "bar")
|
||
@test splitdir(S("///foo/bar/")) == ("///foo/bar", "")
|
||
@test splitdir(S("C:")) == ("C:", "")
|
||
@test splitdir(S("C:\\")) == ("C:\\", "")
|
||
@test splitdir(S("C:\\foo")) == ("C:\\", "foo")
|
||
@test splitdir(S("C:\\foo\\bar")) == ("C:\\foo", "bar")
|
||
@test splitdir(S("\\\\?\\C:\\foo\\bar")) == ("\\\\?\\C:\\foo", "bar")
|
||
@test splitdir(S("\\\\?\\C:\\foo\\bar\\")) == ("\\\\?\\C:\\foo\\bar", "")
|
||
end
|
||
|
||
@test splitext(S("")) == ("", "")
|
||
@test splitext(S(".")) == (".", "")
|
||
@test_broken splitext(S("..")) == ("..", "")
|
||
@test_broken splitext(S("...")) == ("...", "")
|
||
@test splitext(S("foo")) == ("foo", "")
|
||
@test splitext(S("foo.")) == ("foo", ".")
|
||
@test_broken splitext(S("foo..")) == ("foo", "..")
|
||
@test_broken splitext(S("foo...")) == ("foo", "...")
|
||
@test splitext(S("foo.bar")) == ("foo", ".bar")
|
||
@test splitext(S(".foo")) == (".foo", "")
|
||
@test splitext(S(".foo.")) == (".foo", ".")
|
||
@test_broken splitext(S(".foo..")) == (".foo", "..")
|
||
@test_broken splitext(S(".foo...")) == (".foo", "...")
|
||
@test splitext(S(".foo.bar")) == (".foo", ".bar")
|
||
@test splitext(S("bar/.foo/baz")) == ("bar/.foo/baz", "")
|
||
@test splitext(S("bar/foo/.baz")) == ("bar/foo/.baz", "")
|
||
@test splitext(S("bar/foo.baz")) == ("bar/foo", ".baz")
|
||
|
||
# Before merging https://github.com/JuliaLang/julia/pull/60677,
|
||
# a single \n would be removed from the first output unless that made
|
||
# it empty or end with a separator. The tests below reflect the
|
||
# updated behavior.
|
||
@test splitext(S("a\r\n")) == ("a\r\n", "")
|
||
@test splitext(S("a/\n")) == ("a/\n", "") # not changed by 60677
|
||
@test splitext(S("a\n.foo")) == ("a\n", ".foo")
|
||
@test splitext(S("a/\n.foo")) == ("a/\n", ".foo")
|
||
@test splitext(S("\n")) == ("\n", "") # not changed by 60677
|
||
if Sys.iswindows()
|
||
@test splitext(S("C:a\n")) == ("C:a\n", "")
|
||
@test splitext(S("C:\n")) == ("C:\n", "") # not changed by 60677
|
||
end
|
||
end
|
||
|
||
@testset "isabspath" begin
|
||
@test isabspath(S("~")) == false
|
||
@test isabspath(S("/")) == true # on windows, this is relatively absolute
|
||
@test isabspath(S("A:/")) == Sys.iswindows()
|
||
@test isabspath(S("B:\\")) == Sys.iswindows()
|
||
@test isabspath(S("./")) == false
|
||
@test isabspath(S("C:")) == false
|
||
@test isabspath(S("C:.")) == false
|
||
@test isabspath(S("α:/")) == false
|
||
@test isabspath(S(".:/")) == false
|
||
#@test isabspath(S("_:/")) == false # FIXME?
|
||
#@test isabspath(S("AB:/")) == false # FIXME?
|
||
@test isabspath(S("\\\\")) == Sys.iswindows()
|
||
@test isabspath(S(expanduser("~"))) == true
|
||
@test startswith(expanduser(S("~")), homedir())
|
||
if Sys.iswindows()
|
||
@test isabspath(S("\\\\?\\C:\\"))
|
||
# Current behavior is to allow anything starting with a separator,
|
||
# even if this is not a long path, nor a UNC path.
|
||
@test isabspath(S("///a/b/"))
|
||
# Drive letters are currently treated differently in long path format. FIXME?
|
||
@test isabspath(S("\\\\?\\α:\\")) != isabspath("α:\\")
|
||
end
|
||
end
|
||
|
||
@testset "relpath" begin
|
||
function test_relpath()
|
||
sep = Base.Filesystem.path_separator
|
||
filepaths = [
|
||
"$(sep)home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
|
||
"$(sep)home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
|
||
"$(sep)home$(sep)user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
|
||
"$(sep)home$(sep)user$(sep)dir_withendsep$(sep)",
|
||
"$(sep)home$(sep)dir2_withendsep$(sep)",
|
||
"$(sep)home$(sep)test.md",
|
||
"$(sep)home",
|
||
# Special cases
|
||
"$(sep)",
|
||
"$(sep)home$(sep)$(sep)$(sep)"
|
||
]
|
||
startpaths = [
|
||
"$(sep)home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)genindex.md",
|
||
"$(sep)multi_docs$(sep)genindex.md",
|
||
"$(sep)home$(sep)user$(sep)dir_withendsep$(sep)",
|
||
"$(sep)home$(sep)dir2_withendsep$(sep)",
|
||
"$(sep)home$(sep)test.md",
|
||
"$(sep)home",
|
||
# Special cases
|
||
"$(sep)",
|
||
"$(sep)home$(sep)$(sep)$(sep)"
|
||
]
|
||
relpath_expected_results = [
|
||
"..$(sep)Test1.md",
|
||
"..$(sep)..$(sep)home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
|
||
"..$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
|
||
"..$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
|
||
"..$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
|
||
"user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
|
||
"home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
|
||
"user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
|
||
"..$(sep)lib$(sep)file1.md",
|
||
"..$(sep)..$(sep)home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
|
||
"..$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
|
||
"..$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
|
||
"..$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
|
||
"user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
|
||
"home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
|
||
"user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
|
||
"..$(sep)..$(sep)..$(sep)..$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
|
||
"..$(sep)..$(sep)home$(sep)user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
|
||
"..$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
|
||
"..$(sep)user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
|
||
"..$(sep)user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
|
||
"user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
|
||
"home$(sep)user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
|
||
"user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
|
||
"..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)dir_withendsep",
|
||
"..$(sep)..$(sep)home$(sep)user$(sep)dir_withendsep",".","..$(sep)user$(sep)dir_withendsep",
|
||
"..$(sep)user$(sep)dir_withendsep","user$(sep)dir_withendsep",
|
||
"home$(sep)user$(sep)dir_withendsep","user$(sep)dir_withendsep",
|
||
"..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)dir2_withendsep",
|
||
"..$(sep)..$(sep)home$(sep)dir2_withendsep","..$(sep)..$(sep)dir2_withendsep",".",
|
||
"..$(sep)dir2_withendsep","dir2_withendsep","home$(sep)dir2_withendsep","dir2_withendsep",
|
||
"..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)test.md","..$(sep)..$(sep)home$(sep)test.md",
|
||
"..$(sep)..$(sep)test.md","..$(sep)test.md",".","test.md","home$(sep)test.md","test.md",
|
||
"..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..","..$(sep)..$(sep)home","..$(sep)..",
|
||
"..","..",".","home",".","..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..","..$(sep)..",
|
||
"..$(sep)..$(sep)..","..$(sep)..","..$(sep)..","..",".","..",
|
||
"..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..","..$(sep)..$(sep)home","..$(sep)..",
|
||
"..","..",".","home","."
|
||
]
|
||
idx = 0
|
||
for filep in filepaths
|
||
for startp in startpaths
|
||
res = relpath(filep, startp)
|
||
idx += 1
|
||
@test res == relpath_expected_results[idx]
|
||
if Sys.iswindows()
|
||
@test relpath("e:$filep", "e:$startp") == relpath_expected_results[idx]
|
||
@test relpath("e:$filep", "E:$startp") == relpath_expected_results[idx]
|
||
@test relpath("E:$filep", "e:$startp") == relpath_expected_results[idx]
|
||
@test relpath("E:$filep", "E:$startp") == relpath_expected_results[idx]
|
||
end
|
||
end
|
||
end
|
||
# Additional cases
|
||
@test_throws ArgumentError relpath(S("$(sep)home$(sep)user$(sep)dir_withendsep$(sep)"), "")
|
||
@test_throws ArgumentError relpath(S(""), S("$(sep)home$(sep)user$(sep)dir_withendsep$(sep)"))
|
||
|
||
# issue 40237
|
||
path = "..$(sep)a$(sep)b$(sep)c"
|
||
@test relpath(abspath(path)) == path
|
||
end
|
||
test_relpath()
|
||
end
|
||
|
||
@testset "uripath" begin
|
||
host = if Sys.iswindows()
|
||
""
|
||
elseif Sys.detectwsl()
|
||
distro = get(ENV, "WSL_DISTRO_NAME", "") # See <https://patrickwu.space/wslconf/>
|
||
"wsl%24/$distro" # See <https://github.com/microsoft/terminal/pull/14993> and <https://learn.microsoft.com/en-us/windows/wsl/filesystems>
|
||
else
|
||
gethostname()
|
||
end
|
||
sysdrive, uridrive = if Sys.iswindows() "C:\\", "C:/" else "/", "" end
|
||
@test Base.Filesystem.uripath("$(sysdrive)some$(sep)file.txt") == "file://$host/$(uridrive)some/file.txt"
|
||
@test Base.Filesystem.uripath("$(sysdrive)another$(sep)$(sep)folder$(sep)file.md") == "file://$host/$(uridrive)another/folder/file.md"
|
||
@test Base.Filesystem.uripath("$(sysdrive)some file with ^odd% chars") == "file://$host/$(uridrive)some%20file%20with%20%5Eodd%25%20chars"
|
||
@test Base.Filesystem.uripath("$(sysdrive)weird chars like @#&()[]{}") == "file://$host/$(uridrive)weird%20chars%20like%20%40%23%26%28%29%5B%5D%7B%7D"
|
||
@test Base.Filesystem.uripath("$sysdrive") == "file://$host/$uridrive"
|
||
@test Base.Filesystem.uripath(".") == Base.Filesystem.uripath(pwd())
|
||
@test Base.Filesystem.uripath("$(sysdrive)unicode$(sep)Δεδομένα") == "file://$host/$(uridrive)unicode/%CE%94%CE%B5%CE%B4%CE%BF%CE%BC%CE%AD%CE%BD%CE%B1"
|
||
@test Base.Filesystem.uripath("$(sysdrive)unicode$(sep)🧮🐛🔨") == "file://$host/$(uridrive)unicode/%F0%9F%A7%AE%F0%9F%90%9B%F0%9F%94%A8"
|
||
end
|
||
|
||
if Sys.iswindows()
|
||
@testset "issue #23646" begin
|
||
@test lowercase(relpath("E:\\a\\b", "C:\\c")) == "e:\\a\\b"
|
||
@test lowercase(relpath("E:\\a\\b", "c:\\c")) == "e:\\a\\b"
|
||
@test lowercase(relpath("e:\\a\\b", "C:\\c")) == "e:\\a\\b"
|
||
@test lowercase(relpath("e:\\a\\b", "c:\\c")) == "e:\\a\\b"
|
||
|
||
@test relpath("C:\\a\\b", "c:\\a\\b") == "."
|
||
@test relpath("c:\\a\\b", "C:\\a\\b") == "."
|
||
@test lowercase(relpath("C:\\a\\b", "c:\\c\\d")) == "..\\..\\a\\b"
|
||
@test lowercase(relpath("c:\\a\\b", "C:\\c\\d")) == "..\\..\\a\\b"
|
||
end
|
||
end
|
||
|
||
@testset "type stability" begin
|
||
@test isa(joinpath(S("a"), S("b")), String)
|
||
@test isa(joinpath(S(abspath("a")), S("b")), String)
|
||
end
|
||
|
||
@testset "Separator" begin
|
||
@test Base.Filesystem.isseparator('/')
|
||
@test any(Base.Filesystem.isseparator, "abc/def")
|
||
@test occursin(Base.Filesystem.path_separator_re, "abc/def")
|
||
@test !Base.Filesystem.isseparator('a')
|
||
@test !any(Base.Filesystem.isseparator, "abcdef")
|
||
@test !occursin(Base.Filesystem.path_separator_re, "abcdef")
|
||
if Sys.iswindows()
|
||
@test Base.Filesystem.isseparator('\\')
|
||
@test any(Base.Filesystem.isseparator, "abc\\def")
|
||
@test occursin(Base.Filesystem.path_separator_re, "abc\\def")
|
||
end
|
||
end
|
||
end
|
||
|
||
@testset "homedir" begin
|
||
var = Sys.iswindows() ? "USERPROFILE" : "HOME"
|
||
AVG_PATH = Base.Filesystem.AVG_PATH - 1 # null-termination character
|
||
for i = 0:9
|
||
local home = " "^AVG_PATH * "123456789"[1:i]
|
||
@test withenv(var => home) do
|
||
homedir()
|
||
end == home
|
||
end
|
||
@test isabspath(withenv(homedir, var => nothing))
|
||
# homedir(username) returns a directory for the current user
|
||
me = Sys.username()
|
||
me_home = homedir(me)
|
||
@test me_home !== nothing
|
||
@test isdir(me_home)
|
||
@test isabspath(me_home)
|
||
# non-existent user returns nothing
|
||
nouser = "nouser_" * randstring(12)
|
||
@test homedir(nouser) === nothing
|
||
end
|