| // Copyright 2018 The Fuchsia 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 "src/lib/files/glob.h" |
| |
| #include <fcntl.h> |
| #include <lib/syslog/cpp/macros.h> |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| #include "src/lib/files/directory.h" |
| #include "src/lib/files/file.h" |
| #include "src/lib/files/scoped_temp_dir.h" |
| #include "src/lib/fxl/strings/substitute.h" |
| |
| namespace files { |
| namespace { |
| |
| class TestGlob : public testing::Test { |
| protected: |
| TestGlob() { |
| // Test directory structure: |
| // a |
| // aa |
| // b |
| // c |
| // d |
| // e |
| // subdir/ |
| // abcd |
| // z |
| |
| std::vector<std::string> names = {"a", "b", "c", "d", "z", "e", "aa"}; |
| for (const auto& name : names) { |
| FX_CHECK(WriteFile(fxl::Substitute("$0/$1", dir_.path(), name), "a", 1)); |
| } |
| FX_CHECK(CreateDirectory(fxl::Substitute("$0/subdir", dir_.path()))); |
| FX_CHECK(WriteFile(fxl::Substitute("$0/subdir/abcd", dir_.path()), "a", 1)); |
| } |
| |
| std::vector<std::string> PrependPath(const std::vector<std::string>& files) { |
| std::vector<std::string> ret; |
| for (const auto& file : files) { |
| ret.push_back(fxl::Substitute("$0/$1", dir_.path(), file)); |
| } |
| return ret; |
| } |
| |
| ScopedTempDir dir_; |
| const std::vector<std::string> sorted_names_in_dir_ = {"a", "aa", "b", "c", |
| "d", "e", "subdir", "z"}; |
| }; // namespace |
| |
| TEST_F(TestGlob, Empty) { |
| Glob glob({}); |
| |
| EXPECT_EQ(glob.size(), 0u); |
| EXPECT_EQ(glob.begin(), glob.end()); |
| } |
| |
| TEST_F(TestGlob, EmptyDir) { |
| ScopedTempDir dir2; |
| auto path = fxl::Substitute("$0/*", dir2.path()); |
| Glob glob(path); |
| |
| EXPECT_EQ(glob.size(), 0u); |
| EXPECT_EQ(glob.begin(), glob.end()); |
| } |
| |
| TEST_F(TestGlob, AllFiles) { |
| auto path = fxl::Substitute("$0/*", dir_.path()); |
| Glob glob(path); |
| EXPECT_EQ(glob.size(), sorted_names_in_dir_.size()); |
| std::vector<std::string> globbed = {glob.begin(), glob.end()}; |
| EXPECT_THAT(globbed, ::testing::ElementsAreArray(PrependPath(sorted_names_in_dir_))); |
| }; |
| |
| TEST_F(TestGlob, FilePrefix) { |
| // Only "a*" files. |
| auto path = fxl::Substitute("$0/a*", dir_.path()); |
| Glob glob(path); |
| EXPECT_EQ(glob.size(), 2u); |
| std::vector<std::string> globbed = {glob.begin(), glob.end()}; |
| std::vector<std::string> expected{"a", "aa"}; |
| |
| EXPECT_THAT(globbed, ::testing::ElementsAreArray(PrependPath(expected))); |
| } |
| |
| TEST_F(TestGlob, Subdirectory) { |
| auto path = fxl::Substitute("$0/*/*", dir_.path()); |
| Glob glob(path); |
| EXPECT_EQ(glob.size(), 1u); |
| std::vector<std::string> globbed = {glob.begin(), glob.end()}; |
| std::vector<std::string> expected{"subdir/abcd"}; |
| |
| EXPECT_THAT(globbed, ::testing::ElementsAreArray(PrependPath(expected))); |
| } |
| |
| TEST_F(TestGlob, MultiplePaths) { |
| auto path = fxl::Substitute("$0/*", dir_.path()); |
| auto path2 = fxl::Substitute("$0/*/*", dir_.path()); |
| Glob glob({path, path2}); |
| EXPECT_EQ(glob.size(), sorted_names_in_dir_.size() + 1); |
| std::vector<std::string> globbed = {glob.begin(), glob.end()}; |
| std::vector<std::string> expected = sorted_names_in_dir_; |
| expected.push_back("subdir/abcd"); |
| EXPECT_THAT(globbed, ::testing::ElementsAreArray(PrependPath(expected))); |
| } |
| |
| TEST_F(TestGlob, MarkOption) { |
| // Ensure that '/' is appended to directories only. |
| auto path = fxl::Substitute("$0/*", dir_.path()); |
| Glob glob(path, {.mark = true}); |
| EXPECT_EQ(glob.size(), sorted_names_in_dir_.size()); |
| std::vector<std::string> globbed = {glob.begin(), glob.end()}; |
| auto expected = sorted_names_in_dir_; |
| expected[expected.size() - 2] += "/"; |
| EXPECT_THAT(globbed, ::testing::ElementsAreArray(PrependPath(expected))); |
| EXPECT_THAT(globbed[globbed.size() - 2], ::testing::EndsWith("subdir/")); |
| } |
| |
| TEST_F(TestGlob, NoSortOption) { |
| // Ensure we still retrieved the correct entries. |
| auto path = fxl::Substitute("$0/*", dir_.path()); |
| Glob glob(path, {.no_sort = true}); |
| std::vector<std::string> globbed = {glob.begin(), glob.end()}; |
| EXPECT_THAT(globbed, ::testing::UnorderedElementsAreArray(PrependPath(sorted_names_in_dir_))); |
| } |
| |
| TEST_F(TestGlob, Iterator) { |
| // Ensure we still retrieved the correct entries. |
| auto path = fxl::Substitute("$0/*", dir_.path()); |
| Glob glob(path); |
| auto it = glob.begin(); |
| EXPECT_TRUE(it); |
| EXPECT_FALSE(glob.end()); |
| |
| auto first = *it; |
| ++it; |
| auto second = *it; |
| --it; |
| EXPECT_TRUE(it); |
| EXPECT_EQ(*it, first); |
| ++it; |
| EXPECT_TRUE(it); |
| EXPECT_EQ(*it, second); |
| } |
| |
| } // namespace |
| } // namespace files |