| // Copyright 2017 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/files/file_enumerator.h" |
| |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/containers/circular_deque.h" |
| #include "base/files/file_path.h" |
| #include "base/files/file_util.h" |
| #include "base/files/scoped_temp_dir.h" |
| #include "base/logging.h" |
| #include "build/build_config.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using testing::ElementsAre; |
| using testing::IsEmpty; |
| using testing::UnorderedElementsAre; |
| |
| namespace base { |
| namespace { |
| |
| const FilePath::StringType kEmptyPattern; |
| |
| const std::vector<FileEnumerator::FolderSearchPolicy> kFolderSearchPolicies{ |
| FileEnumerator::FolderSearchPolicy::MATCH_ONLY, |
| FileEnumerator::FolderSearchPolicy::ALL}; |
| |
| struct TestFile { |
| TestFile(const FilePath::CharType* file_name, const char* c) |
| : path(file_name), contents(c) {} |
| |
| TestFile(const FilePath::CharType* directory, |
| const FilePath::CharType* file_name, |
| const char* c) |
| : path(FilePath(directory).Append(file_name)), contents(c) {} |
| |
| const FilePath path; |
| const std::string contents; |
| File::Info info; |
| bool found = false; |
| }; |
| |
| struct TestDirectory { |
| explicit TestDirectory(const FilePath::CharType* n) : name(n) {} |
| const FilePath name; |
| File::Info info; |
| bool found = false; |
| }; |
| |
| void CheckModificationTime(const FileEnumerator::FileInfo& actual, |
| Time expected_last_modified_time) { |
| #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) |
| // On POSIX, GetLastModifiedTime() rounds down to the second, but |
| // File::GetInfo() does not. |
| Time::Exploded exploded; |
| expected_last_modified_time.UTCExplode(&exploded); |
| exploded.millisecond = 0; |
| EXPECT_TRUE(Time::FromUTCExploded(exploded, &expected_last_modified_time)); |
| #endif |
| EXPECT_EQ(actual.GetLastModifiedTime(), expected_last_modified_time); |
| } |
| |
| void CheckFileAgainstInfo(const FileEnumerator::FileInfo& actual, |
| TestFile& expected) { |
| EXPECT_FALSE(expected.found) |
| << "Got " << expected.path.BaseName().value() << " twice"; |
| expected.found = true; |
| EXPECT_EQ(actual.GetSize(), int64_t(expected.contents.size())); |
| CheckModificationTime(actual, expected.info.last_modified); |
| } |
| |
| void CheckDirectoryAgainstInfo(const FileEnumerator::FileInfo& actual, |
| TestDirectory& expected) { |
| EXPECT_FALSE(expected.found) << "Got " << expected.name.value() << " twice"; |
| expected.found = true; |
| CheckModificationTime(actual, expected.info.last_modified); |
| } |
| |
| circular_deque<FilePath> RunEnumerator( |
| const FilePath& root_path, |
| bool recursive, |
| int file_type, |
| const FilePath::StringType& pattern, |
| FileEnumerator::FolderSearchPolicy folder_search_policy) { |
| circular_deque<FilePath> rv; |
| FileEnumerator enumerator(root_path, recursive, file_type, pattern, |
| folder_search_policy, |
| FileEnumerator::ErrorPolicy::IGNORE_ERRORS); |
| for (auto file = enumerator.Next(); !file.empty(); file = enumerator.Next()) |
| rv.emplace_back(std::move(file)); |
| return rv; |
| } |
| |
| bool CreateDummyFile(const FilePath& path) { |
| return WriteFile(path, "42", sizeof("42")) == sizeof("42"); |
| } |
| |
| bool GetFileInfo(const FilePath& file_path, File::Info& info) { |
| // FLAG_WIN_BACKUP_SEMANTICS: Needed to open directories on Windows. |
| File f(file_path, |
| File::FLAG_OPEN | File::FLAG_READ | File::FLAG_WIN_BACKUP_SEMANTICS); |
| if (!f.IsValid()) { |
| LOG(ERROR) << "Could not open " << file_path.value() << ": " |
| << File::ErrorToString(f.error_details()); |
| return false; |
| } |
| if (!f.GetInfo(&info)) { |
| std::string last_error = File::ErrorToString(File::GetLastFileError()); |
| LOG(ERROR) << "Could not get info about " << file_path.value() << ": " |
| << last_error; |
| return false; |
| } |
| |
| return true; |
| } |
| |
| void SetUpTestFiles(const ScopedTempDir& temp_dir, |
| std::vector<TestFile>& files) { |
| for (TestFile& file : files) { |
| const FilePath file_path = temp_dir.GetPath().Append(file.path); |
| ASSERT_TRUE(WriteFile(file_path, file.contents)); |
| ASSERT_TRUE(GetFileInfo(file_path, file.info)); |
| } |
| } |
| |
| } // namespace |
| |
| TEST(FileEnumerator, NotExistingPath) { |
| const FilePath path = FilePath::FromUTF8Unsafe("some_not_existing_path"); |
| ASSERT_FALSE(PathExists(path)); |
| |
| for (auto policy : kFolderSearchPolicies) { |
| const auto files = RunEnumerator( |
| path, true, FileEnumerator::FILES | FileEnumerator::DIRECTORIES, |
| FILE_PATH_LITERAL(""), policy); |
| EXPECT_THAT(files, IsEmpty()); |
| } |
| } |
| |
| TEST(FileEnumerator, EmptyFolder) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| for (auto policy : kFolderSearchPolicies) { |
| const auto files = |
| RunEnumerator(temp_dir.GetPath(), true, |
| FileEnumerator::FILES | FileEnumerator::DIRECTORIES, |
| kEmptyPattern, policy); |
| EXPECT_THAT(files, IsEmpty()); |
| } |
| } |
| |
| TEST(FileEnumerator, SingleFileInFolderForFileSearch) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| const FilePath& path = temp_dir.GetPath(); |
| const FilePath file = path.AppendASCII("test.txt"); |
| ASSERT_TRUE(CreateDummyFile(file)); |
| |
| for (auto policy : kFolderSearchPolicies) { |
| const auto files = RunEnumerator( |
| temp_dir.GetPath(), true, FileEnumerator::FILES, kEmptyPattern, policy); |
| EXPECT_THAT(files, ElementsAre(file)); |
| } |
| } |
| |
| TEST(FileEnumerator, SingleFileInFolderForDirSearch) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| const FilePath& path = temp_dir.GetPath(); |
| ASSERT_TRUE(CreateDummyFile(path.AppendASCII("test.txt"))); |
| |
| for (auto policy : kFolderSearchPolicies) { |
| const auto files = RunEnumerator(path, true, FileEnumerator::DIRECTORIES, |
| kEmptyPattern, policy); |
| EXPECT_THAT(files, IsEmpty()); |
| } |
| } |
| |
| // Starboard does not support patterns. |
| #if !defined(STARBOARD) |
| TEST(FileEnumerator, SingleFileInFolderWithFiltering) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| const FilePath& path = temp_dir.GetPath(); |
| const FilePath file = path.AppendASCII("test.txt"); |
| ASSERT_TRUE(CreateDummyFile(file)); |
| |
| for (auto policy : kFolderSearchPolicies) { |
| auto files = RunEnumerator(path, true, FileEnumerator::FILES, |
| FILE_PATH_LITERAL("*.txt"), policy); |
| EXPECT_THAT(files, ElementsAre(file)); |
| |
| files = RunEnumerator(path, true, FileEnumerator::FILES, |
| FILE_PATH_LITERAL("*.pdf"), policy); |
| EXPECT_THAT(files, IsEmpty()); |
| } |
| } |
| #endif // !defined(STARBOARD) |
| |
| // Starboard does not support patterns. |
| #if !defined(STARBOARD) |
| TEST(FileEnumerator, TwoFilesInFolder) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| const FilePath& path = temp_dir.GetPath(); |
| const FilePath foo_txt = path.AppendASCII("foo.txt"); |
| const FilePath bar_txt = path.AppendASCII("bar.txt"); |
| ASSERT_TRUE(CreateDummyFile(foo_txt)); |
| ASSERT_TRUE(CreateDummyFile(bar_txt)); |
| |
| for (auto policy : kFolderSearchPolicies) { |
| auto files = RunEnumerator(path, true, FileEnumerator::FILES, |
| FILE_PATH_LITERAL("*.txt"), policy); |
| EXPECT_THAT(files, UnorderedElementsAre(foo_txt, bar_txt)); |
| |
| files = RunEnumerator(path, true, FileEnumerator::FILES, |
| FILE_PATH_LITERAL("foo*"), policy); |
| EXPECT_THAT(files, ElementsAre(foo_txt)); |
| |
| files = RunEnumerator(path, true, FileEnumerator::FILES, |
| FILE_PATH_LITERAL("*.pdf"), policy); |
| EXPECT_THAT(files, IsEmpty()); |
| |
| files = |
| RunEnumerator(path, true, FileEnumerator::FILES, kEmptyPattern, policy); |
| EXPECT_THAT(files, UnorderedElementsAre(foo_txt, bar_txt)); |
| } |
| } |
| #endif // !defined(STARBOARD) |
| |
| TEST(FileEnumerator, SingleFolderInFolderForFileSearch) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| const FilePath& path = temp_dir.GetPath(); |
| |
| ScopedTempDir temp_subdir; |
| ASSERT_TRUE(temp_subdir.CreateUniqueTempDirUnderPath(path)); |
| |
| for (auto policy : kFolderSearchPolicies) { |
| const auto files = |
| RunEnumerator(path, true, FileEnumerator::FILES, kEmptyPattern, policy); |
| EXPECT_THAT(files, IsEmpty()); |
| } |
| } |
| |
| TEST(FileEnumerator, SingleFolderInFolderForDirSearch) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| const FilePath& path = temp_dir.GetPath(); |
| |
| ScopedTempDir temp_subdir; |
| ASSERT_TRUE(temp_subdir.CreateUniqueTempDirUnderPath(path)); |
| |
| for (auto policy : kFolderSearchPolicies) { |
| const auto files = RunEnumerator(path, true, FileEnumerator::DIRECTORIES, |
| kEmptyPattern, policy); |
| EXPECT_THAT(files, ElementsAre(temp_subdir.GetPath())); |
| } |
| } |
| |
| // Starboard does not support patterns. |
| #if !defined(STARBOARD) |
| TEST(FileEnumerator, TwoFoldersInFolder) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| const FilePath& path = temp_dir.GetPath(); |
| |
| const FilePath subdir_foo = path.AppendASCII("foo"); |
| const FilePath subdir_bar = path.AppendASCII("bar"); |
| ASSERT_TRUE(CreateDirectory(subdir_foo)); |
| ASSERT_TRUE(CreateDirectory(subdir_bar)); |
| |
| for (auto policy : kFolderSearchPolicies) { |
| auto files = RunEnumerator(path, true, FileEnumerator::DIRECTORIES, |
| kEmptyPattern, policy); |
| EXPECT_THAT(files, UnorderedElementsAre(subdir_foo, subdir_bar)); |
| |
| files = RunEnumerator(path, true, FileEnumerator::DIRECTORIES, |
| FILE_PATH_LITERAL("foo"), policy); |
| EXPECT_THAT(files, ElementsAre(subdir_foo)); |
| } |
| } |
| #endif // !defined(STARBOARD) |
| |
| TEST(FileEnumerator, FolderAndFileInFolder) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| const FilePath& path = temp_dir.GetPath(); |
| |
| ScopedTempDir temp_subdir; |
| ASSERT_TRUE(temp_subdir.CreateUniqueTempDirUnderPath(path)); |
| const FilePath file = path.AppendASCII("test.txt"); |
| ASSERT_TRUE(CreateDummyFile(file)); |
| |
| for (auto policy : kFolderSearchPolicies) { |
| auto files = |
| RunEnumerator(path, true, FileEnumerator::FILES, kEmptyPattern, policy); |
| EXPECT_THAT(files, ElementsAre(file)); |
| |
| files = RunEnumerator(path, true, FileEnumerator::DIRECTORIES, |
| kEmptyPattern, policy); |
| EXPECT_THAT(files, ElementsAre(temp_subdir.GetPath())); |
| |
| files = RunEnumerator(path, true, |
| FileEnumerator::FILES | FileEnumerator::DIRECTORIES, |
| kEmptyPattern, policy); |
| EXPECT_THAT(files, UnorderedElementsAre(file, temp_subdir.GetPath())); |
| } |
| } |
| |
| TEST(FileEnumerator, FilesInParentFolderAlwaysFirst) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| const FilePath& path = temp_dir.GetPath(); |
| |
| ScopedTempDir temp_subdir; |
| ASSERT_TRUE(temp_subdir.CreateUniqueTempDirUnderPath(path)); |
| const FilePath foo_txt = path.AppendASCII("foo.txt"); |
| const FilePath bar_txt = temp_subdir.GetPath().AppendASCII("bar.txt"); |
| ASSERT_TRUE(CreateDummyFile(foo_txt)); |
| ASSERT_TRUE(CreateDummyFile(bar_txt)); |
| |
| for (auto policy : kFolderSearchPolicies) { |
| const auto files = |
| RunEnumerator(path, true, FileEnumerator::FILES, kEmptyPattern, policy); |
| EXPECT_THAT(files, ElementsAre(foo_txt, bar_txt)); |
| } |
| } |
| |
| TEST(FileEnumerator, FileInSubfolder) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| const FilePath subdir = temp_dir.GetPath().AppendASCII("subdir"); |
| ASSERT_TRUE(CreateDirectory(subdir)); |
| |
| const FilePath file = subdir.AppendASCII("test.txt"); |
| ASSERT_TRUE(CreateDummyFile(file)); |
| |
| for (auto policy : kFolderSearchPolicies) { |
| auto files = RunEnumerator(temp_dir.GetPath(), true, FileEnumerator::FILES, |
| kEmptyPattern, policy); |
| EXPECT_THAT(files, ElementsAre(file)); |
| |
| files = RunEnumerator(temp_dir.GetPath(), false, FileEnumerator::FILES, |
| kEmptyPattern, policy); |
| EXPECT_THAT(files, IsEmpty()); |
| } |
| } |
| |
| // Starboard does not support patterns. |
| #if !defined(STARBOARD) |
| TEST(FileEnumerator, FilesInSubfoldersWithFiltering) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| const FilePath test_txt = temp_dir.GetPath().AppendASCII("test.txt"); |
| const FilePath subdir_foo = temp_dir.GetPath().AppendASCII("foo_subdir"); |
| const FilePath subdir_bar = temp_dir.GetPath().AppendASCII("bar_subdir"); |
| const FilePath foo_test = subdir_foo.AppendASCII("test.txt"); |
| const FilePath foo_foo = subdir_foo.AppendASCII("foo.txt"); |
| const FilePath foo_bar = subdir_foo.AppendASCII("bar.txt"); |
| const FilePath bar_test = subdir_bar.AppendASCII("test.txt"); |
| const FilePath bar_foo = subdir_bar.AppendASCII("foo.txt"); |
| const FilePath bar_bar = subdir_bar.AppendASCII("bar.txt"); |
| ASSERT_TRUE(CreateDummyFile(test_txt)); |
| ASSERT_TRUE(CreateDirectory(subdir_foo)); |
| ASSERT_TRUE(CreateDirectory(subdir_bar)); |
| ASSERT_TRUE(CreateDummyFile(foo_test)); |
| ASSERT_TRUE(CreateDummyFile(foo_foo)); |
| ASSERT_TRUE(CreateDummyFile(foo_bar)); |
| ASSERT_TRUE(CreateDummyFile(bar_test)); |
| ASSERT_TRUE(CreateDummyFile(bar_foo)); |
| ASSERT_TRUE(CreateDummyFile(bar_bar)); |
| |
| auto files = |
| RunEnumerator(temp_dir.GetPath(), true, |
| FileEnumerator::FILES | FileEnumerator::DIRECTORIES, |
| FILE_PATH_LITERAL("foo*"), |
| FileEnumerator::FolderSearchPolicy::MATCH_ONLY); |
| EXPECT_THAT(files, |
| UnorderedElementsAre(subdir_foo, foo_test, foo_foo, foo_bar)); |
| |
| files = RunEnumerator(temp_dir.GetPath(), true, |
| FileEnumerator::FILES | FileEnumerator::DIRECTORIES, |
| FILE_PATH_LITERAL("foo*"), |
| FileEnumerator::FolderSearchPolicy::ALL); |
| EXPECT_THAT(files, UnorderedElementsAre(subdir_foo, foo_foo, bar_foo)); |
| } |
| #endif // !defined(STARBOARD) |
| |
| TEST(FileEnumerator, InvalidDirectory) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| const FilePath test_file = temp_dir.GetPath().AppendASCII("test_file"); |
| ASSERT_TRUE(CreateDummyFile(test_file)); |
| |
| // Attempt to enumerate entries at a regular file path. |
| FileEnumerator enumerator(test_file, /*recursive=*/true, |
| FileEnumerator::FILES, kEmptyPattern, |
| FileEnumerator::FolderSearchPolicy::ALL, |
| FileEnumerator::ErrorPolicy::STOP_ENUMERATION); |
| FilePath path = enumerator.Next(); |
| EXPECT_TRUE(path.empty()); |
| |
| // Slightly different outcomes between Windows and POSIX. |
| #if BUILDFLAG(IS_WIN) |
| EXPECT_EQ(File::Error::FILE_ERROR_FAILED, enumerator.GetError()); |
| #else |
| EXPECT_EQ(File::Error::FILE_ERROR_NOT_A_DIRECTORY, enumerator.GetError()); |
| #endif |
| } |
| |
| #if BUILDFLAG(IS_POSIX) && !defined(STARBOARD) |
| TEST(FileEnumerator, SymLinkLoops) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| const FilePath subdir = temp_dir.GetPath().AppendASCII("subdir"); |
| ASSERT_TRUE(CreateDirectory(subdir)); |
| |
| const FilePath file = subdir.AppendASCII("test.txt"); |
| ASSERT_TRUE(CreateDummyFile(file)); |
| |
| const FilePath link = subdir.AppendASCII("link"); |
| ASSERT_TRUE(CreateSymbolicLink(temp_dir.GetPath(), link)); |
| |
| auto files = RunEnumerator( |
| temp_dir.GetPath(), true, |
| FileEnumerator::FILES | FileEnumerator::DIRECTORIES, kEmptyPattern, |
| FileEnumerator::FolderSearchPolicy::MATCH_ONLY); |
| |
| EXPECT_THAT(files, UnorderedElementsAre(subdir, link, file)); |
| |
| files = RunEnumerator(subdir, true, |
| FileEnumerator::FILES | FileEnumerator::DIRECTORIES | |
| FileEnumerator::SHOW_SYM_LINKS, |
| kEmptyPattern, |
| FileEnumerator::FolderSearchPolicy::MATCH_ONLY); |
| |
| EXPECT_THAT(files, UnorderedElementsAre(link, file)); |
| } |
| #endif |
| |
| // Test FileEnumerator::GetInfo() on some files and ensure all the returned |
| // information is correct. |
| TEST(FileEnumerator, GetInfo) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| std::vector<TestFile> files = { |
| TestFile(FILE_PATH_LITERAL("file1"), "First"), |
| TestFile(FILE_PATH_LITERAL("file2"), "Second"), |
| TestFile(FILE_PATH_LITERAL("file3"), "Third-third-third")}; |
| SetUpTestFiles(temp_dir, files); |
| |
| FileEnumerator file_enumerator(temp_dir.GetPath(), false, |
| FileEnumerator::FILES); |
| while (!file_enumerator.Next().empty()) { |
| auto info = file_enumerator.GetInfo(); |
| bool found = false; |
| for (TestFile& file : files) { |
| if (info.GetName() == file.path.BaseName()) { |
| CheckFileAgainstInfo(info, file); |
| found = true; |
| break; |
| } |
| } |
| |
| EXPECT_TRUE(found) << "Got unexpected result " << info.GetName().value(); |
| } |
| |
| for (const TestFile& file : files) { |
| EXPECT_TRUE(file.found) |
| << "File " << file.path.value() << " was not returned"; |
| } |
| } |
| |
| // Test that FileEnumerator::GetInfo() works when searching recursively. It also |
| // tests that it returns the correct information about directories. |
| TEST(FileEnumerator, GetInfoRecursive) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| TestDirectory directories[] = {TestDirectory(FILE_PATH_LITERAL("dir1")), |
| TestDirectory(FILE_PATH_LITERAL("dir2")), |
| TestDirectory(FILE_PATH_LITERAL("dir3")), |
| TestDirectory(FILE_PATH_LITERAL("dirempty"))}; |
| |
| for (const TestDirectory& dir : directories) { |
| const FilePath dir_path = temp_dir.GetPath().Append(dir.name); |
| ASSERT_TRUE(CreateDirectory(dir_path)); |
| } |
| |
| std::vector<TestFile> files = { |
| TestFile(FILE_PATH_LITERAL("dir1"), FILE_PATH_LITERAL("file1"), "First"), |
| TestFile(FILE_PATH_LITERAL("dir1"), FILE_PATH_LITERAL("file2"), "Second"), |
| TestFile(FILE_PATH_LITERAL("dir2"), FILE_PATH_LITERAL("fileA"), |
| "Third-third-3"), |
| TestFile(FILE_PATH_LITERAL("dir3"), FILE_PATH_LITERAL(".file"), "Dot")}; |
| SetUpTestFiles(temp_dir, files); |
| |
| // Get last-modification times for directories. Must be done after we create |
| // all the files. |
| for (TestDirectory& dir : directories) { |
| const FilePath dir_path = temp_dir.GetPath().Append(dir.name); |
| ASSERT_TRUE(GetFileInfo(dir_path, dir.info)); |
| } |
| |
| FileEnumerator file_enumerator( |
| temp_dir.GetPath(), true, |
| FileEnumerator::FILES | FileEnumerator::DIRECTORIES); |
| while (!file_enumerator.Next().empty()) { |
| auto info = file_enumerator.GetInfo(); |
| bool found = false; |
| if (info.IsDirectory()) { |
| for (TestDirectory& dir : directories) { |
| if (info.GetName() == dir.name) { |
| CheckDirectoryAgainstInfo(info, dir); |
| found = true; |
| break; |
| } |
| } |
| } else { |
| for (TestFile& file : files) { |
| if (info.GetName() == file.path.BaseName()) { |
| CheckFileAgainstInfo(info, file); |
| found = true; |
| break; |
| } |
| } |
| } |
| |
| EXPECT_TRUE(found) << "Got unexpected result " << info.GetName().value(); |
| } |
| |
| for (const TestDirectory& dir : directories) { |
| EXPECT_TRUE(dir.found) << "Directory " << dir.name.value() |
| << " was not returned"; |
| } |
| for (const TestFile& file : files) { |
| EXPECT_TRUE(file.found) |
| << "File " << file.path.value() << " was not returned"; |
| } |
| } |
| |
| #if BUILDFLAG(IS_FUCHSIA) |
| // FileEnumerator::GetInfo does not work correctly with INCLUDE_DOT_DOT. |
| // https://crbug.com/1106172 |
| #elif BUILDFLAG(IS_WIN) |
| // Windows has a bug in their handling of ".."; they always report the file |
| // modification time of the current directory, not the parent directory. This is |
| // a bug in Windows, not us -- you can see it with the "dir" command (notice |
| // that the time of . and .. always match). Skip this test. |
| // https://crbug.com/1119546 |
| #else |
| // Tests that FileEnumerator::GetInfo() returns the correct info for the .. |
| // directory. |
| TEST(FileEnumerator, GetInfoDotDot) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| const FilePath::CharType kSubdir[] = FILE_PATH_LITERAL("subdir"); |
| const FilePath subdir_path = temp_dir.GetPath().Append(kSubdir); |
| ASSERT_TRUE(CreateDirectory(subdir_path)); |
| |
| std::vector<TestFile> files = { |
| TestFile(kSubdir, FILE_PATH_LITERAL("file1"), "First"), |
| TestFile(kSubdir, FILE_PATH_LITERAL("file2"), "Second"), |
| TestFile(kSubdir, FILE_PATH_LITERAL("file3"), "Third-third-third")}; |
| SetUpTestFiles(temp_dir, files); |
| |
| TestDirectory dotdot(FILE_PATH_LITERAL("..")); |
| // test_dir/subdir/.. is just test_dir. |
| ASSERT_TRUE(GetFileInfo(temp_dir.GetPath(), dotdot.info)); |
| |
| FileEnumerator file_enumerator(subdir_path, false, |
| FileEnumerator::FILES | |
| FileEnumerator::DIRECTORIES | |
| FileEnumerator::INCLUDE_DOT_DOT); |
| while (!file_enumerator.Next().empty()) { |
| auto info = file_enumerator.GetInfo(); |
| bool found = false; |
| if (info.IsDirectory()) { |
| EXPECT_EQ(info.GetName(), FilePath(FILE_PATH_LITERAL(".."))); |
| CheckDirectoryAgainstInfo(info, dotdot); |
| found = true; |
| } else { |
| for (TestFile& file : files) { |
| if (info.GetName() == file.path.BaseName()) { |
| CheckFileAgainstInfo(info, file); |
| found = true; |
| break; |
| } |
| } |
| } |
| |
| EXPECT_TRUE(found) << "Got unexpected result " << info.GetName().value(); |
| } |
| |
| EXPECT_TRUE(dotdot.found) << "Directory .. was not returned"; |
| |
| for (const TestFile& file : files) { |
| EXPECT_TRUE(file.found) |
| << "File " << file.path.value() << " was not returned"; |
| } |
| } |
| #endif // !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_WIN) |
| |
| TEST(FileEnumerator, OnlyName) { |
| ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| |
| const FilePath& path = temp_dir.GetPath(); |
| |
| // Add a directory and a file. |
| ScopedTempDir temp_subdir; |
| ASSERT_TRUE(temp_subdir.CreateUniqueTempDirUnderPath(path)); |
| const FilePath& subdir = temp_subdir.GetPath(); |
| const FilePath dummy_file = path.AppendASCII("a_file.txt"); |
| ASSERT_TRUE(CreateDummyFile(dummy_file)); |
| |
| auto found_paths = RunEnumerator( |
| path, /*recursive=*/false, FileEnumerator::FileType::NAMES_ONLY, |
| FilePath::StringType(), FileEnumerator::FolderSearchPolicy::MATCH_ONLY); |
| EXPECT_THAT(found_paths, UnorderedElementsAre(subdir, dummy_file)); |
| } |
| |
| } // namespace base |