1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/strings/string_util.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "build/build_config.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "tools/gn/filesystem_utils.h"
11 TEST(FilesystemUtils, FileExtensionOffset) {
12 EXPECT_EQ(std::string::npos, FindExtensionOffset(""));
13 EXPECT_EQ(std::string::npos, FindExtensionOffset("foo/bar/baz"));
14 EXPECT_EQ(4u, FindExtensionOffset("foo."));
15 EXPECT_EQ(4u, FindExtensionOffset("f.o.bar"));
16 EXPECT_EQ(std::string::npos, FindExtensionOffset("foo.bar/"));
17 EXPECT_EQ(std::string::npos, FindExtensionOffset("foo.bar/baz"));
20 TEST(FilesystemUtils, FindExtension) {
22 EXPECT_EQ("", FindExtension(&input).as_string());
23 input = "foo/bar/baz";
24 EXPECT_EQ("", FindExtension(&input).as_string());
26 EXPECT_EQ("", FindExtension(&input).as_string());
28 EXPECT_EQ("bar", FindExtension(&input).as_string());
30 EXPECT_EQ("", FindExtension(&input).as_string());
31 input = "foo.bar/baz";
32 EXPECT_EQ("", FindExtension(&input).as_string());
35 TEST(FilesystemUtils, FindFilenameOffset) {
36 EXPECT_EQ(0u, FindFilenameOffset(""));
37 EXPECT_EQ(0u, FindFilenameOffset("foo"));
38 EXPECT_EQ(4u, FindFilenameOffset("foo/"));
39 EXPECT_EQ(4u, FindFilenameOffset("foo/bar"));
42 TEST(FilesystemUtils, RemoveFilename) {
46 EXPECT_STREQ("", s.c_str());
50 EXPECT_STREQ("", s.c_str());
54 EXPECT_STREQ("/", s.c_str());
58 EXPECT_STREQ("foo/", s.c_str());
62 EXPECT_STREQ("foo/bar/", s.c_str());
65 TEST(FilesystemUtils, FindDir) {
67 EXPECT_EQ("", FindDir(&input));
69 EXPECT_EQ("/", FindDir(&input));
71 EXPECT_EQ("foo/", FindDir(&input));
72 input = "foo/bar/baz";
73 EXPECT_EQ("foo/bar/", FindDir(&input));
76 TEST(FilesystemUtils, FindLastDirComponent) {
78 EXPECT_EQ("", FindLastDirComponent(empty));
81 EXPECT_EQ("", FindLastDirComponent(root));
83 SourceDir srcroot("//");
84 EXPECT_EQ("", FindLastDirComponent(srcroot));
86 SourceDir regular1("//foo/");
87 EXPECT_EQ("foo", FindLastDirComponent(regular1));
89 SourceDir regular2("//foo/bar/");
90 EXPECT_EQ("bar", FindLastDirComponent(regular2));
93 TEST(FilesystemUtils, IsPathAbsolute) {
94 EXPECT_TRUE(IsPathAbsolute("/foo/bar"));
95 EXPECT_TRUE(IsPathAbsolute("/"));
96 EXPECT_FALSE(IsPathAbsolute(""));
97 EXPECT_FALSE(IsPathAbsolute("//"));
98 EXPECT_FALSE(IsPathAbsolute("//foo/bar"));
101 EXPECT_TRUE(IsPathAbsolute("C:/foo"));
102 EXPECT_TRUE(IsPathAbsolute("C:/"));
103 EXPECT_TRUE(IsPathAbsolute("C:\\foo"));
104 EXPECT_TRUE(IsPathAbsolute("C:\\"));
105 EXPECT_TRUE(IsPathAbsolute("/C:/foo"));
106 EXPECT_TRUE(IsPathAbsolute("/C:\\foo"));
110 TEST(FilesystemUtils, MakeAbsolutePathRelativeIfPossible) {
114 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("C:\\base", "C:\\base\\foo",
116 EXPECT_EQ("//foo", dest);
117 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("C:\\base", "/C:/base/foo",
119 EXPECT_EQ("//foo", dest);
120 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("c:\\base", "C:\\base\\foo\\",
122 EXPECT_EQ("//foo\\", dest);
124 EXPECT_FALSE(MakeAbsolutePathRelativeIfPossible("C:\\base", "C:\\ba", &dest));
125 EXPECT_FALSE(MakeAbsolutePathRelativeIfPossible("C:\\base",
130 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("/base", "/base/foo/", &dest));
131 EXPECT_EQ("//foo/", dest);
132 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("/base", "/base/foo", &dest));
133 EXPECT_EQ("//foo", dest);
134 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("/base/", "/base/foo/",
136 EXPECT_EQ("//foo/", dest);
138 EXPECT_FALSE(MakeAbsolutePathRelativeIfPossible("/base", "/ba", &dest));
139 EXPECT_FALSE(MakeAbsolutePathRelativeIfPossible("/base", "/notbase/foo",
144 TEST(FilesystemUtils, InvertDir) {
145 EXPECT_TRUE(InvertDir(SourceDir()) == "");
146 EXPECT_TRUE(InvertDir(SourceDir("/")) == "");
147 EXPECT_TRUE(InvertDir(SourceDir("//")) == "");
149 EXPECT_TRUE(InvertDir(SourceDir("//foo/bar")) == "../../");
150 EXPECT_TRUE(InvertDir(SourceDir("//foo\\bar")) == "../../");
151 EXPECT_TRUE(InvertDir(SourceDir("/foo/bar/")) == "../../");
154 TEST(FilesystemUtils, NormalizePath) {
157 NormalizePath(&input);
158 EXPECT_EQ("", input);
160 input = "foo/bar.txt";
161 NormalizePath(&input);
162 EXPECT_EQ("foo/bar.txt", input);
165 NormalizePath(&input);
166 EXPECT_EQ("", input);
169 NormalizePath(&input);
170 EXPECT_EQ("..", input);
173 NormalizePath(&input);
174 EXPECT_EQ("foo/bar", input);
177 NormalizePath(&input);
178 EXPECT_EQ("//foo", input);
180 input = "foo/..//bar";
181 NormalizePath(&input);
182 EXPECT_EQ("bar", input);
184 input = "foo/../../bar";
185 NormalizePath(&input);
186 EXPECT_EQ("../bar", input);
188 input = "/../foo"; // Don't go aboe the root dir.
189 NormalizePath(&input);
190 EXPECT_EQ("/foo", input);
192 input = "//../foo"; // Don't go above the root dir.
193 NormalizePath(&input);
194 EXPECT_EQ("//foo", input);
197 NormalizePath(&input);
198 EXPECT_EQ("../foo", input);
201 NormalizePath(&input);
202 EXPECT_EQ("..", input);
205 NormalizePath(&input);
206 EXPECT_EQ("", input);
209 NormalizePath(&input);
210 EXPECT_EQ("../../..", input);
213 NormalizePath(&input);
214 EXPECT_EQ("../", input);
216 // Backslash normalization.
217 input = "foo\\..\\..\\bar";
218 NormalizePath(&input);
219 EXPECT_EQ("../bar", input);
222 TEST(FilesystemUtils, RebaseSourceAbsolutePath) {
224 EXPECT_EQ(".", RebaseSourceAbsolutePath("//", SourceDir("//")));
226 RebaseSourceAbsolutePath("//foo/bar/", SourceDir("//foo/bar/")));
228 // Going up the tree.
230 RebaseSourceAbsolutePath("//foo", SourceDir("//bar/")));
232 RebaseSourceAbsolutePath("//foo/", SourceDir("//bar/")));
233 EXPECT_EQ("../../foo",
234 RebaseSourceAbsolutePath("//foo", SourceDir("//bar/moo")));
235 EXPECT_EQ("../../foo/",
236 RebaseSourceAbsolutePath("//foo/", SourceDir("//bar/moo")));
238 // Going down the tree.
240 RebaseSourceAbsolutePath("//foo/bar", SourceDir("//")));
241 EXPECT_EQ("foo/bar/",
242 RebaseSourceAbsolutePath("//foo/bar/", SourceDir("//")));
244 // Going up and down the tree.
245 EXPECT_EQ("../../foo/bar",
246 RebaseSourceAbsolutePath("//foo/bar", SourceDir("//a/b/")));
247 EXPECT_EQ("../../foo/bar/",
248 RebaseSourceAbsolutePath("//foo/bar/", SourceDir("//a/b/")));
252 RebaseSourceAbsolutePath("//a/foo", SourceDir("//a/")));
254 RebaseSourceAbsolutePath("//a/foo/", SourceDir("//a/")));
256 RebaseSourceAbsolutePath("//a/b/foo", SourceDir("//a/b/")));
258 RebaseSourceAbsolutePath("//a/b/foo/", SourceDir("//a/b/")));
260 RebaseSourceAbsolutePath("//a/b/foo/bar", SourceDir("//a/b/")));
261 EXPECT_EQ("foo/bar/",
262 RebaseSourceAbsolutePath("//a/b/foo/bar/", SourceDir("//a/b/")));
264 // One could argue about this case. Since the input doesn't have a slash it
265 // would normally not be treated like a directory and we'd go up, which is
266 // simpler. However, since it matches the output directory's name, we could
267 // potentially infer that it's the same and return "." for this.
269 RebaseSourceAbsolutePath("//foo/bar", SourceDir("//foo/bar/")));
272 TEST(FilesystemUtils, DirectoryWithNoLastSlash) {
273 EXPECT_EQ("", DirectoryWithNoLastSlash(SourceDir()));
274 EXPECT_EQ("/.", DirectoryWithNoLastSlash(SourceDir("/")));
275 EXPECT_EQ("//.", DirectoryWithNoLastSlash(SourceDir("//")));
276 EXPECT_EQ("//foo", DirectoryWithNoLastSlash(SourceDir("//foo/")));
277 EXPECT_EQ("/bar", DirectoryWithNoLastSlash(SourceDir("/bar/")));
280 TEST(FilesystemUtils, SourceDirForPath) {
282 base::FilePath root(L"C:\\source\\foo\\");
283 EXPECT_EQ("/C:/foo/bar/", SourceDirForPath(root,
284 base::FilePath(L"C:\\foo\\bar")).value());
285 EXPECT_EQ("/", SourceDirForPath(root,
286 base::FilePath(L"/")).value());
287 EXPECT_EQ("//", SourceDirForPath(root,
288 base::FilePath(L"C:\\source\\foo")).value());
289 EXPECT_EQ("//bar/", SourceDirForPath(root,
290 base::FilePath(L"C:\\source\\foo\\bar\\")). value());
291 EXPECT_EQ("//bar/baz/", SourceDirForPath(root,
292 base::FilePath(L"C:\\source\\foo\\bar\\baz")).value());
294 // Should be case-and-slash-insensitive.
295 EXPECT_EQ("//baR/", SourceDirForPath(root,
296 base::FilePath(L"c:/SOURCE\\Foo/baR/")).value());
298 // Some "weird" Windows paths.
299 EXPECT_EQ("/foo/bar/", SourceDirForPath(root,
300 base::FilePath(L"/foo/bar/")).value());
301 EXPECT_EQ("/C:/foo/bar/", SourceDirForPath(root,
302 base::FilePath(L"C:foo/bar/")).value());
304 // Also allow absolute GN-style Windows paths.
305 EXPECT_EQ("/C:/foo/bar/", SourceDirForPath(root,
306 base::FilePath(L"/C:/foo/bar")).value());
307 EXPECT_EQ("//bar/", SourceDirForPath(root,
308 base::FilePath(L"/C:/source/foo/bar")).value());
311 base::FilePath root("/source/foo/");
312 EXPECT_EQ("/foo/bar/", SourceDirForPath(root,
313 base::FilePath("/foo/bar/")).value());
314 EXPECT_EQ("/", SourceDirForPath(root,
315 base::FilePath("/")).value());
316 EXPECT_EQ("//", SourceDirForPath(root,
317 base::FilePath("/source/foo")).value());
318 EXPECT_EQ("//bar/", SourceDirForPath(root,
319 base::FilePath("/source/foo/bar/")).value());
320 EXPECT_EQ("//bar/baz/", SourceDirForPath(root,
321 base::FilePath("/source/foo/bar/baz/")).value());
323 // Should be case-sensitive.
324 EXPECT_EQ("/SOURCE/foo/bar/", SourceDirForPath(root,
325 base::FilePath("/SOURCE/foo/bar/")).value());
329 TEST(FilesystemUtils, GetToolchainDirs) {
330 BuildSettings build_settings;
331 build_settings.SetBuildDir(SourceDir("//out/Debug/"));
333 Settings default_settings(&build_settings, "");
334 EXPECT_EQ("//out/Debug/",
335 GetToolchainOutputDir(&default_settings).value());
336 EXPECT_EQ("//out/Debug/gen/",
337 GetToolchainGenDir(&default_settings).value());
339 Settings other_settings(&build_settings, "two");
340 EXPECT_EQ("//out/Debug/two/",
341 GetToolchainOutputDir(&other_settings).value());
342 EXPECT_EQ("//out/Debug/two/gen/",
343 GetToolchainGenDir(&other_settings).value());
346 TEST(FilesystemUtils, GetOutDirForSourceDir) {
347 BuildSettings build_settings;
348 build_settings.SetBuildDir(SourceDir("//out/Debug/"));
350 // Test the default toolchain.
351 Settings default_settings(&build_settings, "");
352 EXPECT_EQ("//out/Debug/obj/",
353 GetOutputDirForSourceDir(&default_settings,
354 SourceDir("//")).value());
355 EXPECT_EQ("//out/Debug/obj/foo/bar/",
356 GetOutputDirForSourceDir(&default_settings,
357 SourceDir("//foo/bar/")).value());
359 // Secondary toolchain.
360 Settings other_settings(&build_settings, "two");
361 EXPECT_EQ("//out/Debug/two/obj/",
362 GetOutputDirForSourceDir(&other_settings, SourceDir("//")).value());
363 EXPECT_EQ("//out/Debug/two/obj/foo/bar/",
364 GetOutputDirForSourceDir(&other_settings,
365 SourceDir("//foo/bar/")).value());
368 TEST(FilesystemUtils, GetGenDirForSourceDir) {
369 BuildSettings build_settings;
370 build_settings.SetBuildDir(SourceDir("//out/Debug/"));
372 // Test the default toolchain.
373 Settings default_settings(&build_settings, "");
374 EXPECT_EQ("//out/Debug/gen/",
375 GetGenDirForSourceDir(&default_settings, SourceDir("//")).value());
376 EXPECT_EQ("//out/Debug/gen/foo/bar/",
377 GetGenDirForSourceDir(&default_settings,
378 SourceDir("//foo/bar/")).value());
380 // Secondary toolchain.
381 Settings other_settings(&build_settings, "two");
382 EXPECT_EQ("//out/Debug/two/gen/",
383 GetGenDirForSourceDir(&other_settings, SourceDir("//")).value());
384 EXPECT_EQ("//out/Debug/two/gen/foo/bar/",
385 GetGenDirForSourceDir(&other_settings,
386 SourceDir("//foo/bar/")).value());
389 // Tests handling of output dirs when build dir is the same as the root.
390 TEST(FilesystemUtils, GetDirForEmptyBuildDir) {
391 BuildSettings build_settings;
392 build_settings.SetBuildDir(SourceDir("//"));
393 Settings settings(&build_settings, "");
395 EXPECT_EQ("//", GetToolchainOutputDir(&settings).value());
396 EXPECT_EQ("//gen/", GetToolchainGenDir(&settings).value());
398 GetOutputDirForSourceDir(&settings, SourceDir("//")).value());
400 GetGenDirForSourceDir(&settings, SourceDir("//")).value());