]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Add simple unit test of Util::make_relative_path
authorJoel Rosdahl <joel@rosdahl.net>
Mon, 28 Dec 2020 19:46:06 +0000 (20:46 +0100)
committerJoel Rosdahl <joel@rosdahl.net>
Tue, 29 Dec 2020 19:35:17 +0000 (20:35 +0100)
src/Util.cpp
src/Util.hpp
unittest/test_Util.cpp

index 84f1265cf776a970e193aedc2c4ce394726b16be..caaed55435f3cd1927cf485345a28e5ff05c0ccd 100644 (file)
@@ -858,10 +858,12 @@ localtime(optional<time_t> time)
 }
 
 std::string
-make_relative_path(const Context& ctx, string_view path)
+make_relative_path(const std::string& base_dir,
+                   const std::string& actual_cwd,
+                   const std::string& apparent_cwd,
+                   nonstd::string_view path)
 {
-  if (ctx.config.base_dir().empty()
-      || !Util::starts_with(path, ctx.config.base_dir())) {
+  if (base_dir.empty() || !Util::starts_with(path, base_dir)) {
     return std::string(path);
   }
 
@@ -894,11 +896,11 @@ make_relative_path(const Context& ctx, string_view path)
   std::string path_str(path);
   std::string normalized_path = Util::normalize_absolute_path(path_str);
   std::vector<std::string> relpath_candidates = {
-    Util::get_relative_path(ctx.actual_cwd, normalized_path),
+    Util::get_relative_path(actual_cwd, normalized_path),
   };
-  if (ctx.apparent_cwd != ctx.actual_cwd) {
+  if (apparent_cwd != actual_cwd) {
     relpath_candidates.emplace_back(
-      Util::get_relative_path(ctx.apparent_cwd, normalized_path));
+      Util::get_relative_path(apparent_cwd, normalized_path));
     // Move best (= shortest) match first:
     if (relpath_candidates[0].length() > relpath_candidates[1].length()) {
       std::swap(relpath_candidates[0], relpath_candidates[1]);
@@ -915,6 +917,13 @@ make_relative_path(const Context& ctx, string_view path)
   return std::string(original_path);
 }
 
+std::string
+make_relative_path(const Context& ctx, string_view path)
+{
+  return make_relative_path(
+    ctx.config.base_dir(), ctx.actual_cwd, ctx.apparent_cwd, path);
+}
+
 bool
 matches_dir_prefix_or_file(string_view dir_prefix_or_file, string_view path)
 {
index e353f4ce778bcc6d728c2be6721e72228c9be057..819950b5f3a00990750f8b5282279d2f10e510ff 100644 (file)
@@ -309,8 +309,14 @@ bool is_precompiled_header(nonstd::string_view path);
 // time of day is used.
 nonstd::optional<tm> localtime(nonstd::optional<time_t> time = {});
 
-// Make a relative path from current working directory to `path` if `path` is
-// under the base directory.
+// Make a relative path from current working directory (either `actual_cwd` or
+// `apparent_cwd`) to `path` if `path` is under `base_dir`.
+std::string make_relative_path(const std::string& base_dir,
+                               const std::string& actual_cwd,
+                               const std::string& apparent_cwd,
+                               nonstd::string_view path);
+
+// Like above but with base directory and apparent/actual CWD taken from `ctx`.
 std::string make_relative_path(const Context& ctx, nonstd::string_view path);
 
 // Return whether `path` is equal to `dir_prefix_or_file` or if
index d8c2ddba1a4e3c91346d00a9d22207d0e32a8da5..ff4da6c33759c8e338ce8d4cee7e499f4de7e437 100644 (file)
@@ -554,6 +554,46 @@ TEST_CASE("Util::is_dir_separator")
 #endif
 }
 
+#ifndef _WIN32
+TEST_CASE("Util::make_relative_path")
+{
+  using Util::make_relative_path;
+
+  const TestContext test_context;
+
+  const std::string cwd = Util::get_actual_cwd();
+  const std::string actual_cwd = FMT("{}/d", cwd);
+  const std::string apparent_cwd = FMT("{}/s", cwd);
+
+  REQUIRE(Util::create_dir("d"));
+  REQUIRE(symlink("d", "s") == 0);
+  REQUIRE(chdir("s") == 0);
+  Util::setenv("PWD", apparent_cwd);
+
+  SUBCASE("No base directory")
+  {
+    CHECK(make_relative_path("", "/a", "/a", "/a/x") == "/a/x");
+  }
+
+  SUBCASE("Path matches neither actual nor apparent CWD")
+  {
+    CHECK(make_relative_path("/", "/a", "/b", "/x") == "/x");
+  }
+
+  SUBCASE("Match of actual CWD")
+  {
+    CHECK(make_relative_path("/", actual_cwd, apparent_cwd, actual_cwd + "/x")
+          == "./x");
+  }
+
+  SUBCASE("Match of apparent CWD")
+  {
+    CHECK(make_relative_path("/", actual_cwd, apparent_cwd, apparent_cwd + "/x")
+          == "./x");
+  }
+}
+#endif
+
 TEST_CASE("Util::matches_dir_prefix_or_file")
 {
   CHECK(!Util::matches_dir_prefix_or_file("", ""));