Add foundation event dispatcher tests
This commit is contained in:
136
tests/foundation/event_tests.cpp
Normal file
136
tests/foundation/event_tests.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
#include "foundation/event.h"
|
||||
#include "test_harness.h"
|
||||
|
||||
using pp::foundation::Event;
|
||||
using pp::foundation::EventDispatcher;
|
||||
using pp::foundation::StatusCode;
|
||||
using pp::foundation::max_event_subscriptions;
|
||||
|
||||
namespace {
|
||||
|
||||
struct Receiver {
|
||||
int count = 0;
|
||||
std::uint64_t payload_sum = 0;
|
||||
std::uint64_t last_source = 0;
|
||||
};
|
||||
|
||||
void receive_event(const Event& event, void* user_data) noexcept
|
||||
{
|
||||
auto* receiver = static_cast<Receiver*>(user_data);
|
||||
++receiver->count;
|
||||
receiver->payload_sum += event.payload_u64;
|
||||
receiver->last_source = event.source_id;
|
||||
}
|
||||
|
||||
void subscribe_and_publish_matching_events(pp::tests::Harness& h)
|
||||
{
|
||||
EventDispatcher dispatcher(4);
|
||||
Receiver receiver;
|
||||
|
||||
const auto subscription = dispatcher.subscribe(7, receive_event, &receiver);
|
||||
PP_EXPECT(h, subscription.ok());
|
||||
PP_EXPECT(h, subscription.value() == 1U);
|
||||
PP_EXPECT(h, dispatcher.size() == 1U);
|
||||
PP_EXPECT(h, dispatcher.max_subscriptions() == 4U);
|
||||
|
||||
const auto delivered = dispatcher.publish(Event {
|
||||
.type = 7,
|
||||
.source_id = 42,
|
||||
.frame_id = 3,
|
||||
.payload_u64 = 11,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, delivered == 1U);
|
||||
PP_EXPECT(h, receiver.count == 1);
|
||||
PP_EXPECT(h, receiver.payload_sum == 11U);
|
||||
PP_EXPECT(h, receiver.last_source == 42U);
|
||||
}
|
||||
|
||||
void ignores_non_matching_or_zero_events(pp::tests::Harness& h)
|
||||
{
|
||||
EventDispatcher dispatcher(4);
|
||||
Receiver receiver;
|
||||
|
||||
PP_EXPECT(h, dispatcher.subscribe(2, receive_event, &receiver).ok());
|
||||
PP_EXPECT(h, dispatcher.publish(Event { .type = 3, .payload_u64 = 1 }) == 0U);
|
||||
PP_EXPECT(h, dispatcher.publish(Event { .type = 0, .payload_u64 = 1 }) == 0U);
|
||||
PP_EXPECT(h, receiver.count == 0);
|
||||
}
|
||||
|
||||
void preserves_subscription_order_and_unsubscribes(pp::tests::Harness& h)
|
||||
{
|
||||
EventDispatcher dispatcher(4);
|
||||
Receiver first;
|
||||
Receiver second;
|
||||
|
||||
const auto first_subscription = dispatcher.subscribe(9, receive_event, &first);
|
||||
const auto second_subscription = dispatcher.subscribe(9, receive_event, &second);
|
||||
PP_EXPECT(h, first_subscription.ok());
|
||||
PP_EXPECT(h, second_subscription.ok());
|
||||
|
||||
PP_EXPECT(h, dispatcher.publish(Event { .type = 9, .payload_u64 = 5 }) == 2U);
|
||||
PP_EXPECT(h, first.payload_sum == 5U);
|
||||
PP_EXPECT(h, second.payload_sum == 5U);
|
||||
|
||||
PP_EXPECT(h, dispatcher.unsubscribe(first_subscription.value()).ok());
|
||||
PP_EXPECT(h, dispatcher.publish(Event { .type = 9, .payload_u64 = 7 }) == 1U);
|
||||
PP_EXPECT(h, first.payload_sum == 5U);
|
||||
PP_EXPECT(h, second.payload_sum == 12U);
|
||||
|
||||
const auto missing = dispatcher.unsubscribe(first_subscription.value());
|
||||
PP_EXPECT(h, !missing.ok());
|
||||
PP_EXPECT(h, missing.code == StatusCode::out_of_range);
|
||||
}
|
||||
|
||||
void rejects_invalid_subscriptions_and_capacity(pp::tests::Harness& h)
|
||||
{
|
||||
EventDispatcher dispatcher(1);
|
||||
EventDispatcher zero_capacity(0);
|
||||
EventDispatcher excessive_capacity(max_event_subscriptions + 1U);
|
||||
Receiver receiver;
|
||||
|
||||
const auto zero_type = dispatcher.subscribe(0, receive_event, &receiver);
|
||||
const auto null_callback = dispatcher.subscribe(1, nullptr, &receiver);
|
||||
PP_EXPECT(h, !zero_type.ok());
|
||||
PP_EXPECT(h, zero_type.status().code == StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !null_callback.ok());
|
||||
PP_EXPECT(h, null_callback.status().code == StatusCode::invalid_argument);
|
||||
|
||||
PP_EXPECT(h, dispatcher.subscribe(1, receive_event, &receiver).ok());
|
||||
const auto full = dispatcher.subscribe(2, receive_event, &receiver);
|
||||
PP_EXPECT(h, !full.ok());
|
||||
PP_EXPECT(h, full.status().code == StatusCode::out_of_range);
|
||||
|
||||
const auto zero_capacity_result = zero_capacity.subscribe(1, receive_event, &receiver);
|
||||
const auto excessive_capacity_result = excessive_capacity.subscribe(1, receive_event, &receiver);
|
||||
PP_EXPECT(h, !zero_capacity_result.ok());
|
||||
PP_EXPECT(h, zero_capacity_result.status().code == StatusCode::out_of_range);
|
||||
PP_EXPECT(h, !excessive_capacity_result.ok());
|
||||
PP_EXPECT(h, excessive_capacity_result.status().code == StatusCode::out_of_range);
|
||||
}
|
||||
|
||||
void clear_removes_all_subscriptions(pp::tests::Harness& h)
|
||||
{
|
||||
EventDispatcher dispatcher(4);
|
||||
Receiver receiver;
|
||||
|
||||
PP_EXPECT(h, dispatcher.subscribe(1, receive_event, &receiver).ok());
|
||||
PP_EXPECT(h, dispatcher.subscribe(2, receive_event, &receiver).ok());
|
||||
dispatcher.clear();
|
||||
PP_EXPECT(h, dispatcher.empty());
|
||||
PP_EXPECT(h, dispatcher.publish(Event { .type = 1, .payload_u64 = 5 }) == 0U);
|
||||
PP_EXPECT(h, receiver.count == 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
pp::tests::Harness harness;
|
||||
harness.run("subscribe_and_publish_matching_events", subscribe_and_publish_matching_events);
|
||||
harness.run("ignores_non_matching_or_zero_events", ignores_non_matching_or_zero_events);
|
||||
harness.run("preserves_subscription_order_and_unsubscribes", preserves_subscription_order_and_unsubscribes);
|
||||
harness.run("rejects_invalid_subscriptions_and_capacity", rejects_invalid_subscriptions_and_capacity);
|
||||
harness.run("clear_removes_all_subscriptions", clear_removes_all_subscriptions);
|
||||
return harness.finish();
|
||||
}
|
||||
Reference in New Issue
Block a user