1 //===-- FileDistanceTests.cpp ------------------------*- C++ -*-----------===//
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-exception
7 //===----------------------------------------------------------------------===//
9 #include "FileDistance.h"
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
18 TEST(FileDistanceTests
, Distance
) {
19 FileDistanceOptions Opts
;
25 {{"tools/clang/lib/Format/FormatToken.cpp", SourceParams()},
26 {"tools/clang/include/clang/Format/FormatToken.h", SourceParams()},
27 {"include/llvm/ADT/StringRef.h", CostTwo
}},
31 EXPECT_EQ(D
.distance("tools/clang/lib/Format/FormatToken.cpp"), 0u);
32 EXPECT_EQ(D
.distance("include/llvm/ADT/StringRef.h"), 2u);
34 EXPECT_EQ(D
.distance("tools/clang/lib/Format/"), 5u);
36 EXPECT_EQ(D
.distance("tools/clang/lib/Format/FormatToken.cpp/Oops"), 3u);
37 // Ancestor (up+up+up+up)
38 EXPECT_EQ(D
.distance("/"), 22u);
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);
47 TEST(FileDistanceTests
, BadSource
) {
48 // We mustn't assume that paths above sources are best reached via them.
49 FileDistanceOptions Opts
;
52 SourceParams CostLots
;
54 FileDistance
D({{"a", SourceParams()}, {"b/b/b", CostLots
}}, Opts
);
55 EXPECT_EQ(D
.distance("b"), 8u); // a+up+down, not b+up+up
56 EXPECT_EQ(D
.distance("b/b/b"), 14u); // a+up+down+down+down, not b
57 EXPECT_EQ(D
.distance("b/b/b/c"), 17u); // a+up+down+down+down+down, not b+down
60 // Force the unittest URI scheme to be linked,
61 static int LLVM_ATTRIBUTE_UNUSED UseUnittestScheme
= UnittestSchemeAnchorSource
;
63 TEST(FileDistanceTests
, URI
) {
64 FileDistanceOptions Opts
;
67 SourceParams CostLots
;
70 URIDistance
D({{testPath("foo"), CostLots
},
71 {"/not/a/testpath", SourceParams()},
72 {"C:\\not\\a\\testpath", SourceParams()}},
75 EXPECT_EQ(D
.distance("file:///C%3a/not/a/testpath/either"), 3u);
77 EXPECT_EQ(D
.distance("file:///not/a/testpath/either"), 3u);
79 EXPECT_EQ(D
.distance("unittest:///foo"), 1000u);
80 EXPECT_EQ(D
.distance("unittest:///bar"), 1008u);
83 TEST(FileDistance
, LimitUpTraversals
) {
84 FileDistanceOptions Opts
;
85 Opts
.UpCost
= Opts
.DownCost
= 1;
86 SourceParams CheapButLimited
, CostLots
;
87 CheapButLimited
.MaxUpTraversals
= 1;
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);
97 TEST(FileDistance
, DisallowDownTraversalsFromRoot
) {
98 FileDistanceOptions Opts
;
99 Opts
.UpCost
= Opts
.DownCost
= 1;
100 Opts
.AllowDownTraversalFromRoot
= false;
101 SourceParams CostLots
;
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
);
111 TEST(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::"));
122 } // namespace clangd