blob: df5c48ccae46be35c15dbf793ef8ed6f48a6d050 [file] [log] [blame]
mark@chromium.org6380e262008-10-04 03:21:47 +09001// Copyright (c) 2008 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.
4
mark@chromium.org6380e262008-10-04 03:21:47 +09005#include "base/basictypes.h"
aa@chromium.org76e5c632008-12-18 17:38:16 +09006#include "base/file_path.h"
7#include "base/file_util.h"
8#include "base/path_service.h"
9#include "chrome/common/chrome_paths.h"
mark@chromium.orge3e1ce72008-10-04 04:05:46 +090010#include "testing/gtest/include/gtest/gtest.h"
aa@chromium.org76e5c632008-12-18 17:38:16 +090011#include "testing/platform_test.h"
mark@chromium.org6380e262008-10-04 03:21:47 +090012
13// This macro helps avoid wrapped lines in the test structs.
14#define FPL(x) FILE_PATH_LITERAL(x)
15
16struct UnaryTestData {
17 const FilePath::CharType* input;
18 const FilePath::CharType* expected;
19};
20
21struct UnaryBooleanTestData {
22 const FilePath::CharType* input;
23 bool expected;
24};
25
26struct BinaryTestData {
27 const FilePath::CharType* inputs[2];
28 const FilePath::CharType* expected;
29};
30
aa@chromium.org76e5c632008-12-18 17:38:16 +090031// file_util winds up using autoreleased objects on the Mac, so this needs
32// to be a PlatformTest
33class FilePathTest : public PlatformTest {
34 protected:
35 virtual void SetUp() {
36 PlatformTest::SetUp();
37 }
38 virtual void TearDown() {
39 PlatformTest::TearDown();
40 }
41};
42
43TEST_F(FilePathTest, DirName) {
mark@chromium.org6380e262008-10-04 03:21:47 +090044 const struct UnaryTestData cases[] = {
45 { FPL(""), FPL(".") },
46 { FPL("aa"), FPL(".") },
47 { FPL("/aa/bb"), FPL("/aa") },
48 { FPL("/aa/bb/"), FPL("/aa") },
49 { FPL("/aa/bb//"), FPL("/aa") },
50 { FPL("/aa/bb/ccc"), FPL("/aa/bb") },
51 { FPL("/aa"), FPL("/") },
52 { FPL("/aa/"), FPL("/") },
53 { FPL("/"), FPL("/") },
54 { FPL("//"), FPL("//") },
55 { FPL("///"), FPL("/") },
56 { FPL("aa/"), FPL(".") },
57 { FPL("aa/bb"), FPL("aa") },
58 { FPL("aa/bb/"), FPL("aa") },
59 { FPL("aa/bb//"), FPL("aa") },
60 { FPL("aa//bb//"), FPL("aa") },
61 { FPL("aa//bb/"), FPL("aa") },
62 { FPL("aa//bb"), FPL("aa") },
63 { FPL("//aa/bb"), FPL("//aa") },
64 { FPL("//aa/"), FPL("//") },
65 { FPL("//aa"), FPL("//") },
66 { FPL("0:"), FPL(".") },
67 { FPL("@:"), FPL(".") },
68 { FPL("[:"), FPL(".") },
69 { FPL("`:"), FPL(".") },
70 { FPL("{:"), FPL(".") },
71 { FPL("\xB3:"), FPL(".") },
72 { FPL("\xC5:"), FPL(".") },
73#if defined(OS_WIN)
74 { FPL("\x0143:"), FPL(".") },
75#endif // OS_WIN
76#if defined(FILE_PATH_USES_DRIVE_LETTERS)
77 { FPL("c:"), FPL("c:") },
78 { FPL("C:"), FPL("C:") },
79 { FPL("A:"), FPL("A:") },
80 { FPL("Z:"), FPL("Z:") },
81 { FPL("a:"), FPL("a:") },
82 { FPL("z:"), FPL("z:") },
83 { FPL("c:aa"), FPL("c:") },
84 { FPL("c:/"), FPL("c:/") },
85 { FPL("c://"), FPL("c://") },
86 { FPL("c:///"), FPL("c:/") },
87 { FPL("c:/aa"), FPL("c:/") },
88 { FPL("c:/aa/"), FPL("c:/") },
89 { FPL("c:/aa/bb"), FPL("c:/aa") },
90 { FPL("c:aa/bb"), FPL("c:aa") },
91#endif // FILE_PATH_USES_DRIVE_LETTERS
92#if defined(FILE_PATH_USES_WIN_SEPARATORS)
93 { FPL("\\aa\\bb"), FPL("\\aa") },
94 { FPL("\\aa\\bb\\"), FPL("\\aa") },
95 { FPL("\\aa\\bb\\\\"), FPL("\\aa") },
96 { FPL("\\aa\\bb\\ccc"), FPL("\\aa\\bb") },
97 { FPL("\\aa"), FPL("\\") },
98 { FPL("\\aa\\"), FPL("\\") },
99 { FPL("\\"), FPL("\\") },
100 { FPL("\\\\"), FPL("\\\\") },
101 { FPL("\\\\\\"), FPL("\\") },
102 { FPL("aa\\"), FPL(".") },
103 { FPL("aa\\bb"), FPL("aa") },
104 { FPL("aa\\bb\\"), FPL("aa") },
105 { FPL("aa\\bb\\\\"), FPL("aa") },
106 { FPL("aa\\\\bb\\\\"), FPL("aa") },
107 { FPL("aa\\\\bb\\"), FPL("aa") },
108 { FPL("aa\\\\bb"), FPL("aa") },
109 { FPL("\\\\aa\\bb"), FPL("\\\\aa") },
110 { FPL("\\\\aa\\"), FPL("\\\\") },
111 { FPL("\\\\aa"), FPL("\\\\") },
112#if defined(FILE_PATH_USES_DRIVE_LETTERS)
113 { FPL("c:\\"), FPL("c:\\") },
114 { FPL("c:\\\\"), FPL("c:\\\\") },
115 { FPL("c:\\\\\\"), FPL("c:\\") },
116 { FPL("c:\\aa"), FPL("c:\\") },
117 { FPL("c:\\aa\\"), FPL("c:\\") },
118 { FPL("c:\\aa\\bb"), FPL("c:\\aa") },
119 { FPL("c:aa\\bb"), FPL("c:aa") },
120#endif // FILE_PATH_USES_DRIVE_LETTERS
121#endif // FILE_PATH_USES_WIN_SEPARATORS
122 };
123
124 for (size_t i = 0; i < arraysize(cases); ++i) {
125 FilePath input(cases[i].input);
126 FilePath observed = input.DirName();
127 EXPECT_EQ(FilePath::StringType(cases[i].expected), observed.value()) <<
128 "i: " << i << ", input: " << input.value();
129 }
130}
131
aa@chromium.org76e5c632008-12-18 17:38:16 +0900132TEST_F(FilePathTest, BaseName) {
mark@chromium.org6380e262008-10-04 03:21:47 +0900133 const struct UnaryTestData cases[] = {
134 { FPL(""), FPL("") },
135 { FPL("aa"), FPL("aa") },
136 { FPL("/aa/bb"), FPL("bb") },
137 { FPL("/aa/bb/"), FPL("bb") },
138 { FPL("/aa/bb//"), FPL("bb") },
139 { FPL("/aa/bb/ccc"), FPL("ccc") },
140 { FPL("/aa"), FPL("aa") },
141 { FPL("/"), FPL("/") },
142 { FPL("//"), FPL("//") },
143 { FPL("///"), FPL("/") },
144 { FPL("aa/"), FPL("aa") },
145 { FPL("aa/bb"), FPL("bb") },
146 { FPL("aa/bb/"), FPL("bb") },
147 { FPL("aa/bb//"), FPL("bb") },
148 { FPL("aa//bb//"), FPL("bb") },
149 { FPL("aa//bb/"), FPL("bb") },
150 { FPL("aa//bb"), FPL("bb") },
151 { FPL("//aa/bb"), FPL("bb") },
152 { FPL("//aa/"), FPL("aa") },
153 { FPL("//aa"), FPL("aa") },
154 { FPL("0:"), FPL("0:") },
155 { FPL("@:"), FPL("@:") },
156 { FPL("[:"), FPL("[:") },
157 { FPL("`:"), FPL("`:") },
158 { FPL("{:"), FPL("{:") },
159 { FPL("\xB3:"), FPL("\xB3:") },
160 { FPL("\xC5:"), FPL("\xC5:") },
161#if defined(OS_WIN)
162 { FPL("\x0143:"), FPL("\x0143:") },
163#endif // OS_WIN
164#if defined(FILE_PATH_USES_DRIVE_LETTERS)
165 { FPL("c:"), FPL("") },
166 { FPL("C:"), FPL("") },
167 { FPL("A:"), FPL("") },
168 { FPL("Z:"), FPL("") },
169 { FPL("a:"), FPL("") },
170 { FPL("z:"), FPL("") },
171 { FPL("c:aa"), FPL("aa") },
172 { FPL("c:/"), FPL("/") },
173 { FPL("c://"), FPL("//") },
174 { FPL("c:///"), FPL("/") },
175 { FPL("c:/aa"), FPL("aa") },
176 { FPL("c:/aa/"), FPL("aa") },
177 { FPL("c:/aa/bb"), FPL("bb") },
178 { FPL("c:aa/bb"), FPL("bb") },
179#endif // FILE_PATH_USES_DRIVE_LETTERS
180#if defined(FILE_PATH_USES_WIN_SEPARATORS)
181 { FPL("\\aa\\bb"), FPL("bb") },
182 { FPL("\\aa\\bb\\"), FPL("bb") },
183 { FPL("\\aa\\bb\\\\"), FPL("bb") },
184 { FPL("\\aa\\bb\\ccc"), FPL("ccc") },
185 { FPL("\\aa"), FPL("aa") },
186 { FPL("\\"), FPL("\\") },
187 { FPL("\\\\"), FPL("\\\\") },
188 { FPL("\\\\\\"), FPL("\\") },
189 { FPL("aa\\"), FPL("aa") },
190 { FPL("aa\\bb"), FPL("bb") },
191 { FPL("aa\\bb\\"), FPL("bb") },
192 { FPL("aa\\bb\\\\"), FPL("bb") },
193 { FPL("aa\\\\bb\\\\"), FPL("bb") },
194 { FPL("aa\\\\bb\\"), FPL("bb") },
195 { FPL("aa\\\\bb"), FPL("bb") },
196 { FPL("\\\\aa\\bb"), FPL("bb") },
197 { FPL("\\\\aa\\"), FPL("aa") },
198 { FPL("\\\\aa"), FPL("aa") },
199#if defined(FILE_PATH_USES_DRIVE_LETTERS)
200 { FPL("c:\\"), FPL("\\") },
201 { FPL("c:\\\\"), FPL("\\\\") },
202 { FPL("c:\\\\\\"), FPL("\\") },
203 { FPL("c:\\aa"), FPL("aa") },
204 { FPL("c:\\aa\\"), FPL("aa") },
205 { FPL("c:\\aa\\bb"), FPL("bb") },
206 { FPL("c:aa\\bb"), FPL("bb") },
207#endif // FILE_PATH_USES_DRIVE_LETTERS
208#endif // FILE_PATH_USES_WIN_SEPARATORS
209 };
210
211 for (size_t i = 0; i < arraysize(cases); ++i) {
212 FilePath input(cases[i].input);
213 FilePath observed = input.BaseName();
214 EXPECT_EQ(FilePath::StringType(cases[i].expected), observed.value()) <<
215 "i: " << i << ", input: " << input.value();
216 }
217}
218
aa@chromium.org76e5c632008-12-18 17:38:16 +0900219TEST_F(FilePathTest, Append) {
mark@chromium.org6380e262008-10-04 03:21:47 +0900220 const struct BinaryTestData cases[] = {
221 { { FPL(""), FPL("cc") }, FPL("cc") },
222 { { FPL("."), FPL("ff") }, FPL("ff") },
223 { { FPL("/"), FPL("cc") }, FPL("/cc") },
224 { { FPL("/aa"), FPL("") }, FPL("/aa") },
225 { { FPL("/aa/"), FPL("") }, FPL("/aa") },
226 { { FPL("//aa"), FPL("") }, FPL("//aa") },
227 { { FPL("//aa/"), FPL("") }, FPL("//aa") },
228 { { FPL("//"), FPL("aa") }, FPL("//aa") },
229#if defined(FILE_PATH_USES_DRIVE_LETTERS)
230 { { FPL("c:"), FPL("a") }, FPL("c:a") },
231 { { FPL("c:"), FPL("") }, FPL("c:") },
232 { { FPL("c:/"), FPL("a") }, FPL("c:/a") },
233 { { FPL("c://"), FPL("a") }, FPL("c://a") },
234 { { FPL("c:///"), FPL("a") }, FPL("c:/a") },
235#endif // FILE_PATH_USES_DRIVE_LETTERS
236#if defined(FILE_PATH_USES_WIN_SEPARATORS)
237 // Append introduces the default separator character, so these test cases
238 // need to be defined with different expected results on platforms that use
239 // different default separator characters.
240 { { FPL("\\"), FPL("cc") }, FPL("\\cc") },
241 { { FPL("\\aa"), FPL("") }, FPL("\\aa") },
242 { { FPL("\\aa\\"), FPL("") }, FPL("\\aa") },
243 { { FPL("\\\\aa"), FPL("") }, FPL("\\\\aa") },
244 { { FPL("\\\\aa\\"), FPL("") }, FPL("\\\\aa") },
245 { { FPL("\\\\"), FPL("aa") }, FPL("\\\\aa") },
246 { { FPL("/aa/bb"), FPL("cc") }, FPL("/aa/bb\\cc") },
247 { { FPL("/aa/bb/"), FPL("cc") }, FPL("/aa/bb\\cc") },
248 { { FPL("aa/bb/"), FPL("cc") }, FPL("aa/bb\\cc") },
249 { { FPL("aa/bb"), FPL("cc") }, FPL("aa/bb\\cc") },
250 { { FPL("a/b"), FPL("c") }, FPL("a/b\\c") },
251 { { FPL("a/b/"), FPL("c") }, FPL("a/b\\c") },
252 { { FPL("//aa"), FPL("bb") }, FPL("//aa\\bb") },
253 { { FPL("//aa/"), FPL("bb") }, FPL("//aa\\bb") },
254 { { FPL("\\aa\\bb"), FPL("cc") }, FPL("\\aa\\bb\\cc") },
255 { { FPL("\\aa\\bb\\"), FPL("cc") }, FPL("\\aa\\bb\\cc") },
256 { { FPL("aa\\bb\\"), FPL("cc") }, FPL("aa\\bb\\cc") },
257 { { FPL("aa\\bb"), FPL("cc") }, FPL("aa\\bb\\cc") },
258 { { FPL("a\\b"), FPL("c") }, FPL("a\\b\\c") },
259 { { FPL("a\\b\\"), FPL("c") }, FPL("a\\b\\c") },
260 { { FPL("\\\\aa"), FPL("bb") }, FPL("\\\\aa\\bb") },
261 { { FPL("\\\\aa\\"), FPL("bb") }, FPL("\\\\aa\\bb") },
262#if defined(FILE_PATH_USES_DRIVE_LETTERS)
263 { { FPL("c:\\"), FPL("a") }, FPL("c:\\a") },
264 { { FPL("c:\\\\"), FPL("a") }, FPL("c:\\\\a") },
265 { { FPL("c:\\\\\\"), FPL("a") }, FPL("c:\\a") },
266 { { FPL("c:\\"), FPL("") }, FPL("c:\\") },
267 { { FPL("c:\\a"), FPL("b") }, FPL("c:\\a\\b") },
268 { { FPL("c:\\a\\"), FPL("b") }, FPL("c:\\a\\b") },
269#endif // FILE_PATH_USES_DRIVE_LETTERS
270#else // FILE_PATH_USES_WIN_SEPARATORS
271 { { FPL("/aa/bb"), FPL("cc") }, FPL("/aa/bb/cc") },
272 { { FPL("/aa/bb/"), FPL("cc") }, FPL("/aa/bb/cc") },
273 { { FPL("aa/bb/"), FPL("cc") }, FPL("aa/bb/cc") },
274 { { FPL("aa/bb"), FPL("cc") }, FPL("aa/bb/cc") },
275 { { FPL("a/b"), FPL("c") }, FPL("a/b/c") },
276 { { FPL("a/b/"), FPL("c") }, FPL("a/b/c") },
277 { { FPL("//aa"), FPL("bb") }, FPL("//aa/bb") },
278 { { FPL("//aa/"), FPL("bb") }, FPL("//aa/bb") },
279#if defined(FILE_PATH_USES_DRIVE_LETTERS)
280 { { FPL("c:/"), FPL("a") }, FPL("c:/a") },
281 { { FPL("c:/"), FPL("") }, FPL("c:/") },
282 { { FPL("c:/a"), FPL("b") }, FPL("c:/a/b") },
283 { { FPL("c:/a/"), FPL("b") }, FPL("c:/a/b") },
284#endif // FILE_PATH_USES_DRIVE_LETTERS
285#endif // FILE_PATH_USES_WIN_SEPARATORS
286 };
287
288 for (size_t i = 0; i < arraysize(cases); ++i) {
289 FilePath root(cases[i].inputs[0]);
290 FilePath::StringType leaf(cases[i].inputs[1]);
mark@chromium.orgfac7b262008-12-09 01:49:08 +0900291 FilePath observed_str = root.Append(leaf);
292 EXPECT_EQ(FilePath::StringType(cases[i].expected), observed_str.value()) <<
293 "i: " << i << ", root: " << root.value() << ", leaf: " << leaf;
294 FilePath observed_path = root.Append(FilePath(leaf));
295 EXPECT_EQ(FilePath::StringType(cases[i].expected), observed_path.value()) <<
mark@chromium.org6380e262008-10-04 03:21:47 +0900296 "i: " << i << ", root: " << root.value() << ", leaf: " << leaf;
297 }
298}
299
aa@chromium.org76e5c632008-12-18 17:38:16 +0900300TEST_F(FilePathTest, IsAbsolute) {
mark@chromium.org6380e262008-10-04 03:21:47 +0900301 const struct UnaryBooleanTestData cases[] = {
302 { FPL(""), false },
303 { FPL("a"), false },
304 { FPL("c:"), false },
305 { FPL("c:a"), false },
306 { FPL("a/b"), false },
307 { FPL("//"), true },
308 { FPL("//a"), true },
309 { FPL("c:a/b"), false },
310 { FPL("?:/a"), false },
311#if defined(FILE_PATH_USES_DRIVE_LETTERS)
312 { FPL("/"), false },
313 { FPL("/a"), false },
314 { FPL("/."), false },
315 { FPL("/.."), false },
316 { FPL("c:/"), true },
317 { FPL("c:/a"), true },
318 { FPL("c:/."), true },
319 { FPL("c:/.."), true },
320 { FPL("C:/a"), true },
321 { FPL("d:/a"), true },
322#else // FILE_PATH_USES_DRIVE_LETTERS
323 { FPL("/"), true },
324 { FPL("/a"), true },
325 { FPL("/."), true },
326 { FPL("/.."), true },
327 { FPL("c:/"), false },
328#endif // FILE_PATH_USES_DRIVE_LETTERS
329#if defined(FILE_PATH_USES_WIN_SEPARATORS)
330 { FPL("a\\b"), false },
331 { FPL("\\\\"), true },
332 { FPL("\\\\a"), true },
333 { FPL("a\\b"), false },
334 { FPL("\\\\"), true },
335 { FPL("//a"), true },
336 { FPL("c:a\\b"), false },
337 { FPL("?:\\a"), false },
338#if defined(FILE_PATH_USES_DRIVE_LETTERS)
339 { FPL("\\"), false },
340 { FPL("\\a"), false },
341 { FPL("\\."), false },
342 { FPL("\\.."), false },
343 { FPL("c:\\"), true },
344 { FPL("c:\\"), true },
345 { FPL("c:\\a"), true },
346 { FPL("c:\\."), true },
347 { FPL("c:\\.."), true },
348 { FPL("C:\\a"), true },
349 { FPL("d:\\a"), true },
350#else // FILE_PATH_USES_DRIVE_LETTERS
351 { FPL("\\"), true },
352 { FPL("\\a"), true },
353 { FPL("\\."), true },
354 { FPL("\\.."), true },
355 { FPL("c:\\"), false },
356#endif // FILE_PATH_USES_DRIVE_LETTERS
357#endif // FILE_PATH_USES_WIN_SEPARATORS
358 };
359
360 for (size_t i = 0; i < arraysize(cases); ++i) {
361 FilePath input(cases[i].input);
362 bool observed = input.IsAbsolute();
363 EXPECT_EQ(cases[i].expected, observed) <<
364 "i: " << i << ", input: " << input.value();
365 }
366}
aa@chromium.org76e5c632008-12-18 17:38:16 +0900367
368TEST_F(FilePathTest, Contains) {
369 FilePath data_dir;
370 ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &data_dir));
371 data_dir = data_dir.Append(FILE_PATH_LITERAL("FilePathTest"));
372
373 // Create a fresh, empty copy of this directory.
374 file_util::Delete(data_dir, true);
375 file_util::CreateDirectory(data_dir);
376
377 FilePath foo(data_dir.Append(FILE_PATH_LITERAL("foo")));
378 FilePath bar(foo.Append(FILE_PATH_LITERAL("bar.txt")));
379 FilePath baz(data_dir.Append(FILE_PATH_LITERAL("baz.txt")));
380 FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt")));
381
382 // Annoyingly, the directories must actually exist in order for realpath(),
383 // which Contains() relies on in posix, to work.
384 file_util::CreateDirectory(foo);
385 std::string data("hello");
386 file_util::WriteFile(bar.ToWStringHack(), data.c_str(), data.length());
387 file_util::WriteFile(baz.ToWStringHack(), data.c_str(), data.length());
388 file_util::WriteFile(foobar.ToWStringHack(), data.c_str(), data.length());
389
390 EXPECT_TRUE(foo.Contains(bar));
391 EXPECT_FALSE(foo.Contains(baz));
392 EXPECT_FALSE(foo.Contains(foobar));
393 EXPECT_FALSE(foo.Contains(foo));
394
395// Platform-specific concerns
396 FilePath foo_caps(data_dir.Append(FILE_PATH_LITERAL("FOO")));
397#if defined(OS_WIN)
398 EXPECT_TRUE(foo.Contains(foo_caps.Append(FILE_PATH_LITERAL("bar.txt"))));
399 EXPECT_TRUE(foo.Contains(
400 FilePath(foo.value() + FILE_PATH_LITERAL("/bar.txt"))));
401#elif defined(OS_LINUX)
402 EXPECT_FALSE(foo.Contains(foo_caps.Append(FILE_PATH_LITERAL("bar.txt"))));
403#else
404 // We can't really do this test on osx since the case-sensitivity of the
405 // filesystem is configurable.
406#endif
407
408 // Note: whether
409}