summaryrefslogtreecommitdiff
path: root/test/test-collection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/test-collection.cpp')
-rw-r--r--test/test-collection.cpp419
1 files changed, 352 insertions, 67 deletions
diff --git a/test/test-collection.cpp b/test/test-collection.cpp
index 00204fc..45086a9 100644
--- a/test/test-collection.cpp
+++ b/test/test-collection.cpp
@@ -8,109 +8,394 @@
#include <special_members.h>
#include <vector>
-class Base {
-public:
- Base() = default;
- virtual ~Base() = default;
- DEFAULT_MOVE_COPY(Base);
-
- virtual bool
- add()
- {
- total += 1;
- return false;
- }
-
- unsigned int total {0};
-};
-
-class Sub : public Base {
-public:
- bool
- add() override
- {
- total += 2;
- return true;
- }
-};
-
-using TestCollection = Collection<Base>;
-
-BOOST_TEST_DONT_PRINT_LOG_VALUE(Collection<Base>::Objects::const_iterator)
-BOOST_TEST_DONT_PRINT_LOG_VALUE(Collection<Base>::Objects::const_reverse_iterator)
+namespace {
+ class Base {
+ public:
+ Base() = default;
+ virtual ~Base() = default;
+ DEFAULT_MOVE_COPY(Base);
+
+ virtual bool
+ add()
+ {
+ total += 1;
+ return false;
+ }
+
+ [[nodiscard]] virtual bool
+ yes() const
+ {
+ return true;
+ }
+
+ unsigned int total {0};
+ };
+
+ class Sub : public Base {
+ public:
+ bool
+ add() override
+ {
+ total += 2;
+ return true;
+ }
+ };
+
+ class Sub1 : public Sub { };
+
+ class Sub2 : public Sub { };
+
+ class Base2 {
+ public:
+ Base2() = default;
+ virtual ~Base2() = default;
+ DEFAULT_MOVE_COPY(Base2);
+ };
+
+ class Multi : public Sub1, public Base2 { };
+
+ using TestCollection = SharedCollection<Base, Sub>;
+}
+
+BOOST_TEST_DONT_PRINT_LOG_VALUE(TestCollection::Objects::iterator)
+BOOST_TEST_DONT_PRINT_LOG_VALUE(TestCollection::Objects::const_iterator)
+BOOST_TEST_DONT_PRINT_LOG_VALUE(TestCollection::Objects::const_reverse_iterator)
+BOOST_TEST_DONT_PRINT_LOG_VALUE(TestCollection::OtherObjects<Sub>::iterator)
+BOOST_TEST_DONT_PRINT_LOG_VALUE(TestCollection::OtherObjects<Sub>::const_iterator)
BOOST_FIXTURE_TEST_SUITE(tc, TestCollection)
-BOOST_AUTO_TEST_CASE(empty)
+BOOST_AUTO_TEST_CASE(Empty)
{
+ BOOST_CHECK(TestCollection::empty());
BOOST_REQUIRE(!apply(&Base::add));
- const auto i = applyOne(&Base::add);
- BOOST_CHECK_EQUAL(i, end());
+ const auto appliedTo = applyOne(&Base::add);
+ BOOST_CHECK_EQUAL(appliedTo, end());
+ BOOST_CHECK(!find<Base>());
+ BOOST_CHECK(!find<Sub>());
+ BOOST_CHECK(!find<Sub1>());
}
-BOOST_AUTO_TEST_CASE(a_base)
+BOOST_AUTO_TEST_CASE(ABaseApply)
{
- auto b = create<Base>();
+ auto base = create<Base>();
+ BOOST_CHECK_EQUAL(objects.size(), 1);
+ BOOST_CHECK(std::get<OtherObjects<Sub>>(otherObjects).empty());
BOOST_REQUIRE(apply(&Base::add));
- BOOST_CHECK_EQUAL(b->total, 1);
- const auto i = applyOne(&Base::add);
- BOOST_CHECK_EQUAL(i, end());
+ BOOST_CHECK_EQUAL(base->total, 1);
+ const auto appliedTo = applyOne(&Base::add);
+ BOOST_CHECK_EQUAL(appliedTo, end());
+ BOOST_CHECK_EQUAL(base.get(), find<Base>());
+ BOOST_CHECK(!find<Sub>());
+ BOOST_CHECK(!find<Sub1>());
}
-BOOST_AUTO_TEST_CASE(a_rbase)
+BOOST_AUTO_TEST_CASE(EmplaceOthers)
{
- auto b = create<Base>();
+ auto base = emplace(std::make_shared<Base>());
+ BOOST_CHECK_EQUAL(objects.size(), 1);
+ BOOST_CHECK(std::get<OtherObjects<Sub>>(otherObjects).empty());
+ auto sub = emplace(std::make_shared<Sub>());
+ BOOST_CHECK_EQUAL(objects.size(), 2);
+ BOOST_CHECK_EQUAL(std::get<OtherObjects<Sub>>(otherObjects).size(), 1);
+ BOOST_CHECK_EQUAL(base.get(), find<Base>());
+ BOOST_CHECK_EQUAL(sub.get(), find<Sub>());
+ BOOST_CHECK(!find<Sub1>());
+}
+
+BOOST_AUTO_TEST_CASE(ABaseRApply)
+{
+ auto base = create<Base>();
BOOST_REQUIRE(rapply(&Base::add));
- BOOST_CHECK_EQUAL(b->total, 1);
- const auto i = rapplyOne(&Base::add);
- BOOST_CHECK_EQUAL(i, rend());
+ BOOST_CHECK_EQUAL(base->total, 1);
+ const auto appliedTo = rapplyOne(&Base::add);
+ BOOST_CHECK_EQUAL(appliedTo, rend());
}
-BOOST_AUTO_TEST_CASE(a_sub)
+BOOST_AUTO_TEST_CASE(ASubApply)
{
- auto s = create<Sub>();
+ auto sub = create<Sub>();
+ BOOST_CHECK_EQUAL(objects.size(), 1);
+ BOOST_CHECK_EQUAL(std::get<OtherObjects<Sub>>(otherObjects).size(), 1);
BOOST_REQUIRE(apply(&Base::add));
- BOOST_CHECK_EQUAL(s->total, 2);
- const auto i = applyOne(&Base::add);
- BOOST_CHECK_NE(i, end());
- BOOST_CHECK_EQUAL(*i, s);
+ BOOST_CHECK_EQUAL(sub->total, 2);
+ const auto appliedTo = applyOne(&Base::add);
+ BOOST_CHECK_NE(appliedTo, end());
+ BOOST_CHECK_EQUAL(*appliedTo, sub);
+}
+
+BOOST_AUTO_TEST_CASE(Filter)
+{
+ static_assert(TestCollection::idx<Sub>() == 0);
+ static_assert(TestCollection::idx<const Sub>() == 0);
+ static_assert(TestCollection::idx<Sub1>() == 0);
+ static_assert(TestCollection::idx<const Sub1>() == 0);
+ create<Base>();
+ BOOST_CHECK_EQUAL(1, apply<Base>(&Base::yes));
+ BOOST_CHECK_EQUAL(0, apply<Sub>(&Base::yes));
+ BOOST_CHECK_EQUAL(0, apply<Sub1>(&Base::yes));
+ BOOST_CHECK_EQUAL(objects.begin(), applyOne<Base>(&Base::yes));
+ BOOST_CHECK_EQUAL(std::get<0>(otherObjects).end(), applyOne<Sub>(&Base::yes));
+ BOOST_CHECK_EQUAL(std::get<0>(otherObjects).end(), applyOne<Sub1>(&Base::yes));
+ create<Sub>();
+ BOOST_CHECK_EQUAL(2, apply<Base>(&Base::yes));
+ BOOST_CHECK_EQUAL(1, apply<Sub>(&Base::yes));
+ BOOST_CHECK_EQUAL(0, apply<Sub1>(&Base::yes));
+ BOOST_CHECK_EQUAL(objects.begin(), applyOne<Base>(&Base::yes));
+ BOOST_CHECK_EQUAL(std::get<0>(otherObjects).begin(), applyOne<Sub>(&Base::yes));
+ BOOST_CHECK_EQUAL(std::get<0>(otherObjects).end(), applyOne<Sub1>(&Base::yes));
+ create<Sub1>();
+ BOOST_CHECK_EQUAL(3, apply<Base>(&Base::yes));
+ BOOST_CHECK_EQUAL(2, apply<Sub>(&Base::yes));
+ BOOST_CHECK_EQUAL(1, apply<Sub1>(&Base::yes));
+ BOOST_CHECK_EQUAL(objects.begin(), applyOne<Base>(&Base::yes));
+ BOOST_CHECK_EQUAL(std::get<0>(otherObjects).begin(), applyOne<Sub>(&Base::yes));
+ BOOST_CHECK_EQUAL(std::get<0>(otherObjects).begin() + 1, applyOne<Sub1>(&Base::yes));
+
+ BOOST_CHECK_EQUAL(std::get<idx<Sub>()>(otherObjects).size(), 2);
+ BOOST_CHECK_EQUAL(std::get<idx<Sub1>()>(otherObjects).size(), 2);
+
+ BOOST_CHECK_EQUAL(&objects, &containerFor<Base>());
+ BOOST_CHECK_EQUAL(&std::get<0>(otherObjects), &containerFor<Sub>());
+ BOOST_CHECK_EQUAL(&std::get<0>(otherObjects), &containerFor<Sub1>());
+}
+
+BOOST_AUTO_TEST_CASE(BeginEnd)
+{
+ BOOST_CHECK_EQUAL(0, std::distance(begin(), end()));
+ create<Sub>();
+ create<Base>();
+ BOOST_CHECK_EQUAL(2, std::distance(begin(), end()));
+}
+
+BOOST_AUTO_TEST_CASE(RBeginREnd)
+{
+ BOOST_CHECK_EQUAL(0, std::distance(rbegin(), rend()));
+ create<Sub>();
+ create<Base>();
+ BOOST_CHECK_EQUAL(2, std::distance(rbegin(), rend()));
+}
+
+BOOST_AUTO_TEST_CASE(CreateCreate)
+{
+ auto base1 = findOrCreate<Base>();
+ BOOST_CHECK(base1);
+ auto base2 = findOrCreate<Base>();
+ BOOST_CHECK_EQUAL(base1, base2);
+ auto sub1 = findOrCreate<Sub>();
+ BOOST_CHECK_NE(sub1, base1);
+ auto sub2 = findOrCreate<Sub>();
+ BOOST_CHECK_EQUAL(sub1, sub2);
+}
+
+BOOST_AUTO_TEST_CASE(CreateCreateSub)
+{
+ auto sub = findOrCreate<Sub>();
+ auto base = findOrCreate<Base>();
+ BOOST_CHECK_EQUAL(sub, base);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+using TestUniqueCollection = UniqueCollection<Base, Sub>;
+BOOST_TEST_DONT_PRINT_LOG_VALUE(TestUniqueCollection::Objects::const_iterator)
+BOOST_TEST_DONT_PRINT_LOG_VALUE(TestUniqueCollection::Objects::const_reverse_iterator)
+BOOST_TEST_DONT_PRINT_LOG_VALUE(TestUniqueCollection::Objects::iterator)
+BOOST_TEST_DONT_PRINT_LOG_VALUE(TestUniqueCollection::Objects::reverse_iterator)
+
+BOOST_FIXTURE_TEST_SUITE(utc, TestUniqueCollection)
+
+BOOST_AUTO_TEST_CASE(UniqueCreate)
+{
+ create<Base>();
+ BOOST_CHECK_EQUAL(objects.size(), 1);
+ BOOST_CHECK(std::get<OtherObjects<Sub>>(otherObjects).empty());
+ create<Sub>();
+ BOOST_CHECK_EQUAL(objects.size(), 2);
+ BOOST_CHECK_EQUAL(std::get<OtherObjects<Sub>>(otherObjects).size(), 1);
+}
+
+BOOST_AUTO_TEST_CASE(MoveAssign)
+{
+ create<Base>();
+ create<Sub>();
+
+ TestUniqueCollection::Objects other;
+ TestUniqueCollection::operator=(std::move(other));
+ BOOST_CHECK(objects.empty());
+ BOOST_CHECK(std::get<OtherObjects<Sub>>(otherObjects).empty());
+
+ other.push_back(std::make_unique<Sub>());
+ other.push_back(std::make_unique<Base>());
+ TestUniqueCollection::operator=(std::move(other));
+ BOOST_CHECK_EQUAL(objects.size(), 2);
+ BOOST_CHECK_EQUAL(std::get<OtherObjects<Sub>>(otherObjects).size(), 1);
+ BOOST_CHECK(other.empty());
+}
+
+BOOST_AUTO_TEST_CASE(ClearAll)
+{
+ create<Base>();
+ create<Sub>();
+ emplace(std::make_unique<Base>());
+ emplace(std::make_unique<Sub>());
+
+ clear();
+ BOOST_CHECK(objects.empty());
+ BOOST_CHECK(std::get<OtherObjects<Sub>>(otherObjects).empty());
+}
+
+BOOST_AUTO_TEST_CASE(RemoveAllOfSub)
+{
+ create<Base>();
+ create<Sub>();
+ emplace(std::make_unique<Base>());
+ emplace(std::make_unique<Sub>());
+ emplace(std::make_unique<Sub1>());
+
+ BOOST_CHECK_EQUAL(removeAll<Sub>(), 3);
+ BOOST_CHECK_EQUAL(objects.size(), 2);
+ BOOST_CHECK(std::get<OtherObjects<Sub>>(otherObjects).empty());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+BOOST_FIXTURE_TEST_SUITE(btc, UniqueCollection<Base>)
+
+BOOST_AUTO_TEST_CASE(NoOthers)
+{
+ create<Base>();
+ create<Sub>();
+ emplace(std::make_unique<Base>());
+ emplace(std::make_unique<Sub>());
+}
+
+BOOST_AUTO_TEST_CASE(ApplyAll)
+{
+ create<Base>();
+ BOOST_CHECK_EQUAL(0, apply<Sub>(&Base::add));
+ BOOST_CHECK_EQUAL(1, apply<Base>(&Base::add));
+ create<Sub>();
+ BOOST_CHECK_EQUAL(1, apply<Sub>(&Base::add));
+ BOOST_CHECK_EQUAL(2, apply<Base>(&Base::add));
+}
+
+BOOST_AUTO_TEST_CASE(ApplyOneType)
+{
+ create<Base>();
+ BOOST_CHECK_EQUAL(objects.end(), applyOne<Sub>(&Base::yes));
+ BOOST_CHECK_EQUAL(objects.begin(), applyOne<Base>(&Base::yes));
+ create<Sub>();
+ BOOST_CHECK_EQUAL(objects.begin() + 1, applyOne<Sub>(&Base::yes));
+ BOOST_CHECK_EQUAL(objects.begin(), applyOne<Base>(&Base::yes));
+ create<Sub1>();
+ BOOST_CHECK_EQUAL(objects.begin() + 2, applyOne<Sub1>(&Base::yes));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+using MultiCollection = Collection<std::unique_ptr<Base>, Multi, Sub, Base2>;
+
+BOOST_FIXTURE_TEST_SUITE(multi, MultiCollection)
+
+BOOST_AUTO_TEST_CASE(AddMulti)
+{
+ static_assert(MultiCollection::idx<Multi>() == 0);
+ static_assert(MultiCollection::idx<Sub>() == 1);
+ static_assert(MultiCollection::idx<Base2>() == 2);
+ create<Base>();
+ BOOST_CHECK_EQUAL(objects.size(), 1);
+ BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 0);
+ BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 0);
+ BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 0);
+ create<Sub>();
+ BOOST_CHECK_EQUAL(objects.size(), 2);
+ BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 0);
+ BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 1);
+ BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 0);
+ create<Sub1>();
+ BOOST_CHECK_EQUAL(objects.size(), 3);
+ BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 0);
+ BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 2);
+ BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 0);
+ create<Sub2>();
+ BOOST_CHECK_EQUAL(objects.size(), 4);
+ BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 0);
+ BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 3);
+ BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 0);
+ create<Multi>();
+ BOOST_CHECK_EQUAL(size(), 5);
+ BOOST_CHECK_EQUAL(size<Multi>(), 1);
+ BOOST_CHECK_EQUAL(size<Sub>(), 4);
+ BOOST_CHECK_EQUAL(size<Base2>(), 1);
+}
+
+BOOST_AUTO_TEST_CASE(RemoveMulti)
+{
+ create<Base>();
+ create<Sub>();
+ create<Sub1>();
+ create<Sub2>();
+ create<Multi>();
+ BOOST_CHECK_EQUAL(objects.size(), 5);
+ BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 1);
+ BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 4);
+ BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 1);
+
+ BOOST_CHECK_EQUAL(removeAll<Multi>(), 1);
+ BOOST_CHECK_EQUAL(objects.size(), 4);
+ BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 0);
+ BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 3);
+ BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 0);
+
+ BOOST_CHECK_EQUAL(removeAll<Sub>(), 3);
+ BOOST_CHECK_EQUAL(objects.size(), 1);
+ BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 0);
+ BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 0);
+ BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 0);
+
+ BOOST_CHECK_EQUAL(removeAll<Base>(), 1);
+ BOOST_CHECK_EQUAL(objects.size(), 0);
+ BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 0);
+ BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 0);
+ BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 0);
}
BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_CASE(wrapped_ptr_file_cons)
+BOOST_AUTO_TEST_CASE(WrappedPtrFileCons)
{
using FilePtr = wrapped_ptr<FILE, &fclose>;
- const FilePtr fp {fopen, "/dev/null", "r"};
- BOOST_REQUIRE(fp);
- BOOST_CHECK_NO_THROW(fflush(fp));
+ const FilePtr file {fopen, "/dev/null", "r"};
+ BOOST_REQUIRE(file);
+ BOOST_CHECK_NO_THROW(fflush(file));
- BOOST_CHECK_EQUAL(fp.get(), fp.operator->());
- BOOST_CHECK_EQUAL(fp.get(), fp.operator FILE *());
+ BOOST_CHECK_EQUAL(file.get(), file.operator->());
+ BOOST_CHECK_EQUAL(file.get(), file.operator FILE *());
}
-BOOST_AUTO_TEST_CASE(wrapped_ptr_file_move)
+BOOST_AUTO_TEST_CASE(WrappedPtrFileMove)
{
using FilePtr = wrapped_ptr<FILE, &fclose>;
- FilePtr fp {fopen, "/dev/null", "r"};
- BOOST_REQUIRE(fp);
+ FilePtr file {fopen, "/dev/null", "r"};
+ BOOST_REQUIRE(file);
- FilePtr fp2 {std::move(fp)};
- BOOST_REQUIRE(!fp);
+ FilePtr fp2 {std::move(file)};
+ BOOST_REQUIRE(!file);
BOOST_REQUIRE(fp2);
- fp = std::move(fp2);
- BOOST_REQUIRE(fp);
+ file = std::move(fp2);
+ BOOST_REQUIRE(file);
BOOST_REQUIRE(!fp2);
FilePtr fp3 {fopen, "/dev/null", "r"};
- fp = std::move(fp3);
+ file = std::move(fp3);
}
-BOOST_AUTO_TEST_CASE(wrapped_ptr_file_typed)
+BOOST_AUTO_TEST_CASE(WrappedPtrFileTyped)
{
using FilePtr = wrapped_ptrt<FILE, &fopen, &fclose>;
- const FilePtr fp {"/dev/null", "r"};
- BOOST_REQUIRE(fp);
- BOOST_CHECK_NO_THROW(fflush(fp));
+ const FilePtr file {"/dev/null", "r"};
+ BOOST_REQUIRE(file);
+ BOOST_CHECK_NO_THROW(fflush(file));
}