124 lines · cpp
1//===-- FileDistanceTests.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 "FileDistance.h"10#include "TestFS.h"11#include "gmock/gmock.h"12#include "gtest/gtest.h"13 14namespace clang {15namespace clangd {16namespace {17 18TEST(FileDistanceTests, Distance) {19 FileDistanceOptions Opts;20 Opts.UpCost = 5;21 Opts.DownCost = 3;22 SourceParams CostTwo;23 CostTwo.Cost = 2;24 FileDistance D(25 {{"tools/clang/lib/Format/FormatToken.cpp", SourceParams()},26 {"tools/clang/include/clang/Format/FormatToken.h", SourceParams()},27 {"include/llvm/ADT/StringRef.h", CostTwo}},28 Opts);29 30 // Source31 EXPECT_EQ(D.distance("tools/clang/lib/Format/FormatToken.cpp"), 0u);32 EXPECT_EQ(D.distance("include/llvm/ADT/StringRef.h"), 2u);33 // Parent34 EXPECT_EQ(D.distance("tools/clang/lib/Format/"), 5u);35 // Child36 EXPECT_EQ(D.distance("tools/clang/lib/Format/FormatToken.cpp/Oops"), 3u);37 // Ancestor (up+up+up+up)38 EXPECT_EQ(D.distance("/"), 22u);39 // Sibling (up+down)40 EXPECT_EQ(D.distance("tools/clang/lib/Format/AnotherFile.cpp"), 8u);41 // Cousin (up+up+down+down)42 EXPECT_EQ(D.distance("include/llvm/Support/Allocator.h"), 18u);43 // First cousin, once removed (up+up+up+down+down)44 EXPECT_EQ(D.distance("include/llvm-c/Core.h"), 23u);45}46 47TEST(FileDistanceTests, BadSource) {48 // We mustn't assume that paths above sources are best reached via them.49 FileDistanceOptions Opts;50 Opts.UpCost = 5;51 Opts.DownCost = 3;52 SourceParams CostLots;53 CostLots.Cost = 100;54 FileDistance D({{"a", SourceParams()}, {"b/b/b", CostLots}}, Opts);55 EXPECT_EQ(D.distance("b"), 8u); // a+up+down, not b+up+up56 EXPECT_EQ(D.distance("b/b/b"), 14u); // a+up+down+down+down, not b57 EXPECT_EQ(D.distance("b/b/b/c"), 17u); // a+up+down+down+down+down, not b+down58}59 60// Force the unittest URI scheme to be linked,61[[maybe_unused]] static int UseUnittestScheme = UnittestSchemeAnchorSource;62 63TEST(FileDistanceTests, URI) {64 FileDistanceOptions Opts;65 Opts.UpCost = 5;66 Opts.DownCost = 3;67 SourceParams CostLots;68 CostLots.Cost = 1000;69 70 URIDistance D({{testPath("foo"), CostLots},71 {"/not/a/testpath", SourceParams()},72 {"C:\\not\\a\\testpath", SourceParams()}},73 Opts);74#ifdef _WIN3275 EXPECT_EQ(D.distance("file:///C%3a/not/a/testpath/either"), 3u);76#else77 EXPECT_EQ(D.distance("file:///not/a/testpath/either"), 3u);78#endif79 EXPECT_EQ(D.distance("unittest:///foo"), 1000u);80 EXPECT_EQ(D.distance("unittest:///bar"), 1008u);81}82 83TEST(FileDistance, LimitUpTraversals) {84 FileDistanceOptions Opts;85 Opts.UpCost = Opts.DownCost = 1;86 SourceParams CheapButLimited, CostLots;87 CheapButLimited.MaxUpTraversals = 1;88 CostLots.Cost = 100;89 90 FileDistance D({{"/", CostLots}, {"/a/b/c", CheapButLimited}}, Opts);91 EXPECT_EQ(D.distance("/a"), 101u);92 EXPECT_EQ(D.distance("/a/z"), 102u);93 EXPECT_EQ(D.distance("/a/b"), 1u);94 EXPECT_EQ(D.distance("/a/b/z"), 2u);95}96 97TEST(FileDistance, DisallowDownTraversalsFromRoot) {98 FileDistanceOptions Opts;99 Opts.UpCost = Opts.DownCost = 1;100 Opts.AllowDownTraversalFromRoot = false;101 SourceParams CostLots;102 CostLots.Cost = 100;103 104 FileDistance D({{"/", SourceParams()}, {"/a/b/c", CostLots}}, Opts);105 EXPECT_EQ(D.distance("/"), 0u);106 EXPECT_EQ(D.distance("/a"), 102u);107 EXPECT_EQ(D.distance("/a/b"), 101u);108 EXPECT_EQ(D.distance("/x"), FileDistance::Unreachable);109}110 111TEST(ScopeDistance, Smoke) {112 ScopeDistance D({"x::y::z", "x::", "", "a::"});113 EXPECT_EQ(D.distance("x::y::z::"), 0u);114 EXPECT_GT(D.distance("x::y::"), D.distance("x::y::z::"));115 EXPECT_GT(D.distance("x::"), D.distance("x::y::"));116 EXPECT_GT(D.distance("x::y::z::down::"), D.distance("x::y::"));117 EXPECT_GT(D.distance(""), D.distance("a::"));118 EXPECT_GT(D.distance("x::"), D.distance("a::"));119}120 121} // namespace122} // namespace clangd123} // namespace clang124