// 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
