blob: 4137a5a9fecf907a5a4172f9f68a27c2f72f4125 [file] [log] [blame]
// 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 <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