brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.9 KiB · 2e26148 Raw
218 lines · cpp
1//===-- PathMappingTests.cpp  ------------------------*- C++ -*-----------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "PathMapping.h"10#include "llvm/Support/JSON.h"11#include "gmock/gmock.h"12#include "gtest/gtest.h"13#include <optional>14#include <string>15namespace clang {16namespace clangd {17namespace {18using ::testing::ElementsAre;19MATCHER_P2(Mapping, ClientPath, ServerPath, "") {20  return arg.ClientPath == ClientPath && arg.ServerPath == ServerPath;21}22 23bool failedParse(llvm::StringRef RawMappings) {24  llvm::Expected<PathMappings> Mappings = parsePathMappings(RawMappings);25  if (!Mappings) {26    consumeError(Mappings.takeError());27    return true;28  }29  return false;30}31 32TEST(ParsePathMappingTests, WindowsPath) {33  // Relative path to C drive34  EXPECT_TRUE(failedParse(R"(C:a=/root)"));35  EXPECT_TRUE(failedParse(R"(\C:a=/root)"));36  // Relative path to current drive.37  EXPECT_TRUE(failedParse(R"(\a=/root)"));38  // Absolute paths39  llvm::Expected<PathMappings> ParsedMappings =40      parsePathMappings(R"(C:\a=/root)");41  ASSERT_TRUE(bool(ParsedMappings));42  EXPECT_THAT(*ParsedMappings, ElementsAre(Mapping("/C:/a", "/root")));43  // Absolute UNC path44  ParsedMappings = parsePathMappings(R"(\\Server\C$=/root)");45  ASSERT_TRUE(bool(ParsedMappings));46  EXPECT_THAT(*ParsedMappings, ElementsAre(Mapping("//Server/C$", "/root")));47}48 49TEST(ParsePathMappingTests, UnixPath) {50  // Relative unix path51  EXPECT_TRUE(failedParse("a/b=/root"));52  // Absolute unix path53  llvm::Expected<PathMappings> ParsedMappings = parsePathMappings("/A/b=/root");54  ASSERT_TRUE(bool(ParsedMappings));55  EXPECT_THAT(*ParsedMappings, ElementsAre(Mapping("/A/b", "/root")));56  // Absolute unix path w/ backslash57  ParsedMappings = parsePathMappings(R"(/a/b\\ar=/root)");58  ASSERT_TRUE(bool(ParsedMappings));59  EXPECT_THAT(*ParsedMappings, ElementsAre(Mapping(R"(/a/b\\ar)", "/root")));60}61 62TEST(ParsePathMappingTests, ImproperFormat) {63  // uneven mappings64  EXPECT_TRUE(failedParse("/home/myuser1="));65  // mappings need to be absolute66  EXPECT_TRUE(failedParse("home/project=/workarea/project"));67  // duplicate delimiter68  EXPECT_TRUE(failedParse("/home==/workarea"));69  // no delimiter70  EXPECT_TRUE(failedParse("/home"));71  // improper delimiter72  EXPECT_TRUE(failedParse("/home,/workarea"));73}74 75TEST(ParsePathMappingTests, ParsesMultiple) {76  std::string RawPathMappings =77      "/home/project=/workarea/project,/home/project/.includes=/opt/include";78  auto Parsed = parsePathMappings(RawPathMappings);79  ASSERT_TRUE(bool(Parsed));80  EXPECT_THAT(*Parsed,81              ElementsAre(Mapping("/home/project", "/workarea/project"),82                          Mapping("/home/project/.includes", "/opt/include")));83}84 85bool mapsProperly(llvm::StringRef Orig, llvm::StringRef Expected,86                  llvm::StringRef RawMappings, PathMapping::Direction Dir) {87  llvm::Expected<PathMappings> Mappings = parsePathMappings(RawMappings);88  if (!Mappings)89    return false;90  std::optional<std::string> MappedPath = doPathMapping(Orig, Dir, *Mappings);91  std::string Actual = MappedPath ? *MappedPath : Orig.str();92  EXPECT_STREQ(Expected.str().c_str(), Actual.c_str());93  return Expected == Actual;94}95 96TEST(DoPathMappingTests, PreservesOriginal) {97  // Preserves original path when no mapping98  EXPECT_TRUE(mapsProperly("file:///home", "file:///home", "",99                           PathMapping::Direction::ClientToServer));100}101 102TEST(DoPathMappingTests, UsesFirstMatch) {103  EXPECT_TRUE(mapsProperly("file:///home/foo.cpp", "file:///workarea1/foo.cpp",104                           "/home=/workarea1,/home=/workarea2",105                           PathMapping::Direction::ClientToServer));106}107 108TEST(DoPathMappingTests, IgnoresSubstrings) {109  // Doesn't map substrings that aren't a proper path prefix110  EXPECT_TRUE(mapsProperly("file://home/foo-bar.cpp", "file://home/foo-bar.cpp",111                           "/home/foo=/home/bar",112                           PathMapping::Direction::ClientToServer));113}114 115TEST(DoPathMappingTests, MapsOutgoingPaths) {116  // When IsIncoming is false (i.e.a  response), map the other way117  EXPECT_TRUE(mapsProperly("file:///workarea/foo.cpp", "file:///home/foo.cpp",118                           "/home=/workarea",119                           PathMapping::Direction::ServerToClient));120}121 122TEST(DoPathMappingTests, OnlyMapFileUris) {123  EXPECT_TRUE(mapsProperly("test:///home/foo.cpp", "test:///home/foo.cpp",124                           "/home=/workarea",125                           PathMapping::Direction::ClientToServer));126}127 128TEST(DoPathMappingTests, RespectsCaseSensitivity) {129  EXPECT_TRUE(mapsProperly("file:///HOME/foo.cpp", "file:///HOME/foo.cpp",130                           "/home=/workarea",131                           PathMapping::Direction::ClientToServer));132}133 134TEST(DoPathMappingTests, MapsWindowsPaths) {135  // Maps windows properly136  EXPECT_TRUE(mapsProperly("file:///C:/home/foo.cpp",137                           "file:///C:/workarea/foo.cpp", R"(C:\home=C:\workarea)",138                           PathMapping::Direction::ClientToServer));139}140 141TEST(DoPathMappingTests, MapsWindowsUnixInterop) {142  // Path mappings with a windows-style client path and unix-style server path143  EXPECT_TRUE(mapsProperly(144      "file:///C:/home/foo.cpp", "file:///workarea/foo.cpp",145      R"(C:\home=/workarea)", PathMapping::Direction::ClientToServer));146}147 148TEST(ApplyPathMappingTests, PreservesOriginalParams) {149  auto Params = llvm::json::parse(R"({150    "textDocument": {"uri": "file:///home/foo.cpp"},151    "position": {"line": 0, "character": 0}152  })");153  ASSERT_TRUE(bool(Params));154  llvm::json::Value ExpectedParams = *Params;155  PathMappings Mappings;156  applyPathMappings(*Params, PathMapping::Direction::ClientToServer, Mappings);157  EXPECT_EQ(*Params, ExpectedParams);158}159 160TEST(ApplyPathMappingTests, MapsAllMatchingPaths) {161  // Handles nested objects and array values162  auto Params = llvm::json::parse(R"({163    "rootUri": {"uri": "file:///home/foo.cpp"},164    "workspaceFolders": ["file:///home/src", "file:///tmp"]165  })");166  auto ExpectedParams = llvm::json::parse(R"({167    "rootUri": {"uri": "file:///workarea/foo.cpp"},168    "workspaceFolders": ["file:///workarea/src", "file:///tmp"]169  })");170  auto Mappings = parsePathMappings("/home=/workarea");171  ASSERT_TRUE(bool(Params) && bool(ExpectedParams) && bool(Mappings));172  applyPathMappings(*Params, PathMapping::Direction::ClientToServer, *Mappings);173  EXPECT_EQ(*Params, *ExpectedParams);174}175 176TEST(ApplyPathMappingTests, MapsOutbound) {177  auto Params = llvm::json::parse(R"({178    "id": 1,179    "result": [180      {"uri": "file:///opt/include/foo.h"},181      {"uri": "file:///workarea/src/foo.cpp"}]182  })");183  auto ExpectedParams = llvm::json::parse(R"({184    "id": 1,185    "result": [186      {"uri": "file:///home/.includes/foo.h"},187      {"uri": "file:///home/src/foo.cpp"}]188  })");189  auto Mappings =190      parsePathMappings("/home=/workarea,/home/.includes=/opt/include");191  ASSERT_TRUE(bool(Params) && bool(ExpectedParams) && bool(Mappings));192  applyPathMappings(*Params, PathMapping::Direction::ServerToClient, *Mappings);193  EXPECT_EQ(*Params, *ExpectedParams);194}195 196TEST(ApplyPathMappingTests, MapsKeys) {197  auto Params = llvm::json::parse(R"({198    "changes": {199      "file:///home/foo.cpp": {"newText": "..."},200      "file:///home/src/bar.cpp": {"newText": "..."}201    }202  })");203  auto ExpectedParams = llvm::json::parse(R"({204    "changes": {205      "file:///workarea/foo.cpp": {"newText": "..."},206      "file:///workarea/src/bar.cpp": {"newText": "..."}207    }208  })");209  auto Mappings = parsePathMappings("/home=/workarea");210  ASSERT_TRUE(bool(Params) && bool(ExpectedParams) && bool(Mappings));211  applyPathMappings(*Params, PathMapping::Direction::ClientToServer, *Mappings);212  EXPECT_EQ(*Params, *ExpectedParams);213}214 215} // namespace216} // namespace clangd217} // namespace clang218