1 | //===-- FileSpecTest.cpp --------------------------------------------------===// |
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-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "gtest/gtest.h" |
10 | |
11 | #include "lldb/Utility/FileSpec.h" |
12 | |
13 | using namespace lldb_private; |
14 | |
15 | static FileSpec PosixSpec(llvm::StringRef path) { |
16 | return FileSpec(path, FileSpec::Style::posix); |
17 | } |
18 | |
19 | static FileSpec WindowsSpec(llvm::StringRef path) { |
20 | return FileSpec(path, FileSpec::Style::windows); |
21 | } |
22 | |
23 | TEST(FileSpecTest, FileAndDirectoryComponents) { |
24 | FileSpec fs_posix("/foo/bar" , FileSpec::Style::posix); |
25 | EXPECT_STREQ("/foo/bar" , fs_posix.GetPath().c_str()); |
26 | EXPECT_STREQ("/foo" , fs_posix.GetDirectory().GetCString()); |
27 | EXPECT_STREQ("bar" , fs_posix.GetFilename().GetCString()); |
28 | |
29 | FileSpec fs_windows("F:\\bar" , FileSpec::Style::windows); |
30 | EXPECT_STREQ("F:\\bar" , fs_windows.GetPath().c_str()); |
31 | // EXPECT_STREQ("F:\\", fs_windows.GetDirectory().GetPath().c_str()); // It returns |
32 | // "F:/" |
33 | EXPECT_STREQ("bar" , fs_windows.GetFilename().GetCString()); |
34 | |
35 | FileSpec fs_posix_root("/" , FileSpec::Style::posix); |
36 | EXPECT_STREQ("/" , fs_posix_root.GetPath().c_str()); |
37 | EXPECT_EQ(nullptr, fs_posix_root.GetDirectory().GetCString()); |
38 | EXPECT_STREQ("/" , fs_posix_root.GetFilename().GetCString()); |
39 | |
40 | FileSpec fs_net_drive("//net" , FileSpec::Style::posix); |
41 | EXPECT_STREQ("//net" , fs_net_drive.GetPath().c_str()); |
42 | EXPECT_EQ(nullptr, fs_net_drive.GetDirectory().GetCString()); |
43 | EXPECT_STREQ("//net" , fs_net_drive.GetFilename().GetCString()); |
44 | |
45 | FileSpec fs_net_root("//net/" , FileSpec::Style::posix); |
46 | EXPECT_STREQ("//net/" , fs_net_root.GetPath().c_str()); |
47 | EXPECT_STREQ("//net" , fs_net_root.GetDirectory().GetCString()); |
48 | EXPECT_STREQ("/" , fs_net_root.GetFilename().GetCString()); |
49 | |
50 | FileSpec fs_windows_drive("F:" , FileSpec::Style::windows); |
51 | EXPECT_STREQ("F:" , fs_windows_drive.GetPath().c_str()); |
52 | EXPECT_EQ(nullptr, fs_windows_drive.GetDirectory().GetCString()); |
53 | EXPECT_STREQ("F:" , fs_windows_drive.GetFilename().GetCString()); |
54 | |
55 | FileSpec fs_windows_root("F:\\" , FileSpec::Style::windows); |
56 | EXPECT_STREQ("F:\\" , fs_windows_root.GetPath().c_str()); |
57 | EXPECT_STREQ("F:" , fs_windows_root.GetDirectory().GetCString()); |
58 | // EXPECT_STREQ("\\", fs_windows_root.GetFilename().GetCString()); // It |
59 | // returns "/" |
60 | |
61 | FileSpec fs_posix_long("/foo/bar/baz" , FileSpec::Style::posix); |
62 | EXPECT_STREQ("/foo/bar/baz" , fs_posix_long.GetPath().c_str()); |
63 | EXPECT_STREQ("/foo/bar" , fs_posix_long.GetDirectory().GetCString()); |
64 | EXPECT_STREQ("baz" , fs_posix_long.GetFilename().GetCString()); |
65 | |
66 | FileSpec fs_windows_long("F:\\bar\\baz" , FileSpec::Style::windows); |
67 | EXPECT_STREQ("F:\\bar\\baz" , fs_windows_long.GetPath().c_str()); |
68 | // EXPECT_STREQ("F:\\bar", fs_windows_long.GetDirectory().GetCString()); // It |
69 | // returns "F:/bar" |
70 | EXPECT_STREQ("baz" , fs_windows_long.GetFilename().GetCString()); |
71 | |
72 | FileSpec fs_posix_trailing_slash("/foo/bar/" , FileSpec::Style::posix); |
73 | EXPECT_STREQ("/foo/bar" , fs_posix_trailing_slash.GetPath().c_str()); |
74 | EXPECT_STREQ("/foo" , fs_posix_trailing_slash.GetDirectory().GetCString()); |
75 | EXPECT_STREQ("bar" , fs_posix_trailing_slash.GetFilename().GetCString()); |
76 | |
77 | FileSpec fs_windows_trailing_slash("F:\\bar\\" , FileSpec::Style::windows); |
78 | EXPECT_STREQ("F:\\bar" , fs_windows_trailing_slash.GetPath().c_str()); |
79 | EXPECT_STREQ("bar" , fs_windows_trailing_slash.GetFilename().GetCString()); |
80 | } |
81 | |
82 | TEST(FileSpecTest, AppendPathComponent) { |
83 | FileSpec fs_posix("/foo" , FileSpec::Style::posix); |
84 | fs_posix.AppendPathComponent(component: "bar" ); |
85 | EXPECT_STREQ("/foo/bar" , fs_posix.GetPath().c_str()); |
86 | EXPECT_STREQ("/foo" , fs_posix.GetDirectory().GetCString()); |
87 | EXPECT_STREQ("bar" , fs_posix.GetFilename().GetCString()); |
88 | |
89 | FileSpec fs_posix_2("/foo" , FileSpec::Style::posix); |
90 | fs_posix_2.AppendPathComponent(component: "//bar/baz" ); |
91 | EXPECT_STREQ("/foo/bar/baz" , fs_posix_2.GetPath().c_str()); |
92 | EXPECT_STREQ("/foo/bar" , fs_posix_2.GetDirectory().GetCString()); |
93 | EXPECT_STREQ("baz" , fs_posix_2.GetFilename().GetCString()); |
94 | |
95 | FileSpec fs_windows("F:\\bar" , FileSpec::Style::windows); |
96 | fs_windows.AppendPathComponent(component: "baz" ); |
97 | EXPECT_STREQ("F:\\bar\\baz" , fs_windows.GetPath().c_str()); |
98 | // EXPECT_STREQ("F:\\bar", fs_windows.GetDirectory().GetCString()); // It |
99 | // returns "F:/bar" |
100 | EXPECT_STREQ("baz" , fs_windows.GetFilename().GetCString()); |
101 | |
102 | FileSpec fs_posix_root("/" , FileSpec::Style::posix); |
103 | fs_posix_root.AppendPathComponent(component: "bar" ); |
104 | EXPECT_STREQ("/bar" , fs_posix_root.GetPath().c_str()); |
105 | EXPECT_STREQ("/" , fs_posix_root.GetDirectory().GetCString()); |
106 | EXPECT_STREQ("bar" , fs_posix_root.GetFilename().GetCString()); |
107 | |
108 | FileSpec fs_windows_root("F:\\" , FileSpec::Style::windows); |
109 | fs_windows_root.AppendPathComponent(component: "bar" ); |
110 | EXPECT_STREQ("F:\\bar" , fs_windows_root.GetPath().c_str()); |
111 | // EXPECT_STREQ("F:\\", fs_windows_root.GetDirectory().GetCString()); // It |
112 | // returns "F:/" |
113 | EXPECT_STREQ("bar" , fs_windows_root.GetFilename().GetCString()); |
114 | } |
115 | |
116 | TEST(FileSpecTest, CopyByAppendingPathComponent) { |
117 | FileSpec fs = PosixSpec(path: "/foo" ).CopyByAppendingPathComponent(component: "bar" ); |
118 | EXPECT_STREQ("/foo/bar" , fs.GetPath().c_str()); |
119 | EXPECT_STREQ("/foo" , fs.GetDirectory().GetCString()); |
120 | EXPECT_STREQ("bar" , fs.GetFilename().GetCString()); |
121 | } |
122 | |
123 | TEST(FileSpecTest, PrependPathComponent) { |
124 | FileSpec fs_posix("foo" , FileSpec::Style::posix); |
125 | fs_posix.PrependPathComponent(component: "/bar" ); |
126 | EXPECT_STREQ("/bar/foo" , fs_posix.GetPath().c_str()); |
127 | |
128 | FileSpec fs_posix_2("foo/bar" , FileSpec::Style::posix); |
129 | fs_posix_2.PrependPathComponent(component: "/baz" ); |
130 | EXPECT_STREQ("/baz/foo/bar" , fs_posix_2.GetPath().c_str()); |
131 | |
132 | FileSpec fs_windows("baz" , FileSpec::Style::windows); |
133 | fs_windows.PrependPathComponent(component: "F:\\bar" ); |
134 | EXPECT_STREQ("F:\\bar\\baz" , fs_windows.GetPath().c_str()); |
135 | |
136 | FileSpec fs_posix_root("bar" , FileSpec::Style::posix); |
137 | fs_posix_root.PrependPathComponent(component: "/" ); |
138 | EXPECT_STREQ("/bar" , fs_posix_root.GetPath().c_str()); |
139 | |
140 | FileSpec fs_windows_root("bar" , FileSpec::Style::windows); |
141 | fs_windows_root.PrependPathComponent(component: "F:\\" ); |
142 | EXPECT_STREQ("F:\\bar" , fs_windows_root.GetPath().c_str()); |
143 | } |
144 | |
145 | TEST(FileSpecTest, EqualSeparator) { |
146 | EXPECT_EQ(WindowsSpec("C:\\foo\\bar" ), WindowsSpec("C:/foo/bar" )); |
147 | } |
148 | |
149 | TEST(FileSpecTest, EqualDotsWindows) { |
150 | std::pair<const char *, const char *> tests[] = { |
151 | {R"(C:\foo\bar\baz)" , R"(C:\foo\foo\..\bar\baz)" }, |
152 | {R"(C:\bar\baz)" , R"(C:\foo\..\bar\baz)" }, |
153 | {R"(C:\bar\baz)" , R"(C:/foo/../bar/baz)" }, |
154 | {R"(C:/bar/baz)" , R"(C:\foo\..\bar\baz)" }, |
155 | {R"(C:\bar)" , R"(C:\foo\..\bar)" }, |
156 | {R"(C:\foo\bar)" , R"(C:\foo\.\bar)" }, |
157 | {R"(C:\foo\bar)" , R"(C:\foo\bar\.)" }, |
158 | }; |
159 | |
160 | for (const auto &test : tests) { |
161 | SCOPED_TRACE(llvm::Twine(test.first) + " <=> " + test.second); |
162 | EXPECT_EQ(WindowsSpec(test.first), WindowsSpec(test.second)); |
163 | } |
164 | } |
165 | |
166 | TEST(FileSpecTest, EqualDotsPosix) { |
167 | std::pair<const char *, const char *> tests[] = { |
168 | {R"(/foo/bar/baz)" , R"(/foo/foo/../bar/baz)" }, |
169 | {R"(/bar/baz)" , R"(/foo/../bar/baz)" }, |
170 | {R"(/bar)" , R"(/foo/../bar)" }, |
171 | {R"(/foo/bar)" , R"(/foo/./bar)" }, |
172 | {R"(/foo/bar)" , R"(/foo/bar/.)" }, |
173 | }; |
174 | |
175 | for (const auto &test : tests) { |
176 | SCOPED_TRACE(llvm::Twine(test.first) + " <=> " + test.second); |
177 | EXPECT_EQ(PosixSpec(test.first), PosixSpec(test.second)); |
178 | } |
179 | } |
180 | |
181 | TEST(FileSpecTest, EqualDotsPosixRoot) { |
182 | std::pair<const char *, const char *> tests[] = { |
183 | {R"(/)" , R"(/..)" }, |
184 | {R"(/)" , R"(/.)" }, |
185 | {R"(/)" , R"(/foo/..)" }, |
186 | }; |
187 | |
188 | for (const auto &test : tests) { |
189 | SCOPED_TRACE(llvm::Twine(test.first) + " <=> " + test.second); |
190 | EXPECT_EQ(PosixSpec(test.first), PosixSpec(test.second)); |
191 | } |
192 | } |
193 | |
194 | TEST(FileSpecTest, GuessPathStyle) { |
195 | EXPECT_EQ(FileSpec::Style::posix, FileSpec::GuessPathStyle("/foo/bar.txt" )); |
196 | EXPECT_EQ(FileSpec::Style::posix, FileSpec::GuessPathStyle("//net/bar.txt" )); |
197 | EXPECT_EQ(FileSpec::Style::windows, |
198 | FileSpec::GuessPathStyle(R"(C:\foo.txt)" )); |
199 | EXPECT_EQ(FileSpec::Style::windows, |
200 | FileSpec::GuessPathStyle(R"(C:/foo.txt)" )); |
201 | EXPECT_EQ(FileSpec::Style::windows, |
202 | FileSpec::GuessPathStyle(R"(\\net\foo.txt)" )); |
203 | EXPECT_EQ(FileSpec::Style::windows, FileSpec::GuessPathStyle(R"(Z:\)" )); |
204 | EXPECT_EQ(FileSpec::Style::windows, FileSpec::GuessPathStyle(R"(Z:/)" )); |
205 | EXPECT_EQ(std::nullopt, FileSpec::GuessPathStyle("foo.txt" )); |
206 | EXPECT_EQ(std::nullopt, FileSpec::GuessPathStyle("foo/bar.txt" )); |
207 | EXPECT_EQ(std::nullopt, FileSpec::GuessPathStyle("Z:" )); |
208 | } |
209 | |
210 | TEST(FileSpecTest, GetPath) { |
211 | std::pair<const char *, const char *> posix_tests[] = { |
212 | {"/foo/.././bar" , "/bar" }, |
213 | {"/foo/./../bar" , "/bar" }, |
214 | {"/foo/../bar" , "/bar" }, |
215 | {"/foo/./bar" , "/foo/bar" }, |
216 | {"/foo/.." , "/" }, |
217 | {"/foo/." , "/foo" }, |
218 | {"/foo//bar" , "/foo/bar" }, |
219 | {"/foo//bar/baz" , "/foo/bar/baz" }, |
220 | {"/foo//bar/./baz" , "/foo/bar/baz" }, |
221 | {"/./foo" , "/foo" }, |
222 | {"/" , "/" }, |
223 | {"//" , "/" }, |
224 | {"//net" , "//net" }, |
225 | {"/.." , "/" }, |
226 | {"/." , "/" }, |
227 | {".." , ".." }, |
228 | {"." , "." }, |
229 | {"../.." , "../.." }, |
230 | {"foo/.." , "." }, |
231 | {"foo/../bar" , "bar" }, |
232 | {"../foo/.." , ".." }, |
233 | {"./foo" , "foo" }, |
234 | {"././foo" , "foo" }, |
235 | {"../foo" , "../foo" }, |
236 | {"../../foo" , "../../foo" }, |
237 | }; |
238 | for (auto test : posix_tests) { |
239 | SCOPED_TRACE(llvm::Twine("test.first = " ) + test.first); |
240 | EXPECT_EQ(test.second, PosixSpec(test.first).GetPath()); |
241 | } |
242 | |
243 | std::pair<const char *, const char *> windows_tests[] = { |
244 | {R"(c:\bar\..\bar)" , R"(c:\bar)" }, |
245 | {R"(c:\bar\.\bar)" , R"(c:\bar\bar)" }, |
246 | {R"(c:\bar\..)" , R"(c:\)" }, |
247 | {R"(c:\bar\.)" , R"(c:\bar)" }, |
248 | {R"(c:\.\bar)" , R"(c:\bar)" }, |
249 | {R"(\)" , R"(\)" }, |
250 | {R"(\\)" , R"(\)" }, |
251 | {R"(\\net)" , R"(\\net)" }, |
252 | {R"(c:\..)" , R"(c:\)" }, |
253 | {R"(c:\.)" , R"(c:\)" }, |
254 | {R"(\..)" , R"(\)" }, |
255 | // {R"(c:..)", R"(c:..)"}, |
256 | {R"(..)" , R"(..)" }, |
257 | {R"(.)" , R"(.)" }, |
258 | {R"(c:..\..)" , R"(c:)" }, |
259 | {R"(..\..)" , R"(..\..)" }, |
260 | {R"(foo\..)" , R"(.)" }, |
261 | {R"(foo\..\bar)" , R"(bar)" }, |
262 | {R"(..\foo\..)" , R"(..)" }, |
263 | {R"(.\foo)" , R"(foo)" }, |
264 | {R"(.\.\foo)" , R"(foo)" }, |
265 | {R"(..\foo)" , R"(..\foo)" }, |
266 | {R"(..\..\foo)" , R"(..\..\foo)" }, |
267 | }; |
268 | for (auto test : windows_tests) { |
269 | SCOPED_TRACE(llvm::Twine("test.first = " ) + test.first); |
270 | EXPECT_EQ(test.second, WindowsSpec(test.first).GetPath()); |
271 | } |
272 | } |
273 | |
274 | TEST(FileSpecTest, FormatFileSpec) { |
275 | auto win = FileSpec::Style::windows; |
276 | |
277 | FileSpec F; |
278 | EXPECT_EQ("(empty)" , llvm::formatv("{0}" , F).str()); |
279 | EXPECT_EQ("(empty)" , llvm::formatv("{0:D}" , F).str()); |
280 | EXPECT_EQ("(empty)" , llvm::formatv("{0:F}" , F).str()); |
281 | |
282 | F = FileSpec("C:\\foo\\bar.txt" , win); |
283 | EXPECT_EQ("C:\\foo\\bar.txt" , llvm::formatv("{0}" , F).str()); |
284 | EXPECT_EQ("C:\\foo\\" , llvm::formatv("{0:D}" , F).str()); |
285 | EXPECT_EQ("bar.txt" , llvm::formatv("{0:F}" , F).str()); |
286 | |
287 | F = FileSpec("foo\\bar.txt" , win); |
288 | EXPECT_EQ("foo\\bar.txt" , llvm::formatv("{0}" , F).str()); |
289 | EXPECT_EQ("foo\\" , llvm::formatv("{0:D}" , F).str()); |
290 | EXPECT_EQ("bar.txt" , llvm::formatv("{0:F}" , F).str()); |
291 | |
292 | F = FileSpec("foo" , win); |
293 | EXPECT_EQ("foo" , llvm::formatv("{0}" , F).str()); |
294 | EXPECT_EQ("foo" , llvm::formatv("{0:F}" , F).str()); |
295 | EXPECT_EQ("(empty)" , llvm::formatv("{0:D}" , F).str()); |
296 | } |
297 | |
298 | TEST(FileSpecTest, IsRelative) { |
299 | llvm::StringRef not_relative[] = { |
300 | "/" , |
301 | "/a" , |
302 | "/a/" , |
303 | "/a/b" , |
304 | "/a/b/" , |
305 | "//" , |
306 | "//a/" , |
307 | "//a/b" , |
308 | "//a/b/" , |
309 | "~" , |
310 | "~/" , |
311 | "~/a" , |
312 | "~/a/" , |
313 | "~/a/b" , |
314 | "~/a/b/" , |
315 | "/foo/." , |
316 | "/foo/.." , |
317 | "/foo/../" , |
318 | "/foo/../." , |
319 | }; |
320 | for (const auto &path: not_relative) { |
321 | SCOPED_TRACE(path); |
322 | EXPECT_FALSE(PosixSpec(path).IsRelative()); |
323 | } |
324 | llvm::StringRef is_relative[] = { |
325 | "." , |
326 | "./" , |
327 | ".///" , |
328 | "a" , |
329 | "./a" , |
330 | "./a/" , |
331 | "./a/" , |
332 | "./a/b" , |
333 | "./a/b/" , |
334 | "../foo" , |
335 | "foo/bar.c" , |
336 | "./foo/bar.c" |
337 | }; |
338 | for (const auto &path: is_relative) { |
339 | SCOPED_TRACE(path); |
340 | EXPECT_TRUE(PosixSpec(path).IsRelative()); |
341 | } |
342 | } |
343 | |
344 | TEST(FileSpecTest, RemoveLastPathComponent) { |
345 | FileSpec fs_posix("/foo/bar/baz" , FileSpec::Style::posix); |
346 | EXPECT_STREQ("/foo/bar/baz" , fs_posix.GetPath().c_str()); |
347 | EXPECT_TRUE(fs_posix.RemoveLastPathComponent()); |
348 | EXPECT_STREQ("/foo/bar" , fs_posix.GetPath().c_str()); |
349 | EXPECT_TRUE(fs_posix.RemoveLastPathComponent()); |
350 | EXPECT_STREQ("/foo" , fs_posix.GetPath().c_str()); |
351 | EXPECT_TRUE(fs_posix.RemoveLastPathComponent()); |
352 | EXPECT_STREQ("/" , fs_posix.GetPath().c_str()); |
353 | EXPECT_FALSE(fs_posix.RemoveLastPathComponent()); |
354 | EXPECT_STREQ("/" , fs_posix.GetPath().c_str()); |
355 | |
356 | FileSpec fs_posix_relative("./foo/bar/baz" , FileSpec::Style::posix); |
357 | EXPECT_STREQ("foo/bar/baz" , fs_posix_relative.GetPath().c_str()); |
358 | EXPECT_TRUE(fs_posix_relative.RemoveLastPathComponent()); |
359 | EXPECT_STREQ("foo/bar" , fs_posix_relative.GetPath().c_str()); |
360 | EXPECT_TRUE(fs_posix_relative.RemoveLastPathComponent()); |
361 | EXPECT_STREQ("foo" , fs_posix_relative.GetPath().c_str()); |
362 | EXPECT_FALSE(fs_posix_relative.RemoveLastPathComponent()); |
363 | EXPECT_STREQ("foo" , fs_posix_relative.GetPath().c_str()); |
364 | |
365 | FileSpec fs_posix_relative2("./" , FileSpec::Style::posix); |
366 | EXPECT_STREQ("." , fs_posix_relative2.GetPath().c_str()); |
367 | EXPECT_FALSE(fs_posix_relative2.RemoveLastPathComponent()); |
368 | EXPECT_STREQ("." , fs_posix_relative2.GetPath().c_str()); |
369 | EXPECT_FALSE(fs_posix_relative.RemoveLastPathComponent()); |
370 | EXPECT_STREQ("." , fs_posix_relative2.GetPath().c_str()); |
371 | |
372 | FileSpec fs_windows("C:\\foo\\bar\\baz" , FileSpec::Style::windows); |
373 | EXPECT_STREQ("C:\\foo\\bar\\baz" , fs_windows.GetPath().c_str()); |
374 | EXPECT_TRUE(fs_windows.RemoveLastPathComponent()); |
375 | EXPECT_STREQ("C:\\foo\\bar" , fs_windows.GetPath().c_str()); |
376 | EXPECT_TRUE(fs_windows.RemoveLastPathComponent()); |
377 | EXPECT_STREQ("C:\\foo" , fs_windows.GetPath().c_str()); |
378 | EXPECT_TRUE(fs_windows.RemoveLastPathComponent()); |
379 | EXPECT_STREQ("C:\\" , fs_windows.GetPath().c_str()); |
380 | EXPECT_TRUE(fs_windows.RemoveLastPathComponent()); |
381 | EXPECT_STREQ("C:" , fs_windows.GetPath().c_str()); |
382 | EXPECT_FALSE(fs_windows.RemoveLastPathComponent()); |
383 | EXPECT_STREQ("C:" , fs_windows.GetPath().c_str()); |
384 | } |
385 | |
386 | TEST(FileSpecTest, Equal) { |
387 | auto Eq = [](const char *a, const char *b, bool full) { |
388 | return FileSpec::Equal(a: PosixSpec(path: a), b: PosixSpec(path: b), full); |
389 | }; |
390 | EXPECT_TRUE(Eq("/foo/bar" , "/foo/bar" , true)); |
391 | EXPECT_TRUE(Eq("/foo/bar" , "/foo/bar" , false)); |
392 | |
393 | EXPECT_FALSE(Eq("/foo/bar" , "/foo/baz" , true)); |
394 | EXPECT_FALSE(Eq("/foo/bar" , "/foo/baz" , false)); |
395 | |
396 | EXPECT_FALSE(Eq("/bar/foo" , "/baz/foo" , true)); |
397 | EXPECT_FALSE(Eq("/bar/foo" , "/baz/foo" , false)); |
398 | |
399 | EXPECT_FALSE(Eq("/bar/foo" , "foo" , true)); |
400 | EXPECT_TRUE(Eq("/bar/foo" , "foo" , false)); |
401 | |
402 | EXPECT_FALSE(Eq("foo" , "/bar/foo" , true)); |
403 | EXPECT_TRUE(Eq("foo" , "/bar/foo" , false)); |
404 | } |
405 | |
406 | TEST(FileSpecTest, Match) { |
407 | auto Match = [](const char *pattern, const char *file) { |
408 | return FileSpec::Match(pattern: PosixSpec(path: pattern), file: PosixSpec(path: file)); |
409 | }; |
410 | EXPECT_TRUE(Match("/foo/bar" , "/foo/bar" )); |
411 | EXPECT_FALSE(Match("/foo/bar" , "/oof/bar" )); |
412 | EXPECT_FALSE(Match("/foo/bar" , "/foo/baz" )); |
413 | EXPECT_FALSE(Match("/foo/bar" , "bar" )); |
414 | EXPECT_FALSE(Match("/foo/bar" , "" )); |
415 | |
416 | EXPECT_TRUE(Match("bar" , "/foo/bar" )); |
417 | EXPECT_FALSE(Match("bar" , "/foo/baz" )); |
418 | EXPECT_TRUE(Match("bar" , "bar" )); |
419 | EXPECT_FALSE(Match("bar" , "baz" )); |
420 | EXPECT_FALSE(Match("bar" , "" )); |
421 | |
422 | EXPECT_TRUE(Match("" , "/foo/bar" )); |
423 | EXPECT_TRUE(Match("" , "" )); |
424 | |
425 | } |
426 | |
427 | TEST(FileSpecTest, TestAbsoluteCaching) { |
428 | // Test that if we modify a path that we recalculate if a path is relative |
429 | // or absolute correctly. The test below calls set accessors and functions |
430 | // that change the path and verifies that the FileSpec::IsAbsolute() returns |
431 | // the correct value. |
432 | FileSpec file = PosixSpec(path: "/tmp/a" ); |
433 | EXPECT_TRUE(file.IsAbsolute()); |
434 | file.ClearDirectory(); |
435 | EXPECT_FALSE(file.IsAbsolute()); |
436 | file.SetDirectory("/tmp" ); |
437 | EXPECT_TRUE(file.IsAbsolute()); |
438 | file.SetDirectory("." ); |
439 | EXPECT_FALSE(file.IsAbsolute()); |
440 | file.SetPath("/log.txt" ); |
441 | EXPECT_TRUE(file.IsAbsolute()); |
442 | file.RemoveLastPathComponent(); |
443 | EXPECT_TRUE(file.IsAbsolute()); |
444 | file.ClearFilename(); |
445 | EXPECT_FALSE(file.IsAbsolute()); |
446 | file.AppendPathComponent(component: "foo.txt" ); |
447 | EXPECT_FALSE(file.IsAbsolute()); |
448 | file.PrependPathComponent(component: "/tmp" ); |
449 | EXPECT_TRUE(file.IsAbsolute()); |
450 | } |
451 | |
452 | TEST(FileSpecTest, TestFileNameExtensions) { |
453 | FileSpec dylib = PosixSpec(path: "/tmp/foo.dylib" ); |
454 | FileSpec exe = PosixSpec(path: "/tmp/foo" ); |
455 | FileSpec dSYM = PosixSpec(path: "/tmp/foo.dSYM/" ); |
456 | FileSpec just_dot = PosixSpec(path: "/tmp/bar." ); |
457 | |
458 | EXPECT_TRUE(dylib.GetFileNameExtension() == ".dylib" ); |
459 | EXPECT_TRUE(exe.GetFileNameExtension() == llvm::StringRef()); |
460 | EXPECT_TRUE(dSYM.GetFileNameExtension() == ".dSYM" ); |
461 | EXPECT_TRUE(just_dot.GetFileNameExtension() == "." ); |
462 | |
463 | FileSpec dll = WindowsSpec(path: "C:\\tmp\\foo.dll" ); |
464 | FileSpec win_noext = WindowsSpec(path: "C:\\tmp\\foo" ); |
465 | |
466 | EXPECT_TRUE(dll.GetFileNameExtension() == ".dll" ); |
467 | EXPECT_TRUE(win_noext.GetFileNameExtension() == llvm::StringRef()); |
468 | } |
469 | |
470 | TEST(FileSpecTest, TestFileNameStrippingExtension) { |
471 | FileSpec dylib = PosixSpec(path: "/tmp/foo.dylib" ); |
472 | FileSpec exe = PosixSpec(path: "/tmp/foo" ); |
473 | FileSpec just_dot = PosixSpec(path: "/tmp/bar." ); |
474 | |
475 | EXPECT_TRUE(dylib.GetFileNameStrippingExtension() == "foo" ); |
476 | EXPECT_TRUE(exe.GetFileNameStrippingExtension() == "foo" ); |
477 | EXPECT_TRUE(just_dot.GetFileNameStrippingExtension() == "bar" ); |
478 | |
479 | FileSpec dll = WindowsSpec(path: "C:\\tmp\\foo.dll" ); |
480 | FileSpec win_noext = WindowsSpec(path: "C:\\tmp\\foo" ); |
481 | |
482 | EXPECT_TRUE(dll.GetFileNameStrippingExtension() == "foo" ); |
483 | EXPECT_TRUE(win_noext.GetFileNameStrippingExtension() == "foo" ); |
484 | } |
485 | |
486 | TEST(FileSpecTest, TestIsSourceImplementationFile) { |
487 | FileSpec c_src = PosixSpec(path: "/tmp/foo.c" ); |
488 | FileSpec txt_file = PosixSpec(path: "/tmp/foo.txt" ); |
489 | FileSpec executable = PosixSpec(path: "/tmp/foo" ); |
490 | FileSpec just_dot = PosixSpec(path: "/tmp/bar." ); |
491 | |
492 | EXPECT_TRUE(c_src.IsSourceImplementationFile()); |
493 | EXPECT_FALSE(txt_file.IsSourceImplementationFile()); |
494 | EXPECT_FALSE(executable.IsSourceImplementationFile()); |
495 | EXPECT_FALSE(just_dot.IsSourceImplementationFile()); |
496 | |
497 | FileSpec cpp_src = WindowsSpec(path: "C:\\tmp\\foo.cpp" ); |
498 | FileSpec dll = WindowsSpec(path: "C:\\tmp\\foo.dll" ); |
499 | FileSpec win_noext = WindowsSpec(path: "C:\\tmp\\foo" ); |
500 | FileSpec exe = WindowsSpec(path: "C:\\tmp\\foo.exe" ); |
501 | |
502 | EXPECT_TRUE(cpp_src.IsSourceImplementationFile()); |
503 | EXPECT_FALSE(dll.IsSourceImplementationFile()); |
504 | EXPECT_FALSE(win_noext.IsSourceImplementationFile()); |
505 | EXPECT_FALSE(exe.IsSourceImplementationFile()); |
506 | } |
507 | |
508 | TEST(FileSpecTest, TestGetComponents) { |
509 | std::pair<llvm::StringRef, std::vector<llvm::StringRef>> PosixTests[] = { |
510 | {"/" , {}}, |
511 | {"/foo" , {"foo" }}, |
512 | {"/foo/" , {"foo" }}, |
513 | {"/foo/bar" , {"foo" , "bar" }}, |
514 | {"/llvm-project/lldb/unittests/Utility/FileSpecTest.cpp" , |
515 | {"llvm-project" , "lldb" , "unittests" , "Utility" , "FileSpecTest.cpp" }}, |
516 | }; |
517 | |
518 | for (const auto &pair : PosixTests) { |
519 | FileSpec file_spec = PosixSpec(path: pair.first); |
520 | EXPECT_EQ(file_spec.GetComponents(), pair.second); |
521 | } |
522 | |
523 | std::pair<llvm::StringRef, std::vector<llvm::StringRef>> WindowsTests[] = { |
524 | {"C:\\" , {"C:" }}, |
525 | {"C:\\Windows\\" , {"C:" , "Windows" }}, |
526 | {"C:\\Windows\\System32" , {"C:" , "Windows" , "System32" }}, |
527 | {"C:\\llvm-project\\lldb\\unittests\\Utility\\FileSpecTest.cpp" , |
528 | {"C:" , "llvm-project" , "lldb" , "unittests" , "Utility" , |
529 | "FileSpecTest.cpp" }}, |
530 | }; |
531 | |
532 | for (const auto &pair : WindowsTests) { |
533 | FileSpec file_spec = WindowsSpec(path: pair.first); |
534 | EXPECT_EQ(file_spec.GetComponents(), pair.second); |
535 | } |
536 | } |
537 | |