1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/i18n/file_util_icu.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/strings/stringprintf.h"
14 #include "net/base/directory_lister.h"
15 #include "net/base/net_errors.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "testing/platform_test.h"
21 class ListerDelegate : public DirectoryLister::DirectoryListerDelegate {
23 ListerDelegate(bool recursive,
24 bool quit_loop_after_each_file)
26 recursive_(recursive),
27 quit_loop_after_each_file_(quit_loop_after_each_file) {
30 virtual void OnListFile(
31 const DirectoryLister::DirectoryListerData& data) OVERRIDE {
32 file_list_.push_back(data.info);
33 paths_.push_back(data.path);
34 if (quit_loop_after_each_file_)
35 base::MessageLoop::current()->Quit();
38 virtual void OnListDone(int error) OVERRIDE {
40 base::MessageLoop::current()->Quit();
47 void CheckRecursiveSort() {
48 // Check that we got files in the right order.
49 if (!file_list_.empty()) {
50 for (size_t previous = 0, current = 1;
51 current < file_list_.size();
52 previous++, current++) {
53 EXPECT_TRUE(base::i18n::LocaleAwareCompareFilenames(
54 paths_[previous], paths_[current]));
60 // Check that we got files in the right order.
61 if (!file_list_.empty()) {
62 for (size_t previous = 0, current = 1;
63 current < file_list_.size();
64 previous++, current++) {
65 // Directories should come before files.
66 if (file_list_[previous].IsDirectory() &&
67 !file_list_[current].IsDirectory()) {
70 EXPECT_NE(FILE_PATH_LITERAL(".."),
71 file_list_[current].GetName().BaseName().value());
72 EXPECT_EQ(file_list_[previous].IsDirectory(),
73 file_list_[current].IsDirectory());
74 EXPECT_TRUE(base::i18n::LocaleAwareCompareFilenames(
75 file_list_[previous].GetName(),
76 file_list_[current].GetName()));
81 int error() const { return error_; }
83 int num_files() const { return file_list_.size(); }
88 bool quit_loop_after_each_file_;
89 std::vector<base::FileEnumerator::FileInfo> file_list_;
90 std::vector<base::FilePath> paths_;
93 class DirectoryListerTest : public PlatformTest {
96 virtual void SetUp() OVERRIDE {
97 const int kMaxDepth = 3;
98 const int kBranchingFactor = 4;
99 const int kFilesPerDirectory = 5;
101 // Randomly create a directory structure of depth 3 in a temporary root
103 std::list<std::pair<base::FilePath, int> > directories;
104 ASSERT_TRUE(temp_root_dir_.CreateUniqueTempDir());
105 directories.push_back(std::make_pair(temp_root_dir_.path(), 0));
106 while (!directories.empty()) {
107 std::pair<base::FilePath, int> dir_data = directories.front();
108 directories.pop_front();
109 for (int i = 0; i < kFilesPerDirectory; i++) {
110 std::string file_name = base::StringPrintf("file_id_%d", i);
111 base::FilePath file_path = dir_data.first.AppendASCII(file_name);
112 base::File file(file_path,
113 base::File::FLAG_CREATE | base::File::FLAG_WRITE);
114 ASSERT_TRUE(file.IsValid());
116 if (dir_data.second < kMaxDepth - 1) {
117 for (int i = 0; i < kBranchingFactor; i++) {
118 std::string dir_name = base::StringPrintf("child_dir_%d", i);
119 base::FilePath dir_path = dir_data.first.AppendASCII(dir_name);
120 ASSERT_TRUE(base::CreateDirectory(dir_path));
121 directories.push_back(std::make_pair(dir_path, dir_data.second + 1));
125 PlatformTest::SetUp();
128 const base::FilePath& root_path() const {
129 return temp_root_dir_.path();
133 base::ScopedTempDir temp_root_dir_;
136 TEST_F(DirectoryListerTest, BigDirTest) {
137 ListerDelegate delegate(false, false);
138 DirectoryLister lister(root_path(), &delegate);
141 base::MessageLoop::current()->Run();
143 EXPECT_EQ(OK, delegate.error());
146 TEST_F(DirectoryListerTest, BigDirRecursiveTest) {
147 ListerDelegate delegate(true, false);
148 DirectoryLister lister(root_path(), true, DirectoryLister::FULL_PATH,
152 base::MessageLoop::current()->Run();
154 EXPECT_EQ(OK, delegate.error());
157 TEST_F(DirectoryListerTest, CancelTest) {
158 ListerDelegate delegate(false, true);
159 DirectoryLister lister(root_path(), &delegate);
162 base::MessageLoop::current()->Run();
164 int num_files = delegate.num_files();
168 base::MessageLoop::current()->RunUntilIdle();
170 EXPECT_EQ(num_files, delegate.num_files());
173 TEST_F(DirectoryListerTest, EmptyDirTest) {
174 base::ScopedTempDir tempDir;
175 EXPECT_TRUE(tempDir.CreateUniqueTempDir());
177 bool kRecursive = false;
178 bool kQuitLoopAfterEachFile = false;
179 ListerDelegate delegate(kRecursive, kQuitLoopAfterEachFile);
180 DirectoryLister lister(tempDir.path(), &delegate);
183 base::MessageLoop::current()->Run();
185 // Contains only the parent directory ("..")
186 EXPECT_EQ(1, delegate.num_files());
187 EXPECT_EQ(OK, delegate.error());