1
0
mirror of https://github.com/wqking/eventpp.git synced 2024-12-27 16:41:11 +08:00
eventpp/tests/unittest/test_scopedremover.cpp
Wang Qi b565e03998
Merge pull request #33 from Martinii89/feature/scoped_remover_manual_remove
Added function for removing from scoped remover before destruction
2021-11-14 15:50:07 +08:00

452 lines
9.6 KiB
C++

#include "test.h"
#include "eventpp/utilities/scopedremover.h"
#include "eventpp/eventdispatcher.h"
#include "eventpp/hetereventdispatcher.h"
TEST_CASE("ScopedRemover, EventDispatcher")
{
using ED = eventpp::EventDispatcher<int, void ()>;
ED dispatcher;
using Remover = eventpp::ScopedRemover<ED>;
constexpr int event = 3;
std::vector<int> dataList(4);
dispatcher.appendListener(event, [&dataList]() {
++dataList[0];
});
{
Remover r1(dispatcher);
r1.prependListener(event, [&dataList]() {
++dataList[1];
});
{
Remover r2(dispatcher);
auto handle = r2.appendListener(event, [&dataList]() {
++dataList[2];
});
{
Remover r3(dispatcher);
r3.insertListener(event, [&dataList]() {
++dataList[3];
}, handle);
REQUIRE(dataList == std::vector<int> { 0, 0, 0, 0 });
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 1, 1, 1, 1 });
}
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 2, 2, 2, 1 });
}
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 3, 3, 2, 1 });
}
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 4, 3, 2, 1 });
{
ED dispatcher2;
int counter = 0;
Remover r(dispatcher2);
auto handle = r.appendListener(event, [&counter] {
++counter;
});
dispatcher2.dispatch(event);
REQUIRE(counter == 1);
REQUIRE(dispatcher2.hasAnyListener(event) == true);
r.removeListener(event, handle);
REQUIRE(dispatcher2.hasAnyListener(event) == false);
dispatcher2.dispatch(event);
REQUIRE(counter == 1);
}
}
TEST_CASE("ScopedRemover, CallbackList")
{
using CL = eventpp::CallbackList<void ()>;
CL callbackList;
using Remover = eventpp::ScopedRemover<CL>;
std::vector<int> dataList(4);
callbackList.append([&dataList]() {
++dataList[0];
});
{
Remover r1(callbackList);
r1.prepend([&dataList]() {
++dataList[1];
});
{
Remover r2(callbackList);
auto handle = r2.append([&dataList]() {
++dataList[2];
});
{
Remover r3(callbackList);
r3.insert([&dataList]() {
++dataList[3];
}, handle);
REQUIRE(dataList == std::vector<int> { 0, 0, 0, 0 });
callbackList();
REQUIRE(dataList == std::vector<int> { 1, 1, 1, 1 });
}
callbackList();
REQUIRE(dataList == std::vector<int> { 2, 2, 2, 1 });
}
callbackList();
REQUIRE(dataList == std::vector<int> { 3, 3, 2, 1 });
}
callbackList();
REQUIRE(dataList == std::vector<int> { 4, 3, 2, 1 });
{
CL callback_list2;
Remover r(callback_list2);
int counter = 0;
auto handle = r.append([&counter]{++counter;});
callback_list2();
REQUIRE(callbackList.empty() == false);
REQUIRE(counter == 1);
r.remove(handle);
callback_list2();
REQUIRE(callback_list2.empty() == true);
REQUIRE(counter == 1);
}
}
TEST_CASE("ScopedRemover, HeterEventDispatcher")
{
using ED = eventpp::HeterEventDispatcher<int, eventpp::HeterTuple<void ()> >;
ED dispatcher;
using Remover = eventpp::ScopedRemover<ED>;
constexpr int event = 3;
std::vector<int> dataList(4);
dispatcher.appendListener(event, [&dataList]() {
++dataList[0];
});
{
Remover r1(dispatcher);
r1.prependListener(event, [&dataList]() {
++dataList[1];
});
{
Remover r2(dispatcher);
auto handle = r2.appendListener(event, [&dataList]() {
++dataList[2];
});
{
Remover r3(dispatcher);
r3.insertListener(event, [&dataList]() {
++dataList[3];
}, handle);
REQUIRE(dataList == std::vector<int> { 0, 0, 0, 0 });
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 1, 1, 1, 1 });
}
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 2, 2, 2, 1 });
}
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 3, 3, 2, 1 });
}
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 4, 3, 2, 1 });
}
TEST_CASE("ScopedRemover, HeterCallbackList")
{
using CL = eventpp::HeterCallbackList<eventpp::HeterTuple<void ()> >;
CL callbackList;
using Remover = eventpp::ScopedRemover<CL>;
std::vector<int> dataList(4);
callbackList.append([&dataList]() {
++dataList[0];
});
{
Remover r1(callbackList);
r1.prepend([&dataList]() {
++dataList[1];
});
{
Remover r2(callbackList);
auto handle = r2.append([&dataList]() {
++dataList[2];
});
{
Remover r3(callbackList);
r3.insert([&dataList]() {
++dataList[3];
}, handle);
REQUIRE(dataList == std::vector<int> { 0, 0, 0, 0 });
callbackList();
REQUIRE(dataList == std::vector<int> { 1, 1, 1, 1 });
}
callbackList();
REQUIRE(dataList == std::vector<int> { 2, 2, 2, 1 });
}
callbackList();
REQUIRE(dataList == std::vector<int> { 3, 3, 2, 1 });
}
callbackList();
REQUIRE(dataList == std::vector<int> { 4, 3, 2, 1 });
}
TEST_CASE("ScopedRemover, EventDispatcher, move assignment")
{
using ED = eventpp::EventDispatcher<int, void()>;
ED dispatcher;
using Remover = eventpp::ScopedRemover<ED>;
constexpr int event = 3;
std::vector<int> dataList(2);
dispatcher.appendListener(event, [&dataList]() {
++dataList[0];
});
{
Remover moved;
{
Remover r1(dispatcher);
r1.appendListener(event, [&dataList]() {
++dataList[1];
});
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 1, 1 });
// moved = r1; // not compilable
moved = std::move(r1);
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 2, 2 });
}
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 3, 3 });
}
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 4, 3 });
}
TEST_CASE("ScopedRemover, EventDispatcher, move")
{
using ED = eventpp::EventDispatcher<int, void()>;
ED dispatcher;
using Remover = eventpp::ScopedRemover<ED>;
constexpr int event = 3;
std::vector<int> dataList(2);
dispatcher.appendListener(event, [&dataList]() {
++dataList[0];
});
{
Remover r1(dispatcher);
r1.appendListener(event, [&dataList]() {
++dataList[1];
});
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 1, 1 });
{
// Remover moved1(r1); // not compilable
Remover moved(std::move(r1));
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 2, 2 });
}
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 3, 2 });
}
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 4, 2 });
}
TEST_CASE("ScopedRemover, EventDispatcher, swap")
{
using std::swap;
using ED = eventpp::EventDispatcher<int, void()>;
ED dispatcher;
using Remover = eventpp::ScopedRemover<ED>;
constexpr int event = 3;
std::vector<int> dataList(3);
dispatcher.appendListener(event, [&dataList]() {
++dataList[0];
});
Remover r1(dispatcher);
r1.appendListener(event, [&dataList]() {
++dataList[1];
});
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 1, 1, 0 });
r1.reset();
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 2, 1, 0 });
r1.appendListener(event, [&dataList]() {
++dataList[1];
});
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 3, 2, 0 });
Remover r2(dispatcher);
swap(r1, r2);
r1.reset();
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 4, 3, 0 });
r2.appendListener(event, [&dataList]() {
++dataList[2];
});
swap(r1, r2);
r2.reset();
dispatcher.dispatch(event);
REQUIRE(dataList == std::vector<int> { 5, 4, 1 });
}
TEST_CASE("ScopedRemover, CallbackList, move assignment")
{
using CL = eventpp::CallbackList<void()>;
CL callbackList;
using Remover = eventpp::ScopedRemover<CL>;
std::vector<int> dataList(2);
callbackList.append([&dataList]() {
++dataList[0];
});
{
Remover moved;
{
Remover r1(callbackList);
r1.append([&dataList]() {
++dataList[1];
});
callbackList();
REQUIRE(dataList == std::vector<int> { 1, 1 });
// moved = r1; // not compilable
moved = std::move(r1);
callbackList();
REQUIRE(dataList == std::vector<int> { 2, 2 });
}
callbackList();
REQUIRE(dataList == std::vector<int> { 3, 3 });
}
callbackList();
REQUIRE(dataList == std::vector<int> { 4, 3 });
}
TEST_CASE("ScopedRemover, CallbackList, move")
{
using CL = eventpp::CallbackList<void()>;
CL callbackList;
using Remover = eventpp::ScopedRemover<CL>;
std::vector<int> dataList(2);
callbackList.append([&dataList]() {
++dataList[0];
});
{
Remover r1(callbackList);
r1.append([&dataList]() {
++dataList[1];
});
callbackList();
REQUIRE(dataList == std::vector<int> { 1, 1 });
{
// Remover moved1(r1); // not compilable
Remover moved(std::move(r1));
callbackList();
REQUIRE(dataList == std::vector<int> { 2, 2 });
}
callbackList();
REQUIRE(dataList == std::vector<int> { 3, 2 });
}
callbackList();
REQUIRE(dataList == std::vector<int> { 4, 2 });
}
TEST_CASE("ScopedRemover, CallbackList, swap")
{
using std::swap;
using CL = eventpp::CallbackList<void()>;
CL callbackList;
using Remover = eventpp::ScopedRemover<CL>;
std::vector<int> dataList(3);
callbackList.append([&dataList]() {
++dataList[0];
});
Remover r1(callbackList);
r1.append([&dataList]() {
++dataList[1];
});
callbackList();
REQUIRE(dataList == std::vector<int> { 1, 1, 0 });
r1.reset();
callbackList();
REQUIRE(dataList == std::vector<int> { 2, 1, 0 });
r1.append([&dataList]() {
++dataList[1];
});
callbackList();
REQUIRE(dataList == std::vector<int> { 3, 2, 0 });
Remover r2(callbackList);
swap(r1, r2);
r1.reset();
callbackList();
REQUIRE(dataList == std::vector<int> { 4, 3, 0 });
r2.append([&dataList]() {
++dataList[2];
});
swap(r1, r2);
r2.reset();
callbackList();
REQUIRE(dataList == std::vector<int> { 5, 4, 1 });
}