1 //===-- FileSpecTest.cpp ----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "gtest/gtest.h"
12 #include "lldb/Utility/FileSpec.h"
14 using namespace lldb_private;
16 TEST(FileSpecTest, FileAndDirectoryComponents) {
17 FileSpec fs_posix("/foo/bar", false, FileSpec::ePathSyntaxPosix);
18 EXPECT_STREQ("/foo/bar", fs_posix.GetCString());
19 EXPECT_STREQ("/foo", fs_posix.GetDirectory().GetCString());
20 EXPECT_STREQ("bar", fs_posix.GetFilename().GetCString());
22 FileSpec fs_windows("F:\\bar", false, FileSpec::ePathSyntaxWindows);
23 EXPECT_STREQ("F:\\bar", fs_windows.GetCString());
24 // EXPECT_STREQ("F:\\", fs_windows.GetDirectory().GetCString()); // It returns
26 EXPECT_STREQ("bar", fs_windows.GetFilename().GetCString());
28 FileSpec fs_posix_root("/", false, FileSpec::ePathSyntaxPosix);
29 EXPECT_STREQ("/", fs_posix_root.GetCString());
30 EXPECT_EQ(nullptr, fs_posix_root.GetDirectory().GetCString());
31 EXPECT_STREQ("/", fs_posix_root.GetFilename().GetCString());
33 FileSpec fs_windows_drive("F:", false, FileSpec::ePathSyntaxWindows);
34 EXPECT_STREQ("F:", fs_windows_drive.GetCString());
35 EXPECT_EQ(nullptr, fs_windows_drive.GetDirectory().GetCString());
36 EXPECT_STREQ("F:", fs_windows_drive.GetFilename().GetCString());
38 FileSpec fs_windows_root("F:\\", false, FileSpec::ePathSyntaxWindows);
39 EXPECT_STREQ("F:\\", fs_windows_root.GetCString());
40 EXPECT_STREQ("F:", fs_windows_root.GetDirectory().GetCString());
41 // EXPECT_STREQ("\\", fs_windows_root.GetFilename().GetCString()); // It
44 FileSpec fs_posix_long("/foo/bar/baz", false, FileSpec::ePathSyntaxPosix);
45 EXPECT_STREQ("/foo/bar/baz", fs_posix_long.GetCString());
46 EXPECT_STREQ("/foo/bar", fs_posix_long.GetDirectory().GetCString());
47 EXPECT_STREQ("baz", fs_posix_long.GetFilename().GetCString());
49 FileSpec fs_windows_long("F:\\bar\\baz", false, FileSpec::ePathSyntaxWindows);
50 EXPECT_STREQ("F:\\bar\\baz", fs_windows_long.GetCString());
51 // EXPECT_STREQ("F:\\bar", fs_windows_long.GetDirectory().GetCString()); // It
53 EXPECT_STREQ("baz", fs_windows_long.GetFilename().GetCString());
55 FileSpec fs_posix_trailing_slash("/foo/bar/", false,
56 FileSpec::ePathSyntaxPosix);
57 EXPECT_STREQ("/foo/bar/.", fs_posix_trailing_slash.GetCString());
58 EXPECT_STREQ("/foo/bar", fs_posix_trailing_slash.GetDirectory().GetCString());
59 EXPECT_STREQ(".", fs_posix_trailing_slash.GetFilename().GetCString());
61 FileSpec fs_windows_trailing_slash("F:\\bar\\", false,
62 FileSpec::ePathSyntaxWindows);
63 EXPECT_STREQ("F:\\bar\\.", fs_windows_trailing_slash.GetCString());
64 // EXPECT_STREQ("F:\\bar",
65 // fs_windows_trailing_slash.GetDirectory().GetCString()); // It returns
67 EXPECT_STREQ(".", fs_windows_trailing_slash.GetFilename().GetCString());
70 TEST(FileSpecTest, AppendPathComponent) {
71 FileSpec fs_posix("/foo", false, FileSpec::ePathSyntaxPosix);
72 fs_posix.AppendPathComponent("bar");
73 EXPECT_STREQ("/foo/bar", fs_posix.GetCString());
74 EXPECT_STREQ("/foo", fs_posix.GetDirectory().GetCString());
75 EXPECT_STREQ("bar", fs_posix.GetFilename().GetCString());
77 FileSpec fs_posix_2("/foo", false, FileSpec::ePathSyntaxPosix);
78 fs_posix_2.AppendPathComponent("//bar/baz");
79 EXPECT_STREQ("/foo/bar/baz", fs_posix_2.GetCString());
80 EXPECT_STREQ("/foo/bar", fs_posix_2.GetDirectory().GetCString());
81 EXPECT_STREQ("baz", fs_posix_2.GetFilename().GetCString());
83 FileSpec fs_windows("F:\\bar", false, FileSpec::ePathSyntaxWindows);
84 fs_windows.AppendPathComponent("baz");
85 EXPECT_STREQ("F:\\bar\\baz", fs_windows.GetCString());
86 // EXPECT_STREQ("F:\\bar", fs_windows.GetDirectory().GetCString()); // It
88 EXPECT_STREQ("baz", fs_windows.GetFilename().GetCString());
90 FileSpec fs_posix_root("/", false, FileSpec::ePathSyntaxPosix);
91 fs_posix_root.AppendPathComponent("bar");
92 EXPECT_STREQ("/bar", fs_posix_root.GetCString());
93 EXPECT_STREQ("/", fs_posix_root.GetDirectory().GetCString());
94 EXPECT_STREQ("bar", fs_posix_root.GetFilename().GetCString());
96 FileSpec fs_windows_root("F:\\", false, FileSpec::ePathSyntaxWindows);
97 fs_windows_root.AppendPathComponent("bar");
98 EXPECT_STREQ("F:\\bar", fs_windows_root.GetCString());
99 // EXPECT_STREQ("F:\\", fs_windows_root.GetDirectory().GetCString()); // It
101 EXPECT_STREQ("bar", fs_windows_root.GetFilename().GetCString());
104 TEST(FileSpecTest, CopyByAppendingPathComponent) {
105 FileSpec fs = FileSpec("/foo", false, FileSpec::ePathSyntaxPosix)
106 .CopyByAppendingPathComponent("bar");
107 EXPECT_STREQ("/foo/bar", fs.GetCString());
108 EXPECT_STREQ("/foo", fs.GetDirectory().GetCString());
109 EXPECT_STREQ("bar", fs.GetFilename().GetCString());
112 TEST(FileSpecTest, PrependPathComponent) {
113 FileSpec fs_posix("foo", false, FileSpec::ePathSyntaxPosix);
114 fs_posix.PrependPathComponent("/bar");
115 EXPECT_STREQ("/bar/foo", fs_posix.GetCString());
117 FileSpec fs_posix_2("foo/bar", false, FileSpec::ePathSyntaxPosix);
118 fs_posix_2.PrependPathComponent("/baz");
119 EXPECT_STREQ("/baz/foo/bar", fs_posix_2.GetCString());
121 FileSpec fs_windows("baz", false, FileSpec::ePathSyntaxWindows);
122 fs_windows.PrependPathComponent("F:\\bar");
123 EXPECT_STREQ("F:\\bar\\baz", fs_windows.GetCString());
125 FileSpec fs_posix_root("bar", false, FileSpec::ePathSyntaxPosix);
126 fs_posix_root.PrependPathComponent("/");
127 EXPECT_STREQ("/bar", fs_posix_root.GetCString());
129 FileSpec fs_windows_root("bar", false, FileSpec::ePathSyntaxWindows);
130 fs_windows_root.PrependPathComponent("F:\\");
131 EXPECT_STREQ("F:\\bar", fs_windows_root.GetCString());
134 static void Compare(const FileSpec &one, const FileSpec &two, bool full_match,
135 bool remove_backup_dots, bool result) {
136 EXPECT_EQ(result, FileSpec::Equal(one, two, full_match, remove_backup_dots))
137 << "File one: " << one.GetCString() << "\nFile two: " << two.GetCString()
138 << "\nFull match: " << full_match
139 << "\nRemove backup dots: " << remove_backup_dots;
142 TEST(FileSpecTest, EqualSeparator) {
143 FileSpec backward("C:\\foo\\bar", false, FileSpec::ePathSyntaxWindows);
144 FileSpec forward("C:/foo/bar", false, FileSpec::ePathSyntaxWindows);
145 EXPECT_EQ(forward, backward);
147 const bool full_match = true;
148 const bool remove_backup_dots = true;
149 const bool match = true;
150 Compare(forward, backward, full_match, remove_backup_dots, match);
151 Compare(forward, backward, full_match, !remove_backup_dots, match);
152 Compare(forward, backward, !full_match, remove_backup_dots, match);
153 Compare(forward, backward, !full_match, !remove_backup_dots, match);
156 TEST(FileSpecTest, EqualDotsWindows) {
157 const bool full_match = true;
158 const bool remove_backup_dots = true;
159 const bool match = true;
160 std::pair<const char *, const char *> tests[] = {
161 {R"(C:\foo\bar\baz)", R"(C:\foo\foo\..\bar\baz)"},
162 {R"(C:\bar\baz)", R"(C:\foo\..\bar\baz)"},
163 {R"(C:\bar\baz)", R"(C:/foo/../bar/baz)"},
164 {R"(C:/bar/baz)", R"(C:\foo\..\bar\baz)"},
165 {R"(C:\bar)", R"(C:\foo\..\bar)"},
166 {R"(C:\foo\bar)", R"(C:\foo\.\bar)"},
167 {R"(C:\foo\bar)", R"(C:\foo\bar\.)"},
170 for(const auto &test: tests) {
171 FileSpec one(test.first, false, FileSpec::ePathSyntaxWindows);
172 FileSpec two(test.second, false, FileSpec::ePathSyntaxWindows);
174 Compare(one, two, full_match, remove_backup_dots, match);
175 Compare(one, two, full_match, !remove_backup_dots, !match);
176 Compare(one, two, !full_match, remove_backup_dots, match);
177 Compare(one, two, !full_match, !remove_backup_dots, !match);
182 TEST(FileSpecTest, EqualDotsPosix) {
183 const bool full_match = true;
184 const bool remove_backup_dots = true;
185 const bool match = true;
186 std::pair<const char *, const char *> tests[] = {
187 {R"(/foo/bar/baz)", R"(/foo/foo/../bar/baz)"},
188 {R"(/bar/baz)", R"(/foo/../bar/baz)"},
189 {R"(/bar)", R"(/foo/../bar)"},
190 {R"(/foo/bar)", R"(/foo/./bar)"},
191 {R"(/foo/bar)", R"(/foo/bar/.)"},
194 for(const auto &test: tests) {
195 FileSpec one(test.first, false, FileSpec::ePathSyntaxPosix);
196 FileSpec two(test.second, false, FileSpec::ePathSyntaxPosix);
198 Compare(one, two, full_match, remove_backup_dots, match);
199 Compare(one, two, full_match, !remove_backup_dots, !match);
200 Compare(one, two, !full_match, remove_backup_dots, match);
201 Compare(one, two, !full_match, !remove_backup_dots, !match);
206 TEST(FileSpecTest, EqualDotsPosixRoot) {
207 const bool full_match = true;
208 const bool remove_backup_dots = true;
209 const bool match = true;
210 std::pair<const char *, const char *> tests[] = {
211 {R"(/)", R"(/..)"}, {R"(/)", R"(/.)"}, {R"(/)", R"(/foo/..)"},
214 for(const auto &test: tests) {
215 FileSpec one(test.first, false, FileSpec::ePathSyntaxPosix);
216 FileSpec two(test.second, false, FileSpec::ePathSyntaxPosix);
218 Compare(one, two, full_match, remove_backup_dots, match);
219 Compare(one, two, full_match, !remove_backup_dots, !match);
220 Compare(one, two, !full_match, remove_backup_dots, !match);
221 Compare(one, two, !full_match, !remove_backup_dots, !match);
225 TEST(FileSpecTest, GetNormalizedPath) {
226 std::pair<const char *, const char *> posix_tests[] = {
227 {"/foo/.././bar", "/bar"},
228 {"/foo/./../bar", "/bar"},
229 {"/foo/../bar", "/bar"},
230 {"/foo/./bar", "/foo/bar"},
233 {"/foo//bar", "/foo/bar"},
234 {"/foo//bar/baz", "/foo/bar/baz"},
235 {"/foo//bar/./baz", "/foo/bar/baz"},
246 {"foo/../bar", "bar"},
250 for (auto test : posix_tests) {
251 EXPECT_EQ(test.second,
252 FileSpec(test.first, false, FileSpec::ePathSyntaxPosix)
257 std::pair<const char *, const char *> windows_tests[] = {
258 {R"(c:\bar\..\bar)", R"(c:\bar)"},
259 {R"(c:\bar\.\bar)", R"(c:\bar\bar)"},
260 {R"(c:\bar\..)", R"(c:\)"},
261 {R"(c:\bar\.)", R"(c:\bar)"},
262 {R"(c:\.\bar)", R"(c:\bar)"},
264 // {R"(\\)", R"(\\)"},
265 // {R"(\\net)", R"(\\net)"},
266 {R"(c:\..)", R"(c:\)"},
267 {R"(c:\.)", R"(c:\)"},
269 // {R"(c:..)", R"(c:..)"},
272 {R"(c:..\..)", R"(c:..\..)"},
273 {R"(..\..)", R"(..\..)"},
274 {R"(foo\..)", R"(.)"},
275 {R"(foo\..\bar)", R"(bar)"},
276 {R"(..\foo\..)", R"(..)"},
277 {R"(.\foo)", R"(foo)"},
279 for (auto test : windows_tests) {
280 EXPECT_EQ(test.second,
281 FileSpec(test.first, false, FileSpec::ePathSyntaxWindows)
284 << "Original path: " << test.first;
288 TEST(FileSpecTest, FormatFileSpec) {
289 auto win = FileSpec::ePathSyntaxWindows;
292 EXPECT_EQ("(empty)", llvm::formatv("{0}", F).str());
293 EXPECT_EQ("(empty)", llvm::formatv("{0:D}", F).str());
294 EXPECT_EQ("(empty)", llvm::formatv("{0:F}", F).str());
296 F = FileSpec("C:\\foo\\bar.txt", false, win);
297 EXPECT_EQ("C:\\foo\\bar.txt", llvm::formatv("{0}", F).str());
298 EXPECT_EQ("C:\\foo\\", llvm::formatv("{0:D}", F).str());
299 EXPECT_EQ("bar.txt", llvm::formatv("{0:F}", F).str());
301 F = FileSpec("foo\\bar.txt", false, win);
302 EXPECT_EQ("foo\\bar.txt", llvm::formatv("{0}", F).str());
303 EXPECT_EQ("foo\\", llvm::formatv("{0:D}", F).str());
304 EXPECT_EQ("bar.txt", llvm::formatv("{0:F}", F).str());
306 F = FileSpec("foo", false, win);
307 EXPECT_EQ("foo", llvm::formatv("{0}", F).str());
308 EXPECT_EQ("foo", llvm::formatv("{0:F}", F).str());
309 EXPECT_EQ("(empty)", llvm::formatv("{0:D}", F).str());