Imported Upstream version 1.14.0
[platform/upstream/gtest.git] / googletest / test / googletest-filepath-test.cc
1 // Copyright 2008, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Google Test filepath utilities
31 //
32 // This file tests classes and functions used internally by
33 // Google Test.  They are subject to change without notice.
34 //
35 // This file is #included from gtest-internal.h.
36 // Do not #include this file anywhere else!
37
38 #include <string>
39
40 #include "gtest/gtest.h"
41 #include "gtest/internal/gtest-filepath.h"
42 #include "src/gtest-internal-inl.h"
43
44 #ifdef GTEST_OS_WINDOWS_MOBILE
45 #include <windows.h>  // NOLINT
46 #elif defined(GTEST_OS_WINDOWS)
47 #include <direct.h>  // NOLINT
48 #endif               // GTEST_OS_WINDOWS_MOBILE
49
50 namespace testing {
51 namespace internal {
52 namespace {
53
54 #ifdef GTEST_OS_WINDOWS_MOBILE
55
56 // Windows CE doesn't have the remove C function.
57 int remove(const char* path) {
58   LPCWSTR wpath = String::AnsiToUtf16(path);
59   int ret = DeleteFile(wpath) ? 0 : -1;
60   delete[] wpath;
61   return ret;
62 }
63 // Windows CE doesn't have the _rmdir C function.
64 int _rmdir(const char* path) {
65   FilePath filepath(path);
66   LPCWSTR wpath =
67       String::AnsiToUtf16(filepath.RemoveTrailingPathSeparator().c_str());
68   int ret = RemoveDirectory(wpath) ? 0 : -1;
69   delete[] wpath;
70   return ret;
71 }
72
73 #else
74
75 TEST(GetCurrentDirTest, ReturnsCurrentDir) {
76   const FilePath original_dir = FilePath::GetCurrentDir();
77   EXPECT_FALSE(original_dir.IsEmpty());
78
79   posix::ChDir(GTEST_PATH_SEP_);
80   const FilePath cwd = FilePath::GetCurrentDir();
81   posix::ChDir(original_dir.c_str());
82
83 #if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_OS2)
84
85   // Skips the ":".
86   const char* const cwd_without_drive = strchr(cwd.c_str(), ':');
87   ASSERT_TRUE(cwd_without_drive != NULL);
88   EXPECT_STREQ(GTEST_PATH_SEP_, cwd_without_drive + 1);
89
90 #else
91
92   EXPECT_EQ(GTEST_PATH_SEP_, cwd.string());
93
94 #endif
95 }
96
97 #endif  // GTEST_OS_WINDOWS_MOBILE
98
99 TEST(IsEmptyTest, ReturnsTrueForEmptyPath) {
100   EXPECT_TRUE(FilePath("").IsEmpty());
101 }
102
103 TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) {
104   EXPECT_FALSE(FilePath("a").IsEmpty());
105   EXPECT_FALSE(FilePath(".").IsEmpty());
106   EXPECT_FALSE(FilePath("a/b").IsEmpty());
107   EXPECT_FALSE(FilePath("a\\b\\").IsEmpty());
108 }
109
110 // RemoveDirectoryName "" -> ""
111 TEST(RemoveDirectoryNameTest, WhenEmptyName) {
112   EXPECT_EQ("", FilePath("").RemoveDirectoryName().string());
113 }
114
115 // RemoveDirectoryName "afile" -> "afile"
116 TEST(RemoveDirectoryNameTest, ButNoDirectory) {
117   EXPECT_EQ("afile", FilePath("afile").RemoveDirectoryName().string());
118 }
119
120 // RemoveDirectoryName "/afile" -> "afile"
121 TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileName) {
122   EXPECT_EQ("afile",
123             FilePath(GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string());
124 }
125
126 // RemoveDirectoryName "adir/" -> ""
127 TEST(RemoveDirectoryNameTest, WhereThereIsNoFileName) {
128   EXPECT_EQ("",
129             FilePath("adir" GTEST_PATH_SEP_).RemoveDirectoryName().string());
130 }
131
132 // RemoveDirectoryName "adir/afile" -> "afile"
133 TEST(RemoveDirectoryNameTest, ShouldGiveFileName) {
134   EXPECT_EQ(
135       "afile",
136       FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string());
137 }
138
139 // RemoveDirectoryName "adir/subdir/afile" -> "afile"
140 TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) {
141   EXPECT_EQ("afile",
142             FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile")
143                 .RemoveDirectoryName()
144                 .string());
145 }
146
147 #if GTEST_HAS_ALT_PATH_SEP_
148
149 // Tests that RemoveDirectoryName() works with the alternate separator
150 // on Windows.
151
152 // RemoveDirectoryName("/afile") -> "afile"
153 TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileNameForAlternateSeparator) {
154   EXPECT_EQ("afile", FilePath("/afile").RemoveDirectoryName().string());
155 }
156
157 // RemoveDirectoryName("adir/") -> ""
158 TEST(RemoveDirectoryNameTest, WhereThereIsNoFileNameForAlternateSeparator) {
159   EXPECT_EQ("", FilePath("adir/").RemoveDirectoryName().string());
160 }
161
162 // RemoveDirectoryName("adir/afile") -> "afile"
163 TEST(RemoveDirectoryNameTest, ShouldGiveFileNameForAlternateSeparator) {
164   EXPECT_EQ("afile", FilePath("adir/afile").RemoveDirectoryName().string());
165 }
166
167 // RemoveDirectoryName("adir/subdir/afile") -> "afile"
168 TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) {
169   EXPECT_EQ("afile",
170             FilePath("adir/subdir/afile").RemoveDirectoryName().string());
171 }
172
173 #endif
174
175 // RemoveFileName "" -> "./"
176 TEST(RemoveFileNameTest, EmptyName) {
177 #ifdef GTEST_OS_WINDOWS_MOBILE
178   // On Windows CE, we use the root as the current directory.
179   EXPECT_EQ(GTEST_PATH_SEP_, FilePath("").RemoveFileName().string());
180 #else
181   EXPECT_EQ("." GTEST_PATH_SEP_, FilePath("").RemoveFileName().string());
182 #endif
183 }
184
185 // RemoveFileName "adir/" -> "adir/"
186 TEST(RemoveFileNameTest, ButNoFile) {
187   EXPECT_EQ("adir" GTEST_PATH_SEP_,
188             FilePath("adir" GTEST_PATH_SEP_).RemoveFileName().string());
189 }
190
191 // RemoveFileName "adir/afile" -> "adir/"
192 TEST(RemoveFileNameTest, GivesDirName) {
193   EXPECT_EQ("adir" GTEST_PATH_SEP_,
194             FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveFileName().string());
195 }
196
197 // RemoveFileName "adir/subdir/afile" -> "adir/subdir/"
198 TEST(RemoveFileNameTest, GivesDirAndSubDirName) {
199   EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_,
200             FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile")
201                 .RemoveFileName()
202                 .string());
203 }
204
205 // RemoveFileName "/afile" -> "/"
206 TEST(RemoveFileNameTest, GivesRootDir) {
207   EXPECT_EQ(GTEST_PATH_SEP_,
208             FilePath(GTEST_PATH_SEP_ "afile").RemoveFileName().string());
209 }
210
211 #if GTEST_HAS_ALT_PATH_SEP_
212
213 // Tests that RemoveFileName() works with the alternate separator on
214 // Windows.
215
216 // RemoveFileName("adir/") -> "adir/"
217 TEST(RemoveFileNameTest, ButNoFileForAlternateSeparator) {
218   EXPECT_EQ("adir" GTEST_PATH_SEP_,
219             FilePath("adir/").RemoveFileName().string());
220 }
221
222 // RemoveFileName("adir/afile") -> "adir/"
223 TEST(RemoveFileNameTest, GivesDirNameForAlternateSeparator) {
224   EXPECT_EQ("adir" GTEST_PATH_SEP_,
225             FilePath("adir/afile").RemoveFileName().string());
226 }
227
228 // RemoveFileName("adir/subdir/afile") -> "adir/subdir/"
229 TEST(RemoveFileNameTest, GivesDirAndSubDirNameForAlternateSeparator) {
230   EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_,
231             FilePath("adir/subdir/afile").RemoveFileName().string());
232 }
233
234 // RemoveFileName("/afile") -> "\"
235 TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) {
236   EXPECT_EQ(GTEST_PATH_SEP_, FilePath("/afile").RemoveFileName().string());
237 }
238
239 #endif
240
241 TEST(MakeFileNameTest, GenerateWhenNumberIsZero) {
242   FilePath actual =
243       FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), 0, "xml");
244   EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string());
245 }
246
247 TEST(MakeFileNameTest, GenerateFileNameNumberGtZero) {
248   FilePath actual =
249       FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), 12, "xml");
250   EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string());
251 }
252
253 TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberIsZero) {
254   FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_),
255                                            FilePath("bar"), 0, "xml");
256   EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string());
257 }
258
259 TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberGtZero) {
260   FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_),
261                                            FilePath("bar"), 12, "xml");
262   EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string());
263 }
264
265 TEST(MakeFileNameTest, GenerateWhenNumberIsZeroAndDirIsEmpty) {
266   FilePath actual =
267       FilePath::MakeFileName(FilePath(""), FilePath("bar"), 0, "xml");
268   EXPECT_EQ("bar.xml", actual.string());
269 }
270
271 TEST(MakeFileNameTest, GenerateWhenNumberIsNotZeroAndDirIsEmpty) {
272   FilePath actual =
273       FilePath::MakeFileName(FilePath(""), FilePath("bar"), 14, "xml");
274   EXPECT_EQ("bar_14.xml", actual.string());
275 }
276
277 TEST(ConcatPathsTest, WorksWhenDirDoesNotEndWithPathSep) {
278   FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath("bar.xml"));
279   EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string());
280 }
281
282 TEST(ConcatPathsTest, WorksWhenPath1EndsWithPathSep) {
283   FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_),
284                                           FilePath("bar.xml"));
285   EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string());
286 }
287
288 TEST(ConcatPathsTest, Path1BeingEmpty) {
289   FilePath actual = FilePath::ConcatPaths(FilePath(""), FilePath("bar.xml"));
290   EXPECT_EQ("bar.xml", actual.string());
291 }
292
293 TEST(ConcatPathsTest, Path2BeingEmpty) {
294   FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath(""));
295   EXPECT_EQ("foo" GTEST_PATH_SEP_, actual.string());
296 }
297
298 TEST(ConcatPathsTest, BothPathBeingEmpty) {
299   FilePath actual = FilePath::ConcatPaths(FilePath(""), FilePath(""));
300   EXPECT_EQ("", actual.string());
301 }
302
303 TEST(ConcatPathsTest, Path1ContainsPathSep) {
304   FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_ "bar"),
305                                           FilePath("foobar.xml"));
306   EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "foobar.xml",
307             actual.string());
308 }
309
310 TEST(ConcatPathsTest, Path2ContainsPathSep) {
311   FilePath actual =
312       FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_),
313                             FilePath("bar" GTEST_PATH_SEP_ "bar.xml"));
314   EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "bar.xml",
315             actual.string());
316 }
317
318 TEST(ConcatPathsTest, Path2EndsWithPathSep) {
319   FilePath actual =
320       FilePath::ConcatPaths(FilePath("foo"), FilePath("bar" GTEST_PATH_SEP_));
321   EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_, actual.string());
322 }
323
324 // RemoveTrailingPathSeparator "" -> ""
325 TEST(RemoveTrailingPathSeparatorTest, EmptyString) {
326   EXPECT_EQ("", FilePath("").RemoveTrailingPathSeparator().string());
327 }
328
329 // RemoveTrailingPathSeparator "foo" -> "foo"
330 TEST(RemoveTrailingPathSeparatorTest, FileNoSlashString) {
331   EXPECT_EQ("foo", FilePath("foo").RemoveTrailingPathSeparator().string());
332 }
333
334 // RemoveTrailingPathSeparator "foo/" -> "foo"
335 TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) {
336   EXPECT_EQ(
337       "foo",
338       FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().string());
339 #if GTEST_HAS_ALT_PATH_SEP_
340   EXPECT_EQ("foo", FilePath("foo/").RemoveTrailingPathSeparator().string());
341 #endif
342 }
343
344 // RemoveTrailingPathSeparator "foo/bar/" -> "foo/bar/"
345 TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveLastSeparator) {
346   EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar",
347             FilePath("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_)
348                 .RemoveTrailingPathSeparator()
349                 .string());
350 }
351
352 // RemoveTrailingPathSeparator "foo/bar" -> "foo/bar"
353 TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) {
354   EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", FilePath("foo" GTEST_PATH_SEP_ "bar")
355                                              .RemoveTrailingPathSeparator()
356                                              .string());
357 }
358
359 TEST(DirectoryTest, RootDirectoryExists) {
360 #ifdef GTEST_OS_WINDOWS           // We are on Windows.
361   char current_drive[_MAX_PATH];  // NOLINT
362   current_drive[0] = static_cast<char>(_getdrive() + 'A' - 1);
363   current_drive[1] = ':';
364   current_drive[2] = '\\';
365   current_drive[3] = '\0';
366   EXPECT_TRUE(FilePath(current_drive).DirectoryExists());
367 #else
368   EXPECT_TRUE(FilePath("/").DirectoryExists());
369 #endif  // GTEST_OS_WINDOWS
370 }
371
372 #ifdef GTEST_OS_WINDOWS
373 TEST(DirectoryTest, RootOfWrongDriveDoesNotExists) {
374   const int saved_drive_ = _getdrive();
375   // Find a drive that doesn't exist. Start with 'Z' to avoid common ones.
376   for (char drive = 'Z'; drive >= 'A'; drive--)
377     if (_chdrive(drive - 'A' + 1) == -1) {
378       char non_drive[_MAX_PATH];  // NOLINT
379       non_drive[0] = drive;
380       non_drive[1] = ':';
381       non_drive[2] = '\\';
382       non_drive[3] = '\0';
383       EXPECT_FALSE(FilePath(non_drive).DirectoryExists());
384       break;
385     }
386   _chdrive(saved_drive_);
387 }
388 #endif  // GTEST_OS_WINDOWS
389
390 #ifndef GTEST_OS_WINDOWS_MOBILE
391 // Windows CE _does_ consider an empty directory to exist.
392 TEST(DirectoryTest, EmptyPathDirectoryDoesNotExist) {
393   EXPECT_FALSE(FilePath("").DirectoryExists());
394 }
395 #endif  // !GTEST_OS_WINDOWS_MOBILE
396
397 TEST(DirectoryTest, CurrentDirectoryExists) {
398 #ifdef GTEST_OS_WINDOWS  // We are on Windows.
399 #ifndef _WIN32_CE     // Windows CE doesn't have a current directory.
400
401   EXPECT_TRUE(FilePath(".").DirectoryExists());
402   EXPECT_TRUE(FilePath(".\\").DirectoryExists());
403
404 #endif  // _WIN32_CE
405 #else
406   EXPECT_TRUE(FilePath(".").DirectoryExists());
407   EXPECT_TRUE(FilePath("./").DirectoryExists());
408 #endif  // GTEST_OS_WINDOWS
409 }
410
411 // "foo/bar" == foo//bar" == "foo///bar"
412 TEST(NormalizeTest, MultipleConsecutiveSeparatorsInMidstring) {
413   EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar",
414             FilePath("foo" GTEST_PATH_SEP_ "bar").string());
415   EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar",
416             FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
417   EXPECT_EQ(
418       "foo" GTEST_PATH_SEP_ "bar",
419       FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar")
420           .string());
421 }
422
423 // "/bar" == //bar" == "///bar"
424 TEST(NormalizeTest, MultipleConsecutiveSeparatorsAtStringStart) {
425   EXPECT_EQ(GTEST_PATH_SEP_ "bar", FilePath(GTEST_PATH_SEP_ "bar").string());
426 #ifdef GTEST_OS_WINDOWS
427   EXPECT_EQ(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar",
428             FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
429 #else
430   EXPECT_EQ(GTEST_PATH_SEP_ "bar",
431             FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
432 #endif
433   EXPECT_EQ(
434       GTEST_PATH_SEP_ "bar",
435       FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
436 }
437
438 // "foo/" == foo//" == "foo///"
439 TEST(NormalizeTest, MultipleConsecutiveSeparatorsAtStringEnd) {
440   EXPECT_EQ("foo" GTEST_PATH_SEP_, FilePath("foo" GTEST_PATH_SEP_).string());
441   EXPECT_EQ("foo" GTEST_PATH_SEP_,
442             FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_).string());
443   EXPECT_EQ(
444       "foo" GTEST_PATH_SEP_,
445       FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_).string());
446 }
447
448 #if GTEST_HAS_ALT_PATH_SEP_
449
450 // Tests that separators at the end of the string are normalized
451 // regardless of their combination (e.g. "foo\" =="foo/\" ==
452 // "foo\\/").
453 TEST(NormalizeTest, MixAlternateSeparatorAtStringEnd) {
454   EXPECT_EQ("foo" GTEST_PATH_SEP_, FilePath("foo/").string());
455   EXPECT_EQ("foo" GTEST_PATH_SEP_,
456             FilePath("foo" GTEST_PATH_SEP_ "/").string());
457   EXPECT_EQ("foo" GTEST_PATH_SEP_, FilePath("foo//" GTEST_PATH_SEP_).string());
458 }
459
460 #endif
461
462 TEST(AssignmentOperatorTest, DefaultAssignedToNonDefault) {
463   FilePath default_path;
464   FilePath non_default_path("path");
465   non_default_path = default_path;
466   EXPECT_EQ("", non_default_path.string());
467   EXPECT_EQ("", default_path.string());  // RHS var is unchanged.
468 }
469
470 TEST(AssignmentOperatorTest, NonDefaultAssignedToDefault) {
471   FilePath non_default_path("path");
472   FilePath default_path;
473   default_path = non_default_path;
474   EXPECT_EQ("path", default_path.string());
475   EXPECT_EQ("path", non_default_path.string());  // RHS var is unchanged.
476 }
477
478 TEST(AssignmentOperatorTest, ConstAssignedToNonConst) {
479   const FilePath const_default_path("const_path");
480   FilePath non_default_path("path");
481   non_default_path = const_default_path;
482   EXPECT_EQ("const_path", non_default_path.string());
483 }
484
485 class DirectoryCreationTest : public Test {
486  protected:
487   void SetUp() override {
488     testdata_path_.Set(
489         FilePath(TempDir() + GetCurrentExecutableName().string() +
490                  "_directory_creation" GTEST_PATH_SEP_ "test" GTEST_PATH_SEP_));
491     testdata_file_.Set(testdata_path_.RemoveTrailingPathSeparator());
492
493     unique_file0_.Set(
494         FilePath::MakeFileName(testdata_path_, FilePath("unique"), 0, "txt"));
495     unique_file1_.Set(
496         FilePath::MakeFileName(testdata_path_, FilePath("unique"), 1, "txt"));
497
498     remove(testdata_file_.c_str());
499     remove(unique_file0_.c_str());
500     remove(unique_file1_.c_str());
501     posix::RmDir(testdata_path_.c_str());
502   }
503
504   void TearDown() override {
505     remove(testdata_file_.c_str());
506     remove(unique_file0_.c_str());
507     remove(unique_file1_.c_str());
508     posix::RmDir(testdata_path_.c_str());
509   }
510
511   void CreateTextFile(const char* filename) {
512     FILE* f = posix::FOpen(filename, "w");
513     fprintf(f, "text\n");
514     fclose(f);
515   }
516
517   // Strings representing a directory and a file, with identical paths
518   // except for the trailing separator character that distinguishes
519   // a directory named 'test' from a file named 'test'. Example names:
520   FilePath testdata_path_;  // "/tmp/directory_creation/test/"
521   FilePath testdata_file_;  // "/tmp/directory_creation/test"
522   FilePath unique_file0_;   // "/tmp/directory_creation/test/unique.txt"
523   FilePath unique_file1_;   // "/tmp/directory_creation/test/unique_1.txt"
524 };
525
526 TEST_F(DirectoryCreationTest, CreateDirectoriesRecursively) {
527   EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string();
528   EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively());
529   EXPECT_TRUE(testdata_path_.DirectoryExists());
530 }
531
532 TEST_F(DirectoryCreationTest, CreateDirectoriesForAlreadyExistingPath) {
533   EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string();
534   EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively());
535   // Call 'create' again... should still succeed.
536   EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively());
537 }
538
539 TEST_F(DirectoryCreationTest, CreateDirectoriesAndUniqueFilename) {
540   FilePath file_path(FilePath::GenerateUniqueFileName(
541       testdata_path_, FilePath("unique"), "txt"));
542   EXPECT_EQ(unique_file0_.string(), file_path.string());
543   EXPECT_FALSE(file_path.FileOrDirectoryExists());  // file not there
544
545   testdata_path_.CreateDirectoriesRecursively();
546   EXPECT_FALSE(file_path.FileOrDirectoryExists());  // file still not there
547   CreateTextFile(file_path.c_str());
548   EXPECT_TRUE(file_path.FileOrDirectoryExists());
549
550   FilePath file_path2(FilePath::GenerateUniqueFileName(
551       testdata_path_, FilePath("unique"), "txt"));
552   EXPECT_EQ(unique_file1_.string(), file_path2.string());
553   EXPECT_FALSE(file_path2.FileOrDirectoryExists());  // file not there
554   CreateTextFile(file_path2.c_str());
555   EXPECT_TRUE(file_path2.FileOrDirectoryExists());
556 }
557
558 TEST_F(DirectoryCreationTest, CreateDirectoriesFail) {
559   // force a failure by putting a file where we will try to create a directory.
560   CreateTextFile(testdata_file_.c_str());
561   EXPECT_TRUE(testdata_file_.FileOrDirectoryExists());
562   EXPECT_FALSE(testdata_file_.DirectoryExists());
563   EXPECT_FALSE(testdata_file_.CreateDirectoriesRecursively());
564 }
565
566 TEST(NoDirectoryCreationTest, CreateNoDirectoriesForDefaultXmlFile) {
567   const FilePath test_detail_xml("test_detail.xml");
568   EXPECT_FALSE(test_detail_xml.CreateDirectoriesRecursively());
569 }
570
571 TEST(FilePathTest, DefaultConstructor) {
572   FilePath fp;
573   EXPECT_EQ("", fp.string());
574 }
575
576 TEST(FilePathTest, CharAndCopyConstructors) {
577   const FilePath fp("spicy");
578   EXPECT_EQ("spicy", fp.string());
579
580   const FilePath fp_copy(fp);
581   EXPECT_EQ("spicy", fp_copy.string());
582 }
583
584 TEST(FilePathTest, StringConstructor) {
585   const FilePath fp(std::string("cider"));
586   EXPECT_EQ("cider", fp.string());
587 }
588
589 TEST(FilePathTest, Set) {
590   const FilePath apple("apple");
591   FilePath mac("mac");
592   mac.Set(apple);  // Implement Set() since overloading operator= is forbidden.
593   EXPECT_EQ("apple", mac.string());
594   EXPECT_EQ("apple", apple.string());
595 }
596
597 TEST(FilePathTest, ToString) {
598   const FilePath file("drink");
599   EXPECT_EQ("drink", file.string());
600 }
601
602 TEST(FilePathTest, RemoveExtension) {
603   EXPECT_EQ("app", FilePath("app.cc").RemoveExtension("cc").string());
604   EXPECT_EQ("app", FilePath("app.exe").RemoveExtension("exe").string());
605   EXPECT_EQ("APP", FilePath("APP.EXE").RemoveExtension("exe").string());
606 }
607
608 TEST(FilePathTest, RemoveExtensionWhenThereIsNoExtension) {
609   EXPECT_EQ("app", FilePath("app").RemoveExtension("exe").string());
610 }
611
612 TEST(FilePathTest, IsDirectory) {
613   EXPECT_FALSE(FilePath("cola").IsDirectory());
614   EXPECT_TRUE(FilePath("koala" GTEST_PATH_SEP_).IsDirectory());
615 #if GTEST_HAS_ALT_PATH_SEP_
616   EXPECT_TRUE(FilePath("koala/").IsDirectory());
617 #endif
618 }
619
620 TEST(FilePathTest, IsAbsolutePath) {
621   EXPECT_FALSE(FilePath("is" GTEST_PATH_SEP_ "relative").IsAbsolutePath());
622   EXPECT_FALSE(FilePath("").IsAbsolutePath());
623 #ifdef GTEST_OS_WINDOWS
624   EXPECT_TRUE(
625       FilePath("c:\\" GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative")
626           .IsAbsolutePath());
627   EXPECT_FALSE(FilePath("c:foo" GTEST_PATH_SEP_ "bar").IsAbsolutePath());
628   EXPECT_TRUE(
629       FilePath("c:/" GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative")
630           .IsAbsolutePath());
631   EXPECT_TRUE(FilePath("d:/Windows").IsAbsolutePath());
632   EXPECT_TRUE(FilePath("\\\\Host\\Share").IsAbsolutePath());
633   EXPECT_TRUE(FilePath("\\\\Host\\Share\\Folder").IsAbsolutePath());
634 #else
635   EXPECT_TRUE(FilePath(GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative")
636                   .IsAbsolutePath());
637 #endif  // GTEST_OS_WINDOWS
638 }
639
640 TEST(FilePathTest, IsRootDirectory) {
641 #ifdef GTEST_OS_WINDOWS
642   EXPECT_TRUE(FilePath("a:\\").IsRootDirectory());
643   EXPECT_TRUE(FilePath("Z:/").IsRootDirectory());
644   EXPECT_TRUE(FilePath("e://").IsRootDirectory());
645   EXPECT_FALSE(FilePath("").IsRootDirectory());
646   EXPECT_FALSE(FilePath("b:").IsRootDirectory());
647   EXPECT_FALSE(FilePath("b:a").IsRootDirectory());
648   EXPECT_FALSE(FilePath("8:/").IsRootDirectory());
649   EXPECT_FALSE(FilePath("c|/").IsRootDirectory());
650   EXPECT_TRUE(FilePath("c:/").IsRootDirectory());
651   EXPECT_FALSE(FilePath("d:/Windows").IsRootDirectory());
652
653   // This is for backward compatibility, since callers (even in this library)
654   // have assumed IsRootDirectory() implies a trailing directory separator.
655   EXPECT_FALSE(FilePath("\\\\Host\\Share").IsRootDirectory());
656
657   EXPECT_TRUE(FilePath("\\\\Host\\Share\\").IsRootDirectory());
658   EXPECT_FALSE(FilePath("\\\\Host\\Share\\.").IsRootDirectory());
659   EXPECT_FALSE(FilePath("\\\\Host\\Share\\C$\\").IsRootDirectory());
660 #else
661   EXPECT_TRUE(FilePath("/").IsRootDirectory());
662   EXPECT_TRUE(FilePath("//").IsRootDirectory());
663   EXPECT_FALSE(FilePath("").IsRootDirectory());
664   EXPECT_FALSE(FilePath("\\").IsRootDirectory());
665   EXPECT_FALSE(FilePath("/x").IsRootDirectory());
666 #endif
667 }
668
669 }  // namespace
670 }  // namespace internal
671 }  // namespace testing