Skip to content

Commit

Permalink
Remove googletest dependency.
Browse files Browse the repository at this point in the history
  • Loading branch information
asoffer committed Jan 21, 2024
1 parent 8aad460 commit bf01201
Show file tree
Hide file tree
Showing 10 changed files with 345 additions and 313 deletions.
1 change: 0 additions & 1 deletion MODULE.bazel
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
bazel_dep(name = "abseil-cpp", repo_name = "com_google_absl", version = "20230125.1")
bazel_dep(name = "googletest", repo_name = "com_google_googletest", version = "1.12.1")
4 changes: 2 additions & 2 deletions nth/container/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ cc_test(
srcs = ["flyweight_map_test.cc"],
deps = [
":flyweight_map",
"@com_google_googletest//:gtest_main",
"//nth/test:main",
],
)

Expand All @@ -54,7 +54,7 @@ cc_test(
srcs = ["flyweight_set_test.cc"],
deps = [
":flyweight_set",
"@com_google_googletest//:gtest_main",
"//nth/test:main",
],
)

Expand Down
266 changes: 146 additions & 120 deletions nth/container/flyweight_map_test.cc
Original file line number Diff line number Diff line change
@@ -1,222 +1,248 @@
#include "nth/container/flyweight_map.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "nth/test/test.h"

namespace nth {
namespace {

using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::Pair;
using ::nth::debug::ElementsAreSequentially;

MATCHER_P(IteratorRefersTo, matcher, "") {
return ::testing::ExplainMatchResult(matcher, *arg, result_listener);
}

TEST(FlyweightMap, DefaultConstruction) {
NTH_TEST("flyweight_map/default-construction") {
flyweight_map<int, std::string> f;
EXPECT_TRUE(f.empty());
EXPECT_EQ(f.size(), 0);
NTH_EXPECT(f.empty());
NTH_EXPECT(f.size() == size_t{0});
}

TEST(FlyweightMap, TryEmplace) {
NTH_TEST("flyweight_map/try-emplace") {
flyweight_map<int, std::string> f;

auto [p1, inserted1] = f.try_emplace(1, 1, 'x');
EXPECT_FALSE(f.empty());
EXPECT_EQ(f.size(), 1);
NTH_EXPECT(not f.empty());
NTH_EXPECT(f.size() == size_t{1});

auto [p2, inserted2] = f.try_emplace(2, 1, 'y');
EXPECT_FALSE(f.empty());
EXPECT_EQ(f.size(), 2);
NTH_EXPECT(not f.empty());
NTH_EXPECT(f.size() == size_t{2});

auto [p3, inserted3] = f.try_emplace(1, 1, 'z');
EXPECT_FALSE(f.empty());
EXPECT_EQ(f.size(), 2);
NTH_EXPECT(not f.empty());
NTH_EXPECT(f.size() == size_t{2});

EXPECT_TRUE(inserted1);
EXPECT_TRUE(inserted2);
EXPECT_FALSE(inserted3);
NTH_EXPECT(inserted1);
NTH_EXPECT(inserted2);
NTH_EXPECT(not inserted3);

EXPECT_NE(p1, p2);
EXPECT_EQ(p1, p3);
NTH_EXPECT(p1 != p2);
NTH_EXPECT(p1 == p3);

EXPECT_THAT(f, ElementsAre(Pair(1, "x"), Pair(2, "y")));
NTH_EXPECT(
f >>= ElementsAreSequentially(std::pair<int const, std::string>(1, "x"),
std::pair<int const, std::string>(2, "y")));
}

TEST(FlyweightMap, BracketOperator) {
NTH_TEST("flyweight_map/operator[]") {
flyweight_map<int, std::string> f;

f[1];
EXPECT_FALSE(f.empty());
EXPECT_EQ(f.size(), 1);
EXPECT_THAT(f.find(1), IteratorRefersTo(Pair(1, "")));
NTH_EXPECT(not f.empty());
NTH_EXPECT(f.size() == size_t{1});
NTH_EXPECT(*f.find(1) == std::pair<int const, std::string>(1, ""));

f[1] = "a";
EXPECT_FALSE(f.empty());
EXPECT_EQ(f.size(), 1);
EXPECT_THAT(f.find(1), IteratorRefersTo(Pair(1, "a")));
NTH_EXPECT(not f.empty());
NTH_EXPECT(f.size() == size_t{1});
NTH_EXPECT(*f.find(1) == std::pair<int const, std::string>(1, "a"));

f[2] = "b";
EXPECT_FALSE(f.empty());
EXPECT_EQ(f.size(), 2);
EXPECT_THAT(f.find(2), IteratorRefersTo(Pair(2, "b")));
NTH_EXPECT(not f.empty());
NTH_EXPECT(f.size() == size_t{2});
NTH_EXPECT(*f.find(2) == std::pair<int const, std::string>(2, "b"));

f[1] = "c";
EXPECT_FALSE(f.empty());
EXPECT_EQ(f.size(), 2);
EXPECT_THAT(f.find(1), IteratorRefersTo(Pair(1, "c")));
NTH_EXPECT(not f.empty());
NTH_EXPECT(f.size() == size_t{2});
NTH_EXPECT(*f.find(1) == std::pair<int const, std::string>(1, "c"));

EXPECT_THAT(f, ElementsAre(Pair(1, "c"), Pair(2, "b")));
NTH_EXPECT(
f >>= ElementsAreSequentially(std::pair<int const, std::string>(1, "c"),
std::pair<int const, std::string>(2, "b")));
}

TEST(FlyweightMap, ListInitialization) {
NTH_TEST("flyweight_map/list-initialization") {
flyweight_map<int, std::string> f{{3, "a"}, {2, "b"}, {1, "c"},
{2, "d"}, {3, "e"}, {4, "f"}};

EXPECT_FALSE(f.empty());
EXPECT_EQ(f.size(), 4);
NTH_EXPECT(not f.empty());
NTH_EXPECT(f.size() == size_t{4});

EXPECT_THAT(
f, ElementsAre(Pair(3, "a"), Pair(2, "b"), Pair(1, "c"), Pair(4, "f")));
NTH_EXPECT(
f >>= ElementsAreSequentially(std::pair<int const, std::string>(3, "a"),
std::pair<int const, std::string>(2, "b"),
std::pair<int const, std::string>(1, "c"),
std::pair<int const, std::string>(4, "f")));
}

TEST(FlyweightMap, Clear) {
NTH_TEST("flyweight_map/clear") {
flyweight_map<int, std::string> f{{1, "a"}, {2, "b"}, {3, "c"}, {4, "d"}};
EXPECT_FALSE(f.empty());
EXPECT_EQ(f.size(), 4);
NTH_EXPECT(not f.empty());
NTH_EXPECT(f.size() == size_t{4});
f.clear();
EXPECT_TRUE(f.empty());
EXPECT_EQ(f.size(), 0);
NTH_EXPECT(f.empty());
NTH_EXPECT(f.size() == size_t{0});
}

TEST(FlyweightMap, CopyConstruction) {
NTH_TEST("flyweight_map/copy-construction") {
flyweight_map<int, std::string> f{{1, "a"}, {2, "b"}, {3, "c"}, {4, "d"}};
flyweight_map<int, std::string> g = f;

EXPECT_FALSE(f.empty());
EXPECT_EQ(f.size(), 4);
NTH_EXPECT(not f.empty());
NTH_EXPECT(f.size() == size_t{4});

EXPECT_FALSE(g.empty());
EXPECT_EQ(g.size(), 4);
NTH_EXPECT(not g.empty());
NTH_EXPECT(g.size() == size_t{4});

EXPECT_THAT(
f, ElementsAre(Pair(1, "a"), Pair(2, "b"), Pair(3, "c"), Pair(4, "d")));
EXPECT_THAT(
g, ElementsAre(Pair(1, "a"), Pair(2, "b"), Pair(3, "c"), Pair(4, "d")));
NTH_EXPECT(
f >>= ElementsAreSequentially(std::pair<int const, std::string>(1, "a"),
std::pair<int const, std::string>(2, "b"),
std::pair<int const, std::string>(3, "c"),
std::pair<int const, std::string>(4, "d")));
NTH_EXPECT(
g >>= ElementsAreSequentially(std::pair<int const, std::string>(1, "a"),
std::pair<int const, std::string>(2, "b"),
std::pair<int const, std::string>(3, "c"),
std::pair<int const, std::string>(4, "d")));

// Ensure that the members of `g` are not referencing into `f`
f[1] = "A";
EXPECT_THAT(g.find(1), IteratorRefersTo(Pair(1, "a")));
NTH_EXPECT(*g.find(1) == std::pair<int const, std::string>(1, "a"));
}

TEST(FlyweightMap, MoveConstruction) {
NTH_TEST("flyweight_map/move-construction") {
flyweight_map<int, std::string> f{{1, "a"}, {2, "b"}, {3, "c"}, {4, "d"}};
flyweight_map<int, std::string> g = std::move(f);

EXPECT_FALSE(g.empty());
EXPECT_EQ(g.size(), 4);
EXPECT_THAT(
g, ElementsAre(Pair(1, "a"), Pair(2, "b"), Pair(3, "c"), Pair(4, "d")));
EXPECT_NE(g.find(1), g.end());
NTH_EXPECT(not g.empty());
NTH_EXPECT(g.size() == size_t{4});
NTH_EXPECT(
g >>= ElementsAreSequentially(std::pair<int const, std::string>(1, "a"),
std::pair<int const, std::string>(2, "b"),
std::pair<int const, std::string>(3, "c"),
std::pair<int const, std::string>(4, "d")));
NTH_EXPECT(g.find(1) != g.end());
}

TEST(FlyweightMap, CopyAssignment) {
NTH_TEST("flyweight_map/copy-assignment") {
flyweight_map<int, std::string> f{{1, "a"}, {2, "b"}, {3, "c"}, {4, "d"}};
flyweight_map<int, std::string> g;
g = f;

EXPECT_FALSE(f.empty());
EXPECT_EQ(f.size(), 4);
NTH_EXPECT(not f.empty());
NTH_EXPECT(f.size() == size_t{4});

EXPECT_FALSE(g.empty());
EXPECT_EQ(g.size(), 4);
NTH_EXPECT(not g.empty());
NTH_EXPECT(g.size() == size_t{4});

EXPECT_THAT(
f, ElementsAre(Pair(1, "a"), Pair(2, "b"), Pair(3, "c"), Pair(4, "d")));
EXPECT_THAT(
g, ElementsAre(Pair(1, "a"), Pair(2, "b"), Pair(3, "c"), Pair(4, "d")));
NTH_EXPECT(
f >>= ElementsAreSequentially(std::pair<int const, std::string>(1, "a"),
std::pair<int const, std::string>(2, "b"),
std::pair<int const, std::string>(3, "c"),
std::pair<int const, std::string>(4, "d")));
NTH_EXPECT(
g >>= ElementsAreSequentially(std::pair<int const, std::string>(1, "a"),
std::pair<int const, std::string>(2, "b"),
std::pair<int const, std::string>(3, "c"),
std::pair<int const, std::string>(4, "d")));

f[1] = "A";
EXPECT_THAT(g.find(1), IteratorRefersTo(Pair(1, "a")));
NTH_EXPECT(*g.find(1) == std::pair<int const, std::string>(1, "a"));
}

TEST(FlyweightMap, MoveAssignment) {
NTH_TEST("flyweight_map/move-assignment") {
flyweight_map<int, std::string> f{{1, "a"}, {2, "b"}, {3, "c"}, {4, "d"}};
flyweight_map<int, std::string> g;
g = std::move(f);

EXPECT_FALSE(g.empty());
EXPECT_EQ(g.size(), 4);
EXPECT_THAT(
g, ElementsAre(Pair(1, "a"), Pair(2, "b"), Pair(3, "c"), Pair(4, "d")));
NTH_EXPECT(not g.empty());
NTH_EXPECT(g.size() == size_t{4});
NTH_EXPECT(
g >>= ElementsAreSequentially(std::pair<int const, std::string>(1, "a"),
std::pair<int const, std::string>(2, "b"),
std::pair<int const, std::string>(3, "c"),
std::pair<int const, std::string>(4, "d")));
}

TEST(FlyweightMap, Iterators) {
NTH_TEST("flyweight_map/iterators") {
flyweight_map<int, std::string> f{{1, "a"}, {2, "b"}, {3, "c"},
{4, "d"}, {1, "e"}, {2, "f"}};
EXPECT_THAT(
std::vector(f.begin(), f.end()),
ElementsAre(Pair(1, "a"), Pair(2, "b"), Pair(3, "c"), Pair(4, "d")));
EXPECT_THAT(
std::vector(f.cbegin(), f.cend()),
ElementsAre(Pair(1, "a"), Pair(2, "b"), Pair(3, "c"), Pair(4, "d")));
EXPECT_THAT(
std::vector(f.rbegin(), f.rend()),
ElementsAre(Pair(4, "d"), Pair(3, "c"), Pair(2, "b"), Pair(1, "a")));
EXPECT_THAT(
std::vector(f.crbegin(), f.crend()),
ElementsAre(Pair(4, "d"), Pair(3, "c"), Pair(2, "b"), Pair(1, "a")));
}

TEST(FlyweightMap, ConstAccess) {
NTH_EXPECT(std::vector(f.begin(), f.end()) >>= ElementsAreSequentially(
std::pair<int const, std::string>(1, "a"),
std::pair<int const, std::string>(2, "b"),
std::pair<int const, std::string>(3, "c"),
std::pair<int const, std::string>(4, "d")));
NTH_EXPECT(std::vector(f.cbegin(), f.cend()) >>= ElementsAreSequentially(
std::pair<int const, std::string>(1, "a"),
std::pair<int const, std::string>(2, "b"),
std::pair<int const, std::string>(3, "c"),
std::pair<int const, std::string>(4, "d")));
NTH_EXPECT(std::vector(f.rbegin(), f.rend()) >>= ElementsAreSequentially(
std::pair<int const, std::string>(4, "d"),
std::pair<int const, std::string>(3, "c"),
std::pair<int const, std::string>(2, "b"),
std::pair<int const, std::string>(1, "a")));
NTH_EXPECT(std::vector(f.crbegin(), f.crend()) >>= ElementsAreSequentially(
std::pair<int const, std::string>(4, "d"),
std::pair<int const, std::string>(3, "c"),
std::pair<int const, std::string>(2, "b"),
std::pair<int const, std::string>(1, "a")));
}

NTH_TEST("flyweight_map/const-access") {
flyweight_map<int, std::string> const f{
{1, "a"}, {2, "b"}, {1, "c"}, {3, "d"}, {1, "e"}};
EXPECT_THAT(f.front(), Pair(1, "a"));
EXPECT_THAT(f.back(), Pair(3, "d"));
NTH_EXPECT(f.front() == std::pair<int const, std::string>(1, "a"));
NTH_EXPECT(f.back() == std::pair<int const, std::string>(3, "d"));
}

TEST(FlyweightMap, Access) {
NTH_TEST("flyweight_map/access") {
flyweight_map<int, std::string> f{
{1, "a"}, {2, "b"}, {1, "c"}, {3, "d"}, {1, "e"}};
EXPECT_THAT(f.front(), Pair(1, "a"));
EXPECT_THAT(f.back(), Pair(3, "d"));
NTH_EXPECT(f.front() == std::pair<int const, std::string>(1, "a"));
NTH_EXPECT(f.back() == std::pair<int const, std::string>(3, "d"));

f.front().second = "A";
f.back().second = "D";
EXPECT_THAT(f.front(), Pair(1, "A"));
EXPECT_THAT(f.back(), Pair(3, "D"));
NTH_EXPECT(f.front() == std::pair<int const, std::string>(1, "A"));
NTH_EXPECT(f.back() == std::pair<int const, std::string>(3, "D"));
}

TEST(FlyweightMap, Find) {
NTH_TEST("flyweight_map/find") {
flyweight_map<int, std::string> f{{1, "a"}, {2, "b"}, {3, "c"}, {4, "d"}};
EXPECT_EQ(f.find(0), f.end());
EXPECT_EQ(f.find(1), f.begin());
EXPECT_THAT(*f.find(4), Pair(4, "d"));
ASSERT_NE(f.find(4), f.end());
EXPECT_EQ(std::distance(f.begin(), f.find(4)), 3);
NTH_EXPECT(f.find(0) == f.end());
NTH_EXPECT(f.find(1) == f.begin());
NTH_EXPECT(*f.find(4) == std::pair<int const, std::string>(4, "d"));
NTH_ASSERT(f.find(4) != f.end());
NTH_EXPECT(std::distance(f.begin(), f.find(4)) == 3);
}

TEST(FlyweightMap, FromIndex) {
NTH_TEST("flyweight_map/from-index") {
flyweight_map<int, std::string> f{{1, "a"}, {2, "b"}, {3, "c"}, {4, "d"}};
EXPECT_THAT(f.from_index(0), Pair(1, "a"));
EXPECT_THAT(f.from_index(1), Pair(2, "b"));
EXPECT_THAT(f.from_index(2), Pair(3, "c"));
EXPECT_THAT(f.from_index(3), Pair(4, "d"));
NTH_EXPECT(f.from_index(0) == std::pair<int const, std::string>(1, "a"));
NTH_EXPECT(f.from_index(1) == std::pair<int const, std::string>(2, "b"));
NTH_EXPECT(f.from_index(2) == std::pair<int const, std::string>(3, "c"));
NTH_EXPECT(f.from_index(3) == std::pair<int const, std::string>(4, "d"));

auto const& cf = f;
EXPECT_THAT(cf.from_index(0), Pair(1, "a"));
EXPECT_THAT(cf.from_index(1), Pair(2, "b"));
EXPECT_THAT(cf.from_index(2), Pair(3, "c"));
EXPECT_THAT(cf.from_index(3), Pair(4, "d"));
NTH_EXPECT(cf.from_index(0) == std::pair<int const, std::string>(1, "a"));
NTH_EXPECT(cf.from_index(1) == std::pair<int const, std::string>(2, "b"));
NTH_EXPECT(cf.from_index(2) == std::pair<int const, std::string>(3, "c"));
NTH_EXPECT(cf.from_index(3) == std::pair<int const, std::string>(4, "d"));
}

TEST(FlyweightMap, StressTest) {
NTH_TEST("flyweight_map/stress-test") {
flyweight_map<size_t, size_t> f;
for (size_t i = 0; i < 1000; ++i) {
f.try_emplace(i);
for (auto [j, ignored] : f) { ASSERT_EQ(f.index(j), j) << i; }
for (auto [j, ignored] : f) { NTH_ASSERT(f.index(j) == j); }
}
}

Expand Down
Loading

0 comments on commit bf01201

Please sign in to comment.