| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file LICENSE.rst or https://cmake.org/licensing for details. */ | |
| #include <cmConfigure.h> // IWYU pragma: keep | |
| #include <cerrno> | |
| #include <map> | |
| #include <string> | |
| #include <utility> | |
| #ifdef _WIN32 | |
| # include <cmsys/String.h> | |
| #endif | |
| #include <cmsys/Status.hxx> | |
| #include "cmPathResolver.h" | |
| #if defined(_WIN32) || defined(__APPLE__) | |
| # include "cmSystemTools.h" | |
| #endif | |
| #include "testCommon.h" | |
| // IWYU pragma: no_forward_declare cm::PathResolver::Policies::LogicalPath | |
| // IWYU pragma: no_forward_declare cm::PathResolver::Policies::NaivePath | |
| // IWYU pragma: no_forward_declare cm::PathResolver::Policies::CasePath | |
| // IWYU pragma: no_forward_declare cm::PathResolver::Policies::RealPath | |
| namespace { | |
| class MockSystem : public cm::PathResolver::System | |
| { | |
| public: | |
| ~MockSystem() override = default; | |
| struct Path | |
| { | |
| std::string Name; | |
| std::string Link; | |
| }; | |
| std::map<std::string, Path> Paths; | |
| void SetPaths(std::map<std::string, Path> paths) | |
| { | |
| this->Paths = std::move(paths); | |
| } | |
| static std::string AdjustCase(std::string const& path) | |
| { | |
| #if defined(_WIN32) || defined(__APPLE__) | |
| return cmSystemTools::LowerCase(path); | |
| #else | |
| return path; | |
| #endif | |
| } | |
| cmsys::Status ReadSymlink(std::string const& path, | |
| std::string& link) override | |
| { | |
| auto i = this->Paths.find(AdjustCase(path)); | |
| if (i == this->Paths.end()) { | |
| return cmsys::Status::POSIX(ENOENT); | |
| } | |
| if (i->second.Link.empty()) { | |
| return cmsys::Status::POSIX(EINVAL); | |
| } | |
| link = i->second.Link; | |
| return cmsys::Status::Success(); | |
| } | |
| bool PathExists(std::string const& path) override | |
| { | |
| return this->Paths.find(AdjustCase(path)) != this->Paths.end(); | |
| } | |
| std::string WorkDir; | |
| void SetWorkDir(std::string wd) { this->WorkDir = std::move(wd); } | |
| std::string GetWorkingDirectory() override { return this->WorkDir; } | |
| #ifdef _WIN32 | |
| std::map<char, std::string> WorkDirOnDrive; | |
| void SetWorkDirOnDrive(std::map<char, std::string> wd) | |
| { | |
| this->WorkDirOnDrive = std::move(wd); | |
| } | |
| std::string GetWorkingDirectoryOnDrive(char letter) override | |
| { | |
| std::string result; | |
| auto i = this->WorkDirOnDrive.find(cmsysString_tolower(letter)); | |
| if (i != this->WorkDirOnDrive.end()) { | |
| result = i->second; | |
| } | |
| return result; | |
| } | |
| #endif | |
| #if defined(_WIN32) || defined(__APPLE__) | |
| cmsys::Status ReadName(std::string const& path, std::string& name) override | |
| { | |
| auto i = this->Paths.find(AdjustCase(path)); | |
| if (i == this->Paths.end()) { | |
| return cmsys::Status::POSIX(ENOENT); | |
| } | |
| name = i->second.Name; | |
| return cmsys::Status::Success(); | |
| } | |
| #endif | |
| }; | |
| #define EXPECT_RESOLVE(_in, _expect) \ | |
| do { \ | |
| std::string out; \ | |
| ASSERT_TRUE(r.Resolve(_in, out)); \ | |
| ASSERT_EQUAL(out, _expect); \ | |
| } while (false) | |
| #define EXPECT_ENOENT(_in, _expect) \ | |
| do { \ | |
| std::string out; \ | |
| ASSERT_EQUAL(r.Resolve(_in, out).GetPOSIX(), ENOENT); \ | |
| ASSERT_EQUAL(out, _expect); \ | |
| } while (false) | |
| using namespace cm::PathResolver; | |
| bool posixRoot() | |
| { | |
| std::cout << "posixRoot()\n"; | |
| MockSystem os; | |
| os.SetPaths({ | |
| { "/", { {}, {} } }, | |
| }); | |
| Resolver<Policies::RealPath> const r(os); | |
| EXPECT_RESOLVE("/", "/"); | |
| EXPECT_RESOLVE("//", "/"); | |
| EXPECT_RESOLVE("/.", "/"); | |
| EXPECT_RESOLVE("/./", "/"); | |
| EXPECT_RESOLVE("/..", "/"); | |
| EXPECT_RESOLVE("/../", "/"); | |
| return true; | |
| } | |
| bool posixAbsolutePath() | |
| { | |
| std::cout << "posixAbsolutePath()\n"; | |
| MockSystem os; | |
| os.SetPaths({ | |
| { "/", { {}, {} } }, | |
| { "/a", { {}, {} } }, | |
| }); | |
| Resolver<Policies::RealPath> const r(os); | |
| EXPECT_RESOLVE("/a", "/a"); | |
| EXPECT_RESOLVE("/a/", "/a"); | |
| EXPECT_RESOLVE("/a//", "/a"); | |
| EXPECT_RESOLVE("/a/.", "/a"); | |
| EXPECT_RESOLVE("/a/./", "/a"); | |
| EXPECT_RESOLVE("/a/..", "/"); | |
| EXPECT_RESOLVE("/a/../", "/"); | |
| EXPECT_RESOLVE("/a/../..", "/"); | |
| #ifndef _WIN32 | |
| EXPECT_RESOLVE("//a", "/a"); | |
| #endif | |
| return true; | |
| } | |
| bool posixWorkingDirectory() | |
| { | |
| std::cout << "posixWorkingDirectory()\n"; | |
| MockSystem os; | |
| os.SetPaths({ | |
| { "/", { {}, {} } }, | |
| { "/a", { {}, {} } }, | |
| { "/cwd", { {}, {} } }, | |
| { "/cwd/a", { {}, {} } }, | |
| }); | |
| Resolver<Policies::RealPath> const r(os); | |
| EXPECT_RESOLVE("", "/"); | |
| EXPECT_RESOLVE(".", "/"); | |
| EXPECT_RESOLVE("..", "/"); | |
| EXPECT_RESOLVE("a", "/a"); | |
| os.SetWorkDir("/cwd"); | |
| EXPECT_RESOLVE("", "/cwd"); | |
| EXPECT_RESOLVE(".", "/cwd"); | |
| EXPECT_RESOLVE("..", "/"); | |
| EXPECT_RESOLVE("a", "/cwd/a"); | |
| return true; | |
| } | |
| bool posixSymlink() | |
| { | |
| std::cout << "posixSymlink()\n"; | |
| MockSystem os; | |
| os.SetPaths({ | |
| { "/", { {}, {} } }, | |
| { "/link-a", { {}, "a" } }, | |
| { "/link-a-excess", { {}, "a//." } }, | |
| { "/link-broken", { {}, "link-broken-dest" } }, | |
| { "/a", { {}, {} } }, | |
| { "/a/b", { {}, {} } }, | |
| { "/a/link-b", { {}, "b" } }, | |
| { "/a/b/link-c", { {}, "c" } }, | |
| { "/a/b/c", { {}, {} } }, | |
| { "/a/b/c/link-..|..", { {}, "../.." } }, | |
| { "/a/link-|1|2", { {}, "/1/2" } }, | |
| { "/1", { {}, {} } }, | |
| { "/1/2", { {}, {} } }, | |
| { "/1/2/3", { {}, {} } }, | |
| }); | |
| { | |
| Resolver<Policies::CasePath> const r(os); | |
| EXPECT_RESOLVE("/link-a", "/link-a"); | |
| EXPECT_RESOLVE("/link-a-excess", "/link-a-excess"); | |
| EXPECT_RESOLVE("/link-a-excess/b", "/link-a-excess/b"); | |
| EXPECT_RESOLVE("/link-broken", "/link-broken"); | |
| EXPECT_RESOLVE("/link-a/../missing", "/missing"); | |
| EXPECT_RESOLVE("/a/b/link-c", "/a/b/link-c"); | |
| EXPECT_RESOLVE("/a/link-b/c", "/a/link-b/c"); | |
| EXPECT_RESOLVE("/a/link-b/link-c/..", "/a/link-b"); | |
| EXPECT_RESOLVE("/a/b/c/link-..|..", "/a/b/c/link-..|.."); | |
| EXPECT_RESOLVE("/a/b/c/link-..|../link-b", "/a/b/c/link-..|../link-b"); | |
| EXPECT_RESOLVE("/a/link-|1|2/3", "/a/link-|1|2/3"); | |
| EXPECT_RESOLVE("/a/link-|1|2/../2/3", "/a/2/3"); | |
| } | |
| { | |
| Resolver<Policies::LogicalPath> const r(os); | |
| EXPECT_RESOLVE("/link-a", "/link-a"); | |
| EXPECT_RESOLVE("/link-a-excess", "/link-a-excess"); | |
| EXPECT_RESOLVE("/link-a-excess/b", "/link-a-excess/b"); | |
| EXPECT_RESOLVE("/link-broken", "/link-broken"); | |
| EXPECT_RESOLVE("/link-a/../missing", "/missing"); | |
| EXPECT_RESOLVE("/a/b/link-c", "/a/b/link-c"); | |
| EXPECT_RESOLVE("/a/link-b/c", "/a/link-b/c"); | |
| EXPECT_RESOLVE("/a/link-b/link-c/..", "/a/link-b"); | |
| EXPECT_RESOLVE("/a/b/c/link-..|..", "/a/b/c/link-..|.."); | |
| EXPECT_RESOLVE("/a/b/c/link-..|../link-b", "/a/b/c/link-..|../link-b"); | |
| EXPECT_RESOLVE("/a/link-|1|2/3", "/a/link-|1|2/3"); | |
| EXPECT_RESOLVE("/a/link-|1|2/../2/3", "/1/2/3"); | |
| } | |
| { | |
| Resolver<Policies::RealPath> const r(os); | |
| EXPECT_RESOLVE("/link-a", "/a"); | |
| EXPECT_RESOLVE("/link-a-excess", "/a"); | |
| EXPECT_RESOLVE("/link-a-excess/b", "/a/b"); | |
| EXPECT_ENOENT("/link-broken", "/link-broken-dest"); | |
| EXPECT_ENOENT("/link-a/../missing", "/missing"); | |
| EXPECT_RESOLVE("/a/b/link-c", "/a/b/c"); | |
| EXPECT_RESOLVE("/a/link-b/c", "/a/b/c"); | |
| EXPECT_RESOLVE("/a/link-b/link-c/..", "/a/b"); | |
| EXPECT_RESOLVE("/a/b/c/link-..|..", "/a"); | |
| EXPECT_RESOLVE("/a/b/c/link-..|../link-b", "/a/b"); | |
| EXPECT_RESOLVE("/a/link-|1|2/3", "/1/2/3"); | |
| } | |
| return true; | |
| } | |
| #ifdef __APPLE__ | |
| bool macosActualCase() | |
| { | |
| std::cout << "macosActualCase()\n"; | |
| MockSystem os; | |
| os.SetPaths({ | |
| { "/", { {}, {} } }, | |
| { "/mixed", { "MiXeD", {} } }, | |
| { "/mixed/link-mixed", { "LiNk-MiXeD", "mixed" } }, | |
| { "/mixed/mixed", { "MiXeD", {} } }, | |
| { "/mixed/link-c-mixed", { "LiNk-C-MiXeD", "/mIxEd" } }, | |
| { "/upper", { "UPPER", {} } }, | |
| { "/upper/link-upper", { "LINK-UPPER", "upper" } }, | |
| { "/upper/upper", { "UPPER", {} } }, | |
| { "/upper/link-c-upper", { "LINK-C-UPPER", "/upper" } }, | |
| }); | |
| { | |
| Resolver<Policies::CasePath> const r(os); | |
| EXPECT_RESOLVE("/mIxEd/MiSsInG", "/MiXeD/MiSsInG"); | |
| EXPECT_RESOLVE("/mIxEd/link-MiXeD", "/MiXeD/LiNk-MiXeD"); | |
| EXPECT_RESOLVE("/mIxEd/link-c-MiXeD", "/MiXeD/LiNk-C-MiXeD"); | |
| EXPECT_RESOLVE("/upper/mIsSiNg", "/UPPER/mIsSiNg"); | |
| EXPECT_RESOLVE("/upper/link-upper", "/UPPER/LINK-UPPER"); | |
| EXPECT_RESOLVE("/upper/link-c-upper", "/UPPER/LINK-C-UPPER"); | |
| } | |
| { | |
| Resolver<Policies::LogicalPath> const r(os); | |
| EXPECT_RESOLVE("/mIxEd/MiSsInG", "/MiXeD/MiSsInG"); | |
| EXPECT_RESOLVE("/mIxEd/link-MiXeD", "/MiXeD/LiNk-MiXeD"); | |
| EXPECT_RESOLVE("/mIxEd/link-c-MiXeD", "/MiXeD/LiNk-C-MiXeD"); | |
| EXPECT_RESOLVE("/upper/mIsSiNg", "/UPPER/mIsSiNg"); | |
| EXPECT_RESOLVE("/upper/link-upper", "/UPPER/LINK-UPPER"); | |
| EXPECT_RESOLVE("/upper/link-c-upper", "/UPPER/LINK-C-UPPER"); | |
| } | |
| { | |
| Resolver<Policies::RealPath> const r(os); | |
| EXPECT_ENOENT("/mIxEd/MiSsInG", "/MiXeD/MiSsInG"); | |
| EXPECT_RESOLVE("/mIxEd/link-MiXeD", "/MiXeD/MiXeD"); | |
| EXPECT_RESOLVE("/mIxEd/link-c-MiXeD", "/MiXeD"); | |
| EXPECT_ENOENT("/upper/mIsSiNg", "/UPPER/mIsSiNg"); | |
| EXPECT_RESOLVE("/upper/link-upper", "/UPPER/UPPER"); | |
| EXPECT_RESOLVE("/upper/link-c-upper", "/UPPER"); | |
| } | |
| return true; | |
| } | |
| #endif | |
| #ifdef _WIN32 | |
| bool windowsRoot() | |
| { | |
| std::cout << "windowsRoot()\n"; | |
| MockSystem os; | |
| { | |
| Resolver<Policies::NaivePath> const r(os); | |
| EXPECT_RESOLVE("c:/", "c:/"); | |
| EXPECT_RESOLVE("C:/", "C:/"); | |
| EXPECT_RESOLVE("c://", "c:/"); | |
| EXPECT_RESOLVE("C:/.", "C:/"); | |
| EXPECT_RESOLVE("c:/./", "c:/"); | |
| EXPECT_RESOLVE("C:/..", "C:/"); | |
| EXPECT_RESOLVE("c:/../", "c:/"); | |
| } | |
| { | |
| Resolver<Policies::CasePath> const r(os); | |
| EXPECT_RESOLVE("c:/", "C:/"); | |
| EXPECT_RESOLVE("C:/", "C:/"); | |
| EXPECT_RESOLVE("c://", "C:/"); | |
| EXPECT_RESOLVE("C:/.", "C:/"); | |
| EXPECT_RESOLVE("c:/./", "C:/"); | |
| EXPECT_RESOLVE("C:/..", "C:/"); | |
| EXPECT_RESOLVE("c:/../", "C:/"); | |
| } | |
| os.SetPaths({ | |
| { "c:/", { {}, {} } }, | |
| { "//host/", { {}, {} } }, | |
| }); | |
| { | |
| Resolver<Policies::RealPath> const r(os); | |
| EXPECT_RESOLVE("c:/", "C:/"); | |
| EXPECT_RESOLVE("C:/", "C:/"); | |
| EXPECT_RESOLVE("c://", "C:/"); | |
| EXPECT_RESOLVE("C:/.", "C:/"); | |
| EXPECT_RESOLVE("c:/./", "C:/"); | |
| EXPECT_RESOLVE("C:/..", "C:/"); | |
| EXPECT_RESOLVE("c:/../", "C:/"); | |
| EXPECT_RESOLVE("//host", "//host/"); | |
| EXPECT_RESOLVE("//host/.", "//host/"); | |
| EXPECT_RESOLVE("//host/./", "//host/"); | |
| EXPECT_RESOLVE("//host/..", "//host/"); | |
| EXPECT_RESOLVE("//host/../", "//host/"); | |
| } | |
| return true; | |
| } | |
| bool windowsAbsolutePath() | |
| { | |
| std::cout << "windowsAbsolutePath()\n"; | |
| MockSystem os; | |
| os.SetPaths({ | |
| { "c:/", { {}, {} } }, | |
| { "c:/a", { {}, {} } }, | |
| }); | |
| Resolver<Policies::RealPath> const r(os); | |
| EXPECT_RESOLVE("c:/a", "C:/a"); | |
| EXPECT_RESOLVE("c:/a/", "C:/a"); | |
| EXPECT_RESOLVE("c:/a//", "C:/a"); | |
| EXPECT_RESOLVE("c:/a/.", "C:/a"); | |
| EXPECT_RESOLVE("c:/a/./", "C:/a"); | |
| EXPECT_RESOLVE("c:/a/..", "C:/"); | |
| EXPECT_RESOLVE("c:/a/../", "C:/"); | |
| EXPECT_RESOLVE("c:/a/../..", "C:/"); | |
| return true; | |
| } | |
| bool windowsActualCase() | |
| { | |
| std::cout << "windowsActualCase()\n"; | |
| MockSystem os; | |
| os.SetPaths({ | |
| { "c:/", { {}, {} } }, | |
| { "c:/mixed", { "MiXeD", {} } }, | |
| { "c:/mixed/link-mixed", { "LiNk-MiXeD", "mixed" } }, | |
| { "c:/mixed/mixed", { "MiXeD", {} } }, | |
| { "c:/mixed/link-c-mixed", { "LiNk-C-MiXeD", "C:/mIxEd" } }, | |
| { "c:/upper", { "UPPER", {} } }, | |
| { "c:/upper/link-upper", { "LINK-UPPER", "upper" } }, | |
| { "c:/upper/upper", { "UPPER", {} } }, | |
| { "c:/upper/link-c-upper", { "LINK-C-UPPER", "c:/upper" } }, | |
| }); | |
| { | |
| Resolver<Policies::CasePath> const r(os); | |
| EXPECT_RESOLVE("c:/mIxEd/MiSsInG", "C:/MiXeD/MiSsInG"); | |
| EXPECT_RESOLVE("c:/mIxEd/link-MiXeD", "C:/MiXeD/LiNk-MiXeD"); | |
| EXPECT_RESOLVE("c:/mIxEd/link-c-MiXeD", "C:/MiXeD/LiNk-C-MiXeD"); | |
| EXPECT_RESOLVE("c:/upper/mIsSiNg", "C:/UPPER/mIsSiNg"); | |
| EXPECT_RESOLVE("c:/upper/link-upper", "C:/UPPER/LINK-UPPER"); | |
| EXPECT_RESOLVE("c:/upper/link-c-upper", "C:/UPPER/LINK-C-UPPER"); | |
| } | |
| { | |
| Resolver<Policies::LogicalPath> const r(os); | |
| EXPECT_RESOLVE("c:/mIxEd/MiSsInG", "C:/MiXeD/MiSsInG"); | |
| EXPECT_RESOLVE("c:/mIxEd/link-MiXeD", "C:/MiXeD/LiNk-MiXeD"); | |
| EXPECT_RESOLVE("c:/mIxEd/link-c-MiXeD", "C:/MiXeD/LiNk-C-MiXeD"); | |
| EXPECT_RESOLVE("c:/upper/mIsSiNg", "C:/UPPER/mIsSiNg"); | |
| EXPECT_RESOLVE("c:/upper/link-upper", "C:/UPPER/LINK-UPPER"); | |
| EXPECT_RESOLVE("c:/upper/link-c-upper", "C:/UPPER/LINK-C-UPPER"); | |
| } | |
| { | |
| Resolver<Policies::RealPath> const r(os); | |
| EXPECT_ENOENT("c:/mIxEd/MiSsInG", "C:/MiXeD/MiSsInG"); | |
| EXPECT_RESOLVE("c:/mIxEd/link-MiXeD", "C:/MiXeD/MiXeD"); | |
| EXPECT_RESOLVE("c:/mIxEd/link-c-MiXeD", "C:/MiXeD"); | |
| EXPECT_ENOENT("c:/upper/mIsSiNg", "C:/UPPER/mIsSiNg"); | |
| EXPECT_RESOLVE("c:/upper/link-upper", "C:/UPPER/UPPER"); | |
| EXPECT_RESOLVE("c:/upper/link-c-upper", "C:/UPPER"); | |
| } | |
| return true; | |
| } | |
| bool windowsWorkingDirectory() | |
| { | |
| std::cout << "windowsWorkingDirectory()\n"; | |
| MockSystem os; | |
| os.SetPaths({ | |
| { "c:/", { {}, {} } }, | |
| { "c:/a", { {}, {} } }, | |
| { "c:/cwd", { {}, {} } }, | |
| { "c:/cwd/a", { {}, {} } }, | |
| }); | |
| { | |
| Resolver<Policies::LogicalPath> const r(os); | |
| EXPECT_RESOLVE("", "/"); | |
| EXPECT_RESOLVE(".", "/"); | |
| EXPECT_RESOLVE("..", "/"); | |
| EXPECT_RESOLVE("a", "/a"); | |
| } | |
| { | |
| Resolver<Policies::RealPath> const r(os); | |
| os.SetWorkDir("c:/cwd"); | |
| EXPECT_RESOLVE("", "C:/cwd"); | |
| EXPECT_RESOLVE(".", "C:/cwd"); | |
| EXPECT_RESOLVE("..", "C:/"); | |
| EXPECT_RESOLVE("a", "C:/cwd/a"); | |
| EXPECT_ENOENT("missing", "C:/cwd/missing"); | |
| } | |
| return true; | |
| } | |
| bool windowsWorkingDirectoryOnDrive() | |
| { | |
| std::cout << "windowsWorkingDirectoryOnDrive()\n"; | |
| MockSystem os; | |
| os.SetWorkDir("c:/cwd"); | |
| os.SetWorkDirOnDrive({ | |
| { 'd', "d:/cwd-d" }, | |
| }); | |
| { | |
| Resolver<Policies::NaivePath> const r(os); | |
| EXPECT_RESOLVE("c:", "c:/cwd"); | |
| EXPECT_RESOLVE("c:.", "c:/cwd"); | |
| EXPECT_RESOLVE("c:..", "c:/"); | |
| EXPECT_RESOLVE("C:", "C:/cwd"); | |
| EXPECT_RESOLVE("C:.", "C:/cwd"); | |
| EXPECT_RESOLVE("C:..", "C:/"); | |
| EXPECT_RESOLVE("d:", "d:/cwd-d"); | |
| EXPECT_RESOLVE("d:.", "d:/cwd-d"); | |
| EXPECT_RESOLVE("d:..", "d:/"); | |
| EXPECT_RESOLVE("D:", "D:/cwd-d"); | |
| EXPECT_RESOLVE("D:.", "D:/cwd-d"); | |
| EXPECT_RESOLVE("D:..", "D:/"); | |
| EXPECT_RESOLVE("e:", "e:/"); | |
| EXPECT_RESOLVE("e:.", "e:/"); | |
| EXPECT_RESOLVE("e:..", "e:/"); | |
| EXPECT_RESOLVE("E:", "E:/"); | |
| EXPECT_RESOLVE("E:.", "E:/"); | |
| EXPECT_RESOLVE("E:..", "E:/"); | |
| } | |
| { | |
| Resolver<Policies::CasePath> const r(os); | |
| EXPECT_RESOLVE("c:", "C:/cwd"); | |
| EXPECT_RESOLVE("c:.", "C:/cwd"); | |
| EXPECT_RESOLVE("c:..", "C:/"); | |
| EXPECT_RESOLVE("C:", "C:/cwd"); | |
| EXPECT_RESOLVE("C:.", "C:/cwd"); | |
| EXPECT_RESOLVE("C:..", "C:/"); | |
| EXPECT_RESOLVE("d:", "D:/cwd-d"); | |
| EXPECT_RESOLVE("d:.", "D:/cwd-d"); | |
| EXPECT_RESOLVE("d:..", "D:/"); | |
| EXPECT_RESOLVE("D:", "D:/cwd-d"); | |
| EXPECT_RESOLVE("D:.", "D:/cwd-d"); | |
| EXPECT_RESOLVE("D:..", "D:/"); | |
| EXPECT_RESOLVE("e:", "E:/"); | |
| EXPECT_RESOLVE("e:.", "E:/"); | |
| EXPECT_RESOLVE("e:..", "E:/"); | |
| EXPECT_RESOLVE("E:", "E:/"); | |
| EXPECT_RESOLVE("E:.", "E:/"); | |
| EXPECT_RESOLVE("E:..", "E:/"); | |
| } | |
| os.SetPaths({ | |
| { "c:/", { {}, {} } }, | |
| { "c:/cwd", { {}, {} } }, | |
| { "c:/cwd/existing", { {}, {} } }, | |
| { "d:/", { {}, {} } }, | |
| { "d:/cwd-d", { {}, {} } }, | |
| { "d:/cwd-d/existing", { {}, {} } }, | |
| { "e:/", { {}, {} } }, | |
| }); | |
| { | |
| Resolver<Policies::RealPath> const r(os); | |
| EXPECT_RESOLVE("c:existing", "C:/cwd/existing"); | |
| EXPECT_ENOENT("c:missing", "C:/cwd/missing"); | |
| EXPECT_RESOLVE("C:existing", "C:/cwd/existing"); | |
| EXPECT_ENOENT("C:missing", "C:/cwd/missing"); | |
| EXPECT_RESOLVE("d:existing", "D:/cwd-d/existing"); | |
| EXPECT_ENOENT("d:missing", "D:/cwd-d/missing"); | |
| EXPECT_ENOENT("e:missing", "E:/missing"); | |
| EXPECT_ENOENT("f:", "F:/"); | |
| } | |
| return true; | |
| } | |
| bool windowsNetworkShare() | |
| { | |
| std::cout << "windowsNetworkShare()\n"; | |
| MockSystem os; | |
| os.SetPaths({ | |
| { "c:/", { {}, {} } }, | |
| { "c:/cwd", { {}, {} } }, | |
| { "c:/cwd/link-to-host-share", { {}, "//host/share" } }, | |
| { "//host/", { {}, {} } }, | |
| { "//host/share", { {}, {} } }, | |
| }); | |
| os.SetWorkDir("c:/cwd"); | |
| { | |
| Resolver<Policies::RealPath> const r(os); | |
| EXPECT_RESOLVE("//host/share", "//host/share"); | |
| EXPECT_RESOLVE("//host/share/", "//host/share"); | |
| EXPECT_RESOLVE("//host/share/.", "//host/share"); | |
| EXPECT_RESOLVE("//host/share/./", "//host/share"); | |
| EXPECT_RESOLVE("//host/share/..", "//host/"); | |
| EXPECT_RESOLVE("//host/share/../", "//host/"); | |
| EXPECT_RESOLVE("//host/share/../..", "//host/"); | |
| EXPECT_RESOLVE("link-to-host-share", "//host/share"); | |
| EXPECT_RESOLVE("link-to-host-share/..", "//host/"); | |
| EXPECT_ENOENT("link-to-host-share/../missing", "//host/missing"); | |
| } | |
| { | |
| Resolver<Policies::LogicalPath> const r(os); | |
| EXPECT_RESOLVE("link-to-host-share", "C:/cwd/link-to-host-share"); | |
| EXPECT_RESOLVE("link-to-host-share/..", "//host/"); | |
| EXPECT_RESOLVE("link-to-host-share/../missing", "//host/missing"); | |
| } | |
| { | |
| Resolver<Policies::CasePath> const r(os); | |
| EXPECT_RESOLVE("link-to-host-share", "C:/cwd/link-to-host-share"); | |
| EXPECT_RESOLVE("link-to-host-share/..", "C:/cwd"); | |
| EXPECT_RESOLVE("link-to-host-share/../missing", "C:/cwd/missing"); | |
| } | |
| return true; | |
| } | |
| #endif | |
| } | |
| int testPathResolver(int /*unused*/, char* /*unused*/[]) | |
| { | |
| return runTests({ | |
| posixRoot, | |
| posixAbsolutePath, | |
| posixWorkingDirectory, | |
| posixSymlink, | |
| #ifdef __APPLE__ | |
| macosActualCase, | |
| #endif | |
| #ifdef _WIN32 | |
| windowsRoot, | |
| windowsAbsolutePath, | |
| windowsActualCase, | |
| windowsWorkingDirectory, | |
| windowsWorkingDirectoryOnDrive, | |
| windowsNetworkShare, | |
| #endif | |
| }); | |
| } |