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 672