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
, EnsureStringIsInOutputDir
) {
94 SourceDir
output_dir("//out/Debug/");
98 EXPECT_FALSE(EnsureStringIsInOutputDir(output_dir
, "//foo", Value(), false,
100 EXPECT_TRUE(err
.has_error());
102 EXPECT_FALSE(EnsureStringIsInOutputDir(output_dir
, "//out/Debugit", Value(),
104 EXPECT_TRUE(err
.has_error());
108 EXPECT_TRUE(EnsureStringIsInOutputDir(output_dir
, "//out/Debug/", Value(),
110 EXPECT_FALSE(err
.has_error());
111 EXPECT_TRUE(EnsureStringIsInOutputDir(output_dir
, "//out/Debug/foo", Value(),
113 EXPECT_FALSE(err
.has_error());
115 // Pattern but no template expansions are allowed.
116 EXPECT_FALSE(EnsureStringIsInOutputDir(output_dir
, "{{source_gen_dir}}",
117 Value(), false, &err
));
118 EXPECT_TRUE(err
.has_error());
120 // Pattern with template expansions allowed.
122 EXPECT_TRUE(EnsureStringIsInOutputDir(output_dir
, "{{source_gen_dir}}",
123 Value(), true, &err
));
124 EXPECT_FALSE(err
.has_error());
126 // Template expansion that doesn't include the absolute directory.
127 EXPECT_FALSE(EnsureStringIsInOutputDir(output_dir
, "{{source}}",
128 Value(), true, &err
));
129 EXPECT_TRUE(err
.has_error());
131 EXPECT_FALSE(EnsureStringIsInOutputDir(output_dir
,
132 "{{source_root_relative_dir}}",
133 Value(), true, &err
));
134 EXPECT_TRUE(err
.has_error());
137 TEST(FilesystemUtils
, IsPathAbsolute
) {
138 EXPECT_TRUE(IsPathAbsolute("/foo/bar"));
139 EXPECT_TRUE(IsPathAbsolute("/"));
140 EXPECT_FALSE(IsPathAbsolute(""));
141 EXPECT_FALSE(IsPathAbsolute("//"));
142 EXPECT_FALSE(IsPathAbsolute("//foo/bar"));
145 EXPECT_TRUE(IsPathAbsolute("C:/foo"));
146 EXPECT_TRUE(IsPathAbsolute("C:/"));
147 EXPECT_TRUE(IsPathAbsolute("C:\\foo"));
148 EXPECT_TRUE(IsPathAbsolute("C:\\"));
149 EXPECT_TRUE(IsPathAbsolute("/C:/foo"));
150 EXPECT_TRUE(IsPathAbsolute("/C:\\foo"));
154 TEST(FilesystemUtils
, MakeAbsolutePathRelativeIfPossible
) {
158 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("C:\\base", "C:\\base\\foo",
160 EXPECT_EQ("//foo", dest
);
161 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("C:\\base", "/C:/base/foo",
163 EXPECT_EQ("//foo", dest
);
164 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("c:\\base", "C:\\base\\foo\\",
166 EXPECT_EQ("//foo\\", dest
);
168 EXPECT_FALSE(MakeAbsolutePathRelativeIfPossible("C:\\base", "C:\\ba", &dest
));
169 EXPECT_FALSE(MakeAbsolutePathRelativeIfPossible("C:\\base",
174 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("/base", "/base/foo/", &dest
));
175 EXPECT_EQ("//foo/", dest
);
176 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("/base", "/base/foo", &dest
));
177 EXPECT_EQ("//foo", dest
);
178 EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("/base/", "/base/foo/",
180 EXPECT_EQ("//foo/", dest
);
182 EXPECT_FALSE(MakeAbsolutePathRelativeIfPossible("/base", "/ba", &dest
));
183 EXPECT_FALSE(MakeAbsolutePathRelativeIfPossible("/base", "/notbase/foo",
188 TEST(FilesystemUtils
, InvertDir
) {
189 EXPECT_TRUE(InvertDir(SourceDir()) == "");
190 EXPECT_TRUE(InvertDir(SourceDir("/")) == "");
191 EXPECT_TRUE(InvertDir(SourceDir("//")) == "");
193 EXPECT_TRUE(InvertDir(SourceDir("//foo/bar")) == "../../");
194 EXPECT_TRUE(InvertDir(SourceDir("//foo\\bar")) == "../../");
195 EXPECT_TRUE(InvertDir(SourceDir("/foo/bar/")) == "../../");
198 TEST(FilesystemUtils
, NormalizePath
) {
201 NormalizePath(&input
);
202 EXPECT_EQ("", input
);
204 input
= "foo/bar.txt";
205 NormalizePath(&input
);
206 EXPECT_EQ("foo/bar.txt", input
);
209 NormalizePath(&input
);
210 EXPECT_EQ("", input
);
213 NormalizePath(&input
);
214 EXPECT_EQ("..", input
);
217 NormalizePath(&input
);
218 EXPECT_EQ("foo/bar", input
);
221 NormalizePath(&input
);
222 EXPECT_EQ("//foo", input
);
224 input
= "foo/..//bar";
225 NormalizePath(&input
);
226 EXPECT_EQ("bar", input
);
228 input
= "foo/../../bar";
229 NormalizePath(&input
);
230 EXPECT_EQ("../bar", input
);
232 input
= "/../foo"; // Don't go aboe the root dir.
233 NormalizePath(&input
);
234 EXPECT_EQ("/foo", input
);
236 input
= "//../foo"; // Don't go above the root dir.
237 NormalizePath(&input
);
238 EXPECT_EQ("//foo", input
);
241 NormalizePath(&input
);
242 EXPECT_EQ("../foo", input
);
245 NormalizePath(&input
);
246 EXPECT_EQ("..", input
);
249 NormalizePath(&input
);
250 EXPECT_EQ("", input
);
253 NormalizePath(&input
);
254 EXPECT_EQ("../../..", input
);
257 NormalizePath(&input
);
258 EXPECT_EQ("../", input
);
260 // Backslash normalization.
261 input
= "foo\\..\\..\\bar";
262 NormalizePath(&input
);
263 EXPECT_EQ("../bar", input
);
266 TEST(FilesystemUtils
, RebaseSourceAbsolutePath
) {
268 EXPECT_EQ(".", RebaseSourceAbsolutePath("//", SourceDir("//")));
270 RebaseSourceAbsolutePath("//foo/bar/", SourceDir("//foo/bar/")));
272 // Going up the tree.
274 RebaseSourceAbsolutePath("//foo", SourceDir("//bar/")));
276 RebaseSourceAbsolutePath("//foo/", SourceDir("//bar/")));
277 EXPECT_EQ("../../foo",
278 RebaseSourceAbsolutePath("//foo", SourceDir("//bar/moo")));
279 EXPECT_EQ("../../foo/",
280 RebaseSourceAbsolutePath("//foo/", SourceDir("//bar/moo")));
282 // Going down the tree.
284 RebaseSourceAbsolutePath("//foo/bar", SourceDir("//")));
285 EXPECT_EQ("foo/bar/",
286 RebaseSourceAbsolutePath("//foo/bar/", SourceDir("//")));
288 // Going up and down the tree.
289 EXPECT_EQ("../../foo/bar",
290 RebaseSourceAbsolutePath("//foo/bar", SourceDir("//a/b/")));
291 EXPECT_EQ("../../foo/bar/",
292 RebaseSourceAbsolutePath("//foo/bar/", SourceDir("//a/b/")));
296 RebaseSourceAbsolutePath("//a/foo", SourceDir("//a/")));
298 RebaseSourceAbsolutePath("//a/foo/", SourceDir("//a/")));
300 RebaseSourceAbsolutePath("//a/b/foo", SourceDir("//a/b/")));
302 RebaseSourceAbsolutePath("//a/b/foo/", SourceDir("//a/b/")));
304 RebaseSourceAbsolutePath("//a/b/foo/bar", SourceDir("//a/b/")));
305 EXPECT_EQ("foo/bar/",
306 RebaseSourceAbsolutePath("//a/b/foo/bar/", SourceDir("//a/b/")));
308 // One could argue about this case. Since the input doesn't have a slash it
309 // would normally not be treated like a directory and we'd go up, which is
310 // simpler. However, since it matches the output directory's name, we could
311 // potentially infer that it's the same and return "." for this.
313 RebaseSourceAbsolutePath("//foo/bar", SourceDir("//foo/bar/")));
316 TEST(FilesystemUtils
, DirectoryWithNoLastSlash
) {
317 EXPECT_EQ("", DirectoryWithNoLastSlash(SourceDir()));
318 EXPECT_EQ("/.", DirectoryWithNoLastSlash(SourceDir("/")));
319 EXPECT_EQ("//.", DirectoryWithNoLastSlash(SourceDir("//")));
320 EXPECT_EQ("//foo", DirectoryWithNoLastSlash(SourceDir("//foo/")));
321 EXPECT_EQ("/bar", DirectoryWithNoLastSlash(SourceDir("/bar/")));
324 TEST(FilesystemUtils
, SourceDirForPath
) {
326 base::FilePath
root(L
"C:\\source\\foo\\");
327 EXPECT_EQ("/C:/foo/bar/", SourceDirForPath(root
,
328 base::FilePath(L
"C:\\foo\\bar")).value());
329 EXPECT_EQ("/", SourceDirForPath(root
,
330 base::FilePath(L
"/")).value());
331 EXPECT_EQ("//", SourceDirForPath(root
,
332 base::FilePath(L
"C:\\source\\foo")).value());
333 EXPECT_EQ("//bar/", SourceDirForPath(root
,
334 base::FilePath(L
"C:\\source\\foo\\bar\\")). value());
335 EXPECT_EQ("//bar/baz/", SourceDirForPath(root
,
336 base::FilePath(L
"C:\\source\\foo\\bar\\baz")).value());
338 // Should be case-and-slash-insensitive.
339 EXPECT_EQ("//baR/", SourceDirForPath(root
,
340 base::FilePath(L
"c:/SOURCE\\Foo/baR/")).value());
342 // Some "weird" Windows paths.
343 EXPECT_EQ("/foo/bar/", SourceDirForPath(root
,
344 base::FilePath(L
"/foo/bar/")).value());
345 EXPECT_EQ("/C:/foo/bar/", SourceDirForPath(root
,
346 base::FilePath(L
"C:foo/bar/")).value());
348 // Also allow absolute GN-style Windows paths.
349 EXPECT_EQ("/C:/foo/bar/", SourceDirForPath(root
,
350 base::FilePath(L
"/C:/foo/bar")).value());
351 EXPECT_EQ("//bar/", SourceDirForPath(root
,
352 base::FilePath(L
"/C:/source/foo/bar")).value());
355 base::FilePath
root("/source/foo/");
356 EXPECT_EQ("/foo/bar/", SourceDirForPath(root
,
357 base::FilePath("/foo/bar/")).value());
358 EXPECT_EQ("/", SourceDirForPath(root
,
359 base::FilePath("/")).value());
360 EXPECT_EQ("//", SourceDirForPath(root
,
361 base::FilePath("/source/foo")).value());
362 EXPECT_EQ("//bar/", SourceDirForPath(root
,
363 base::FilePath("/source/foo/bar/")).value());
364 EXPECT_EQ("//bar/baz/", SourceDirForPath(root
,
365 base::FilePath("/source/foo/bar/baz/")).value());
367 // Should be case-sensitive.
368 EXPECT_EQ("/SOURCE/foo/bar/", SourceDirForPath(root
,
369 base::FilePath("/SOURCE/foo/bar/")).value());
373 TEST(FilesystemUtils
, GetToolchainDirs
) {
374 BuildSettings build_settings
;
375 build_settings
.SetBuildDir(SourceDir("//out/Debug/"));
377 Settings
default_settings(&build_settings
, "");
378 EXPECT_EQ("//out/Debug/",
379 GetToolchainOutputDir(&default_settings
).value());
380 EXPECT_EQ("//out/Debug/gen/",
381 GetToolchainGenDir(&default_settings
).value());
383 Settings
other_settings(&build_settings
, "two/");
384 EXPECT_EQ("//out/Debug/two/",
385 GetToolchainOutputDir(&other_settings
).value());
386 EXPECT_EQ("//out/Debug/two/gen/",
387 GetToolchainGenDir(&other_settings
).value());
390 TEST(FilesystemUtils
, GetOutDirForSourceDir
) {
391 BuildSettings build_settings
;
392 build_settings
.SetBuildDir(SourceDir("//out/Debug/"));
394 // Test the default toolchain.
395 Settings
default_settings(&build_settings
, "");
396 EXPECT_EQ("//out/Debug/obj/",
397 GetOutputDirForSourceDir(&default_settings
,
398 SourceDir("//")).value());
399 EXPECT_EQ("//out/Debug/obj/foo/bar/",
400 GetOutputDirForSourceDir(&default_settings
,
401 SourceDir("//foo/bar/")).value());
403 // Secondary toolchain.
404 Settings
other_settings(&build_settings
, "two/");
405 EXPECT_EQ("//out/Debug/two/obj/",
406 GetOutputDirForSourceDir(&other_settings
, SourceDir("//")).value());
407 EXPECT_EQ("//out/Debug/two/obj/foo/bar/",
408 GetOutputDirForSourceDir(&other_settings
,
409 SourceDir("//foo/bar/")).value());
412 TEST(FilesystemUtils
, GetGenDirForSourceDir
) {
413 BuildSettings build_settings
;
414 build_settings
.SetBuildDir(SourceDir("//out/Debug/"));
416 // Test the default toolchain.
417 Settings
default_settings(&build_settings
, "");
418 EXPECT_EQ("//out/Debug/gen/",
419 GetGenDirForSourceDir(&default_settings
, SourceDir("//")).value());
420 EXPECT_EQ("//out/Debug/gen/foo/bar/",
421 GetGenDirForSourceDir(&default_settings
,
422 SourceDir("//foo/bar/")).value());
424 // Secondary toolchain.
425 Settings
other_settings(&build_settings
, "two/");
426 EXPECT_EQ("//out/Debug/two/gen/",
427 GetGenDirForSourceDir(&other_settings
, SourceDir("//")).value());
428 EXPECT_EQ("//out/Debug/two/gen/foo/bar/",
429 GetGenDirForSourceDir(&other_settings
,
430 SourceDir("//foo/bar/")).value());
433 // Tests handling of output dirs when build dir is the same as the root.
434 TEST(FilesystemUtils
, GetDirForEmptyBuildDir
) {
435 BuildSettings build_settings
;
436 build_settings
.SetBuildDir(SourceDir("//"));
437 Settings
settings(&build_settings
, "");
439 EXPECT_EQ("//", GetToolchainOutputDir(&settings
).value());
440 EXPECT_EQ("//gen/", GetToolchainGenDir(&settings
).value());
442 GetOutputDirForSourceDir(&settings
, SourceDir("//")).value());
444 GetGenDirForSourceDir(&settings
, SourceDir("//")).value());