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"
10 #include "tools/gn/target.h"
12 TEST(FilesystemUtils, FileExtensionOffset) {
13 EXPECT_EQ(std::string::npos, FindExtensionOffset(""));
14 EXPECT_EQ(std::string::npos, FindExtensionOffset("foo/bar/baz"));
15 EXPECT_EQ(4u, FindExtensionOffset("foo."));
16 EXPECT_EQ(4u, FindExtensionOffset("f.o.bar"));
17 EXPECT_EQ(std::string::npos, FindExtensionOffset("foo.bar/"));
18 EXPECT_EQ(std::string::npos, FindExtensionOffset("foo.bar/baz"));
21 TEST(FilesystemUtils, FindExtension) {
23 EXPECT_EQ("", FindExtension(&input).as_string());
24 input = "foo/bar/baz";
25 EXPECT_EQ("", FindExtension(&input).as_string());
27 EXPECT_EQ("", FindExtension(&input).as_string());
29 EXPECT_EQ("bar", FindExtension(&input).as_string());
31 EXPECT_EQ("", FindExtension(&input).as_string());
32 input = "foo.bar/baz";
33 EXPECT_EQ("", FindExtension(&input).as_string());
36 TEST(FilesystemUtils, FindFilenameOffset) {
37 EXPECT_EQ(0u, FindFilenameOffset(""));
38 EXPECT_EQ(0u, FindFilenameOffset("foo"));
39 EXPECT_EQ(4u, FindFilenameOffset("foo/"));
40 EXPECT_EQ(4u, FindFilenameOffset("foo/bar"));
43 TEST(FilesystemUtils, RemoveFilename) {
47 EXPECT_STREQ("", s.c_str());
51 EXPECT_STREQ("", s.c_str());
55 EXPECT_STREQ("/", s.c_str());
59 EXPECT_STREQ("foo/", s.c_str());
63 EXPECT_STREQ("foo/bar/", s.c_str());
66 TEST(FilesystemUtils, FindDir) {
68 EXPECT_EQ("", FindDir(&input));
70 EXPECT_EQ("/", FindDir(&input));
72 EXPECT_EQ("foo/", FindDir(&input));
73 input = "foo/bar/baz";
74 EXPECT_EQ("foo/bar/", FindDir(&input));
77 TEST(FilesystemUtils, FindLastDirComponent) {
79 EXPECT_EQ("", FindLastDirComponent(empty));
82 EXPECT_EQ("", FindLastDirComponent(root));
84 SourceDir srcroot("//");
85 EXPECT_EQ("", FindLastDirComponent(srcroot));
87 SourceDir regular1("//foo/");
88 EXPECT_EQ("foo", FindLastDirComponent(regular1));
90 SourceDir regular2("//foo/bar/");
91 EXPECT_EQ("bar", FindLastDirComponent(regular2));
94 TEST(FilesystemUtils, EnsureStringIsInOutputDir) {
95 SourceDir output_dir("//out/Debug/");
99 EXPECT_FALSE(EnsureStringIsInOutputDir(output_dir, "//foo", NULL, &err));
100 EXPECT_TRUE(err.has_error());
102 EXPECT_FALSE(EnsureStringIsInOutputDir(output_dir, "//out/Debugit", NULL,
104 EXPECT_TRUE(err.has_error());
108 EXPECT_TRUE(EnsureStringIsInOutputDir(output_dir, "//out/Debug/", NULL,
110 EXPECT_FALSE(err.has_error());
111 EXPECT_TRUE(EnsureStringIsInOutputDir(output_dir, "//out/Debug/foo", NULL,
113 EXPECT_FALSE(err.has_error());
115 // Pattern but no template expansions are allowed.
116 EXPECT_FALSE(EnsureStringIsInOutputDir(output_dir, "{{source_gen_dir}}",
118 EXPECT_TRUE(err.has_error());
121 TEST(FilesystemUtils, IsPathAbsolute) {
122 EXPECT_TRUE(IsPathAbsolute("/foo/bar"));
123 EXPECT_TRUE(IsPathAbsolute("/"));
124 EXPECT_FALSE(IsPathAbsolute(""));
125 EXPECT_FALSE(IsPathAbsolute("//"));
126 EXPECT_FALSE(IsPathAbsolute("//foo/bar"));
129 EXPECT_TRUE(IsPathAbsolute("C:/foo"));
130 EXPECT_TRUE(IsPathAbsolute("C:/"));
131 EXPECT_TRUE(IsPathAbsolute("C:\\foo"));
132 EXPECT_TRUE(IsPathAbsolute("C:\\"));
133 EXPECT_TRUE(IsPathAbsolute("/C:/foo"));
134 EXPECT_TRUE(IsPathAbsolute("/C:\\foo"));
138 TEST(FilesystemUtils, MakeAbsolutePathRelativeIfPossible) {
142 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("C:\\base", "C:\\base\\foo",
144 EXPECT_EQ("//foo", dest);
145 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("C:\\base", "/C:/base/foo",
147 EXPECT_EQ("//foo", dest);
148 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("c:\\base", "C:\\base\\foo\\",
150 EXPECT_EQ("//foo\\", dest);
152 EXPECT_FALSE(MakeAbsolutePathRelativeIfPossible("C:\\base", "C:\\ba", &dest));
153 EXPECT_FALSE(MakeAbsolutePathRelativeIfPossible("C:\\base",
158 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("/base", "/base/foo/", &dest));
159 EXPECT_EQ("//foo/", dest);
160 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("/base", "/base/foo", &dest));
161 EXPECT_EQ("//foo", dest);
162 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("/base/", "/base/foo/",
164 EXPECT_EQ("//foo/", dest);
166 EXPECT_FALSE(MakeAbsolutePathRelativeIfPossible("/base", "/ba", &dest));
167 EXPECT_FALSE(MakeAbsolutePathRelativeIfPossible("/base", "/notbase/foo",
172 TEST(FilesystemUtils, InvertDir) {
173 EXPECT_TRUE(InvertDir(SourceDir()) == "");
174 EXPECT_TRUE(InvertDir(SourceDir("/")) == "");
175 EXPECT_TRUE(InvertDir(SourceDir("//")) == "");
177 EXPECT_TRUE(InvertDir(SourceDir("//foo/bar")) == "../../");
178 EXPECT_TRUE(InvertDir(SourceDir("//foo\\bar")) == "../../");
179 EXPECT_TRUE(InvertDir(SourceDir("/foo/bar/")) == "../../");
182 TEST(FilesystemUtils, NormalizePath) {
185 NormalizePath(&input);
186 EXPECT_EQ("", input);
188 input = "foo/bar.txt";
189 NormalizePath(&input);
190 EXPECT_EQ("foo/bar.txt", input);
193 NormalizePath(&input);
194 EXPECT_EQ("", input);
197 NormalizePath(&input);
198 EXPECT_EQ("..", input);
201 NormalizePath(&input);
202 EXPECT_EQ("foo/bar", input);
205 NormalizePath(&input);
206 EXPECT_EQ("//foo", input);
208 input = "foo/..//bar";
209 NormalizePath(&input);
210 EXPECT_EQ("bar", input);
212 input = "foo/../../bar";
213 NormalizePath(&input);
214 EXPECT_EQ("../bar", input);
216 input = "/../foo"; // Don't go aboe the root dir.
217 NormalizePath(&input);
218 EXPECT_EQ("/foo", input);
220 input = "//../foo"; // Don't go above the root dir.
221 NormalizePath(&input);
222 EXPECT_EQ("//foo", input);
225 NormalizePath(&input);
226 EXPECT_EQ("../foo", input);
229 NormalizePath(&input);
230 EXPECT_EQ("..", input);
233 NormalizePath(&input);
234 EXPECT_EQ("", input);
237 NormalizePath(&input);
238 EXPECT_EQ("../../..", input);
241 NormalizePath(&input);
242 EXPECT_EQ("../", input);
244 // Backslash normalization.
245 input = "foo\\..\\..\\bar";
246 NormalizePath(&input);
247 EXPECT_EQ("../bar", input);
250 TEST(FilesystemUtils, RebaseSourceAbsolutePath) {
252 EXPECT_EQ(".", RebaseSourceAbsolutePath("//", SourceDir("//")));
254 RebaseSourceAbsolutePath("//foo/bar/", SourceDir("//foo/bar/")));
256 // Going up the tree.
258 RebaseSourceAbsolutePath("//foo", SourceDir("//bar/")));
260 RebaseSourceAbsolutePath("//foo/", SourceDir("//bar/")));
261 EXPECT_EQ("../../foo",
262 RebaseSourceAbsolutePath("//foo", SourceDir("//bar/moo")));
263 EXPECT_EQ("../../foo/",
264 RebaseSourceAbsolutePath("//foo/", SourceDir("//bar/moo")));
266 // Going down the tree.
268 RebaseSourceAbsolutePath("//foo/bar", SourceDir("//")));
269 EXPECT_EQ("foo/bar/",
270 RebaseSourceAbsolutePath("//foo/bar/", SourceDir("//")));
272 // Going up and down the tree.
273 EXPECT_EQ("../../foo/bar",
274 RebaseSourceAbsolutePath("//foo/bar", SourceDir("//a/b/")));
275 EXPECT_EQ("../../foo/bar/",
276 RebaseSourceAbsolutePath("//foo/bar/", SourceDir("//a/b/")));
280 RebaseSourceAbsolutePath("//a/foo", SourceDir("//a/")));
282 RebaseSourceAbsolutePath("//a/foo/", SourceDir("//a/")));
284 RebaseSourceAbsolutePath("//a/b/foo", SourceDir("//a/b/")));
286 RebaseSourceAbsolutePath("//a/b/foo/", SourceDir("//a/b/")));
288 RebaseSourceAbsolutePath("//a/b/foo/bar", SourceDir("//a/b/")));
289 EXPECT_EQ("foo/bar/",
290 RebaseSourceAbsolutePath("//a/b/foo/bar/", SourceDir("//a/b/")));
292 // One could argue about this case. Since the input doesn't have a slash it
293 // would normally not be treated like a directory and we'd go up, which is
294 // simpler. However, since it matches the output directory's name, we could
295 // potentially infer that it's the same and return "." for this.
297 RebaseSourceAbsolutePath("//foo/bar", SourceDir("//foo/bar/")));
300 TEST(FilesystemUtils, DirectoryWithNoLastSlash) {
301 EXPECT_EQ("", DirectoryWithNoLastSlash(SourceDir()));
302 EXPECT_EQ("/.", DirectoryWithNoLastSlash(SourceDir("/")));
303 EXPECT_EQ("//.", DirectoryWithNoLastSlash(SourceDir("//")));
304 EXPECT_EQ("//foo", DirectoryWithNoLastSlash(SourceDir("//foo/")));
305 EXPECT_EQ("/bar", DirectoryWithNoLastSlash(SourceDir("/bar/")));
308 TEST(FilesystemUtils, SourceDirForPath) {
310 base::FilePath root(L"C:\\source\\foo\\");
311 EXPECT_EQ("/C:/foo/bar/", SourceDirForPath(root,
312 base::FilePath(L"C:\\foo\\bar")).value());
313 EXPECT_EQ("/", SourceDirForPath(root,
314 base::FilePath(L"/")).value());
315 EXPECT_EQ("//", SourceDirForPath(root,
316 base::FilePath(L"C:\\source\\foo")).value());
317 EXPECT_EQ("//bar/", SourceDirForPath(root,
318 base::FilePath(L"C:\\source\\foo\\bar\\")). value());
319 EXPECT_EQ("//bar/baz/", SourceDirForPath(root,
320 base::FilePath(L"C:\\source\\foo\\bar\\baz")).value());
322 // Should be case-and-slash-insensitive.
323 EXPECT_EQ("//baR/", SourceDirForPath(root,
324 base::FilePath(L"c:/SOURCE\\Foo/baR/")).value());
326 // Some "weird" Windows paths.
327 EXPECT_EQ("/foo/bar/", SourceDirForPath(root,
328 base::FilePath(L"/foo/bar/")).value());
329 EXPECT_EQ("/C:/foo/bar/", SourceDirForPath(root,
330 base::FilePath(L"C:foo/bar/")).value());
332 // Also allow absolute GN-style Windows paths.
333 EXPECT_EQ("/C:/foo/bar/", SourceDirForPath(root,
334 base::FilePath(L"/C:/foo/bar")).value());
335 EXPECT_EQ("//bar/", SourceDirForPath(root,
336 base::FilePath(L"/C:/source/foo/bar")).value());
339 base::FilePath root("/source/foo/");
340 EXPECT_EQ("/foo/bar/", SourceDirForPath(root,
341 base::FilePath("/foo/bar/")).value());
342 EXPECT_EQ("/", SourceDirForPath(root,
343 base::FilePath("/")).value());
344 EXPECT_EQ("//", SourceDirForPath(root,
345 base::FilePath("/source/foo")).value());
346 EXPECT_EQ("//bar/", SourceDirForPath(root,
347 base::FilePath("/source/foo/bar/")).value());
348 EXPECT_EQ("//bar/baz/", SourceDirForPath(root,
349 base::FilePath("/source/foo/bar/baz/")).value());
351 // Should be case-sensitive.
352 EXPECT_EQ("/SOURCE/foo/bar/", SourceDirForPath(root,
353 base::FilePath("/SOURCE/foo/bar/")).value());
357 TEST(FilesystemUtils, GetToolchainDirs) {
358 BuildSettings build_settings;
359 build_settings.SetBuildDir(SourceDir("//out/Debug/"));
361 // The default toolchain.
362 Settings default_settings(&build_settings, "");
363 Label default_toolchain_label(SourceDir("//toolchain/"), "default");
364 default_settings.set_toolchain_label(default_toolchain_label);
365 default_settings.set_default_toolchain_label(default_toolchain_label);
367 // Default toolchain out dir.
368 EXPECT_EQ("//out/Debug/",
369 GetToolchainOutputDir(&default_settings).value());
370 EXPECT_EQ("//out/Debug/",
371 GetToolchainOutputDir(&build_settings, default_toolchain_label,
374 // Default toolchain gen dir.
375 EXPECT_EQ("//out/Debug/gen/",
376 GetToolchainGenDir(&default_settings).value());
378 GetToolchainGenDirAsOutputFile(&default_settings).value());
379 EXPECT_EQ("//out/Debug/gen/",
380 GetToolchainGenDir(&build_settings, default_toolchain_label,
383 // Check a secondary toolchain.
384 Settings other_settings(&build_settings, "two/");
385 Label other_toolchain_label(SourceDir("//toolchain/"), "two");
386 default_settings.set_toolchain_label(other_toolchain_label);
387 default_settings.set_default_toolchain_label(default_toolchain_label);
389 // Secondary toolchain out dir.
390 EXPECT_EQ("//out/Debug/two/",
391 GetToolchainOutputDir(&other_settings).value());
392 EXPECT_EQ("//out/Debug/two/",
393 GetToolchainOutputDir(&build_settings, other_toolchain_label,
396 // Secondary toolchain gen dir.
397 EXPECT_EQ("//out/Debug/two/gen/",
398 GetToolchainGenDir(&other_settings).value());
399 EXPECT_EQ("two/gen/",
400 GetToolchainGenDirAsOutputFile(&other_settings).value());
401 EXPECT_EQ("//out/Debug/two/gen/",
402 GetToolchainGenDir(&build_settings, other_toolchain_label,
406 TEST(FilesystemUtils, GetOutDirForSourceDir) {
407 BuildSettings build_settings;
408 build_settings.SetBuildDir(SourceDir("//out/Debug/"));
410 // Test the default toolchain.
411 Settings default_settings(&build_settings, "");
412 EXPECT_EQ("//out/Debug/obj/",
413 GetOutputDirForSourceDir(
414 &default_settings, SourceDir("//")).value());
416 GetOutputDirForSourceDirAsOutputFile(
417 &default_settings, SourceDir("//")).value());
419 EXPECT_EQ("//out/Debug/obj/foo/bar/",
420 GetOutputDirForSourceDir(
421 &default_settings, SourceDir("//foo/bar/")).value());
422 EXPECT_EQ("obj/foo/bar/",
423 GetOutputDirForSourceDirAsOutputFile(
424 &default_settings, SourceDir("//foo/bar/")).value());
426 // Secondary toolchain.
427 Settings other_settings(&build_settings, "two/");
428 EXPECT_EQ("//out/Debug/two/obj/",
429 GetOutputDirForSourceDir(
430 &other_settings, SourceDir("//")).value());
431 EXPECT_EQ("two/obj/",
432 GetOutputDirForSourceDirAsOutputFile(
433 &other_settings, SourceDir("//")).value());
435 EXPECT_EQ("//out/Debug/two/obj/foo/bar/",
436 GetOutputDirForSourceDir(&other_settings,
437 SourceDir("//foo/bar/")).value());
438 EXPECT_EQ("two/obj/foo/bar/",
439 GetOutputDirForSourceDirAsOutputFile(
440 &other_settings, SourceDir("//foo/bar/")).value());
443 TEST(FilesystemUtils, GetGenDirForSourceDir) {
444 BuildSettings build_settings;
445 build_settings.SetBuildDir(SourceDir("//out/Debug/"));
447 // Test the default toolchain.
448 Settings default_settings(&build_settings, "");
449 EXPECT_EQ("//out/Debug/gen/",
450 GetGenDirForSourceDir(
451 &default_settings, SourceDir("//")).value());
453 GetGenDirForSourceDirAsOutputFile(
454 &default_settings, SourceDir("//")).value());
456 EXPECT_EQ("//out/Debug/gen/foo/bar/",
457 GetGenDirForSourceDir(
458 &default_settings, SourceDir("//foo/bar/")).value());
459 EXPECT_EQ("gen/foo/bar/",
460 GetGenDirForSourceDirAsOutputFile(
461 &default_settings, SourceDir("//foo/bar/")).value());
463 // Secondary toolchain.
464 Settings other_settings(&build_settings, "two/");
465 EXPECT_EQ("//out/Debug/two/gen/",
466 GetGenDirForSourceDir(
467 &other_settings, SourceDir("//")).value());
468 EXPECT_EQ("two/gen/",
469 GetGenDirForSourceDirAsOutputFile(
470 &other_settings, SourceDir("//")).value());
472 EXPECT_EQ("//out/Debug/two/gen/foo/bar/",
473 GetGenDirForSourceDir(
474 &other_settings, SourceDir("//foo/bar/")).value());
475 EXPECT_EQ("two/gen/foo/bar/",
476 GetGenDirForSourceDirAsOutputFile(
477 &other_settings, SourceDir("//foo/bar/")).value());
480 TEST(FilesystemUtils, GetTargetDirs) {
481 BuildSettings build_settings;
482 build_settings.SetBuildDir(SourceDir("//out/Debug/"));
483 Settings settings(&build_settings, "");
485 Target a(&settings, Label(SourceDir("//foo/bar/"), "baz"));
486 EXPECT_EQ("//out/Debug/obj/foo/bar/", GetTargetOutputDir(&a).value());
487 EXPECT_EQ("obj/foo/bar/", GetTargetOutputDirAsOutputFile(&a).value());
488 EXPECT_EQ("//out/Debug/gen/foo/bar/", GetTargetGenDir(&a).value());
489 EXPECT_EQ("gen/foo/bar/", GetTargetGenDirAsOutputFile(&a).value());
492 // Tests handling of output dirs when build dir is the same as the root.
493 TEST(FilesystemUtils, GetDirForEmptyBuildDir) {
494 BuildSettings build_settings;
495 build_settings.SetBuildDir(SourceDir("//"));
496 Settings settings(&build_settings, "");
498 EXPECT_EQ("//", GetToolchainOutputDir(&settings).value());
499 EXPECT_EQ("//gen/", GetToolchainGenDir(&settings).value());
500 EXPECT_EQ("gen/", GetToolchainGenDirAsOutputFile(&settings).value());
502 GetOutputDirForSourceDir(&settings, SourceDir("//")).value());
504 GetOutputDirForSourceDirAsOutputFile(
505 &settings, SourceDir("//")).value());
507 GetGenDirForSourceDirAsOutputFile(
508 &settings, SourceDir("//")).value());