// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include #include "base/file_util.h" #include "base/files/file_path.h" #include "base/files/scoped_temp_dir.h" #include "base/i18n/file_util_icu.h" #include "base/message_loop/message_loop.h" #include "base/strings/stringprintf.h" #include "net/base/directory_lister.h" #include "net/base/net_errors.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" namespace net { class ListerDelegate : public DirectoryLister::DirectoryListerDelegate { public: ListerDelegate(bool recursive, bool quit_loop_after_each_file) : error_(-1), recursive_(recursive), quit_loop_after_each_file_(quit_loop_after_each_file) { } virtual void OnListFile( const DirectoryLister::DirectoryListerData& data) OVERRIDE { file_list_.push_back(data.info); paths_.push_back(data.path); if (quit_loop_after_each_file_) base::MessageLoop::current()->Quit(); } virtual void OnListDone(int error) OVERRIDE { error_ = error; base::MessageLoop::current()->Quit(); if (recursive_) CheckRecursiveSort(); else CheckSort(); } void CheckRecursiveSort() { // Check that we got files in the right order. if (!file_list_.empty()) { for (size_t previous = 0, current = 1; current < file_list_.size(); previous++, current++) { EXPECT_TRUE(file_util::LocaleAwareCompareFilenames( paths_[previous], paths_[current])); } } } void CheckSort() { // Check that we got files in the right order. if (!file_list_.empty()) { for (size_t previous = 0, current = 1; current < file_list_.size(); previous++, current++) { // Directories should come before files. if (file_list_[previous].IsDirectory() && !file_list_[current].IsDirectory()) { continue; } EXPECT_NE(FILE_PATH_LITERAL(".."), file_list_[current].GetName().BaseName().value()); EXPECT_EQ(file_list_[previous].IsDirectory(), file_list_[current].IsDirectory()); EXPECT_TRUE(file_util::LocaleAwareCompareFilenames( file_list_[previous].GetName(), file_list_[current].GetName())); } } } int error() const { return error_; } int num_files() const { return file_list_.size(); } private: int error_; bool recursive_; bool quit_loop_after_each_file_; std::vector file_list_; std::vector paths_; }; class DirectoryListerTest : public PlatformTest { public: virtual void SetUp() OVERRIDE { const int kMaxDepth = 3; const int kBranchingFactor = 4; const int kFilesPerDirectory = 5; // Randomly create a directory structure of depth 3 in a temporary root // directory. std::list > directories; ASSERT_TRUE(temp_root_dir_.CreateUniqueTempDir()); directories.push_back(std::make_pair(temp_root_dir_.path(), 0)); while (!directories.empty()) { std::pair dir_data = directories.front(); directories.pop_front(); for (int i = 0; i < kFilesPerDirectory; i++) { std::string file_name = base::StringPrintf("file_id_%d", i); base::FilePath file_path = dir_data.first.AppendASCII(file_name); base::File file(file_path, base::File::FLAG_CREATE | base::File::FLAG_WRITE); ASSERT_TRUE(file.IsValid()); } if (dir_data.second < kMaxDepth - 1) { for (int i = 0; i < kBranchingFactor; i++) { std::string dir_name = base::StringPrintf("child_dir_%d", i); base::FilePath dir_path = dir_data.first.AppendASCII(dir_name); ASSERT_TRUE(base::CreateDirectory(dir_path)); directories.push_back(std::make_pair(dir_path, dir_data.second + 1)); } } } PlatformTest::SetUp(); } const base::FilePath& root_path() const { return temp_root_dir_.path(); } private: base::ScopedTempDir temp_root_dir_; }; TEST_F(DirectoryListerTest, BigDirTest) { ListerDelegate delegate(false, false); DirectoryLister lister(root_path(), &delegate); lister.Start(); base::MessageLoop::current()->Run(); EXPECT_EQ(OK, delegate.error()); } TEST_F(DirectoryListerTest, BigDirRecursiveTest) { ListerDelegate delegate(true, false); DirectoryLister lister(root_path(), true, DirectoryLister::FULL_PATH, &delegate); lister.Start(); base::MessageLoop::current()->Run(); EXPECT_EQ(OK, delegate.error()); } TEST_F(DirectoryListerTest, CancelTest) { ListerDelegate delegate(false, true); DirectoryLister lister(root_path(), &delegate); lister.Start(); base::MessageLoop::current()->Run(); int num_files = delegate.num_files(); lister.Cancel(); base::MessageLoop::current()->RunUntilIdle(); EXPECT_EQ(num_files, delegate.num_files()); } TEST_F(DirectoryListerTest, EmptyDirTest) { base::ScopedTempDir tempDir; EXPECT_TRUE(tempDir.CreateUniqueTempDir()); bool kRecursive = false; bool kQuitLoopAfterEachFile = false; ListerDelegate delegate(kRecursive, kQuitLoopAfterEachFile); DirectoryLister lister(tempDir.path(), &delegate); lister.Start(); base::MessageLoop::current()->Run(); // Contains only the parent directory ("..") EXPECT_EQ(1, delegate.num_files()); EXPECT_EQ(OK, delegate.error()); } } // namespace net