#include #include #include #include #include using namespace std; using namespace std::chrono_literals; using namespace crepe; class EventManagerTest : public ::testing::Test { protected: Mediator mediator; EventManager event_mgr {mediator}; void SetUp() override { // Clear any existing subscriptions or events before each test event_mgr.clear(); } void TearDown() override { // Ensure cleanup after each test event_mgr.clear(); } }; TEST_F(EventManagerTest, EventSubscription) { EventHandler key_handler = [](const KeyPressEvent & e) { return true; }; // Subscribe to KeyPressEvent event_mgr.subscribe(key_handler, 1); // Verify subscription (not directly verifiable; test by triggering event) event_mgr.trigger_event( KeyPressEvent { .repeat = true, .key = Keycode::A, }, 1 ); event_mgr.trigger_event( KeyPressEvent { .repeat = true, .key = Keycode::A, }, EventManager::CHANNEL_ALL ); } TEST_F(EventManagerTest, EventManagerTest_trigger_all_channels) { bool triggered = false; EventHandler mouse_handler = [&](const MouseClickEvent & e) { triggered = true; EXPECT_EQ(e.mouse_pos.x, 100); EXPECT_EQ(e.mouse_pos.y, 200); EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); return false; }; event_mgr.subscribe(mouse_handler, EventManager::CHANNEL_ALL); MouseClickEvent click_event {.mouse_pos = {100, 200}, .button = MouseButton::LEFT_MOUSE}; event_mgr.trigger_event(click_event, EventManager::CHANNEL_ALL); EXPECT_TRUE(triggered); } TEST_F(EventManagerTest, EventManagerTest_trigger_one_channel) { bool triggered = false; int test_channel = 1; EventHandler mouse_handler = [&](const MouseClickEvent & e) { triggered = true; EXPECT_EQ(e.mouse_pos.x, 100); EXPECT_EQ(e.mouse_pos.y, 200); EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); return false; }; event_mgr.subscribe(mouse_handler, test_channel); MouseClickEvent click_event {.mouse_pos = {100, 200}, .button = MouseButton::LEFT_MOUSE}; event_mgr.trigger_event(click_event, EventManager::CHANNEL_ALL); EXPECT_FALSE(triggered); event_mgr.trigger_event(click_event, test_channel); } TEST_F(EventManagerTest, EventManagerTest_callback_propagation) { // Flags to track handler calls bool triggered_true = false; bool triggered_false = false; // Handlers EventHandler mouse_handler_true = [&](const MouseClickEvent & e) { triggered_true = true; EXPECT_EQ(e.mouse_pos.x, 100); EXPECT_EQ(e.mouse_pos.y, 200); EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); return true; // Stops propagation }; EventHandler mouse_handler_false = [&](const MouseClickEvent & e) { triggered_false = true; EXPECT_EQ(e.mouse_pos.x, 100); EXPECT_EQ(e.mouse_pos.y, 200); EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); return false; // Allows propagation }; // Test event MouseClickEvent click_event {.mouse_pos = {100, 200}, .button = MouseButton::LEFT_MOUSE}; event_mgr.subscribe(mouse_handler_true, EventManager::CHANNEL_ALL); event_mgr.subscribe(mouse_handler_false, EventManager::CHANNEL_ALL); // Trigger event event_mgr.trigger_event(click_event, EventManager::CHANNEL_ALL); // Check that only the true handler was triggered EXPECT_TRUE(triggered_true); EXPECT_FALSE(triggered_false); // Reset and clear triggered_true = false; triggered_false = false; event_mgr.clear(); event_mgr.subscribe(mouse_handler_false, EventManager::CHANNEL_ALL); event_mgr.subscribe(mouse_handler_true, EventManager::CHANNEL_ALL); // Trigger event again event_mgr.trigger_event(click_event, EventManager::CHANNEL_ALL); // Check that both handlers were triggered EXPECT_TRUE(triggered_true); EXPECT_TRUE(triggered_false); } TEST_F(EventManagerTest, EventManagerTest_queue_dispatch) { bool triggered1 = false; bool triggered2 = false; int test_channel = 1; EventHandler mouse_handler1 = [&](const MouseClickEvent & e) { triggered1 = true; EXPECT_EQ(e.mouse_pos.x, 100); EXPECT_EQ(e.mouse_pos.y, 200); EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); return false; // Allows propagation }; EventHandler mouse_handler2 = [&](const MouseClickEvent & e) { triggered2 = true; EXPECT_EQ(e.mouse_pos.x, 100); EXPECT_EQ(e.mouse_pos.y, 200); EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); return false; // Allows propagation }; event_mgr.subscribe(mouse_handler1); event_mgr.subscribe(mouse_handler2, test_channel); event_mgr.queue_event( MouseClickEvent {.mouse_pos = {100, 200}, .button = MouseButton::LEFT_MOUSE} ); event_mgr.queue_event( MouseClickEvent {.mouse_pos = {100, 200}, .button = MouseButton::LEFT_MOUSE}, test_channel ); event_mgr.dispatch_events(); EXPECT_TRUE(triggered1); EXPECT_TRUE(triggered2); } TEST_F(EventManagerTest, EventManagerTest_unsubscribe) { // Flags to track if handlers are triggered bool triggered1 = false; bool triggered2 = false; // Define EventHandlers EventHandler mouse_handler1 = [&](const MouseClickEvent & e) { triggered1 = true; EXPECT_EQ(e.mouse_pos.x, 100); EXPECT_EQ(e.mouse_pos.y, 200); EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); return false; // Allows propagation }; EventHandler mouse_handler2 = [&](const MouseClickEvent & e) { triggered2 = true; EXPECT_EQ(e.mouse_pos.x, 100); EXPECT_EQ(e.mouse_pos.y, 200); EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); return false; // Allows propagation }; // Subscribe handlers subscription_t handler1_id = event_mgr.subscribe(mouse_handler1); subscription_t handler2_id = event_mgr.subscribe(mouse_handler2); // Queue events event_mgr.queue_event( MouseClickEvent {.mouse_pos = {100, 200}, .button = MouseButton::LEFT_MOUSE} ); // Dispatch events - both handlers should be triggered event_mgr.dispatch_events(); EXPECT_TRUE(triggered1); // Handler 1 should be triggered EXPECT_TRUE(triggered2); // Handler 2 should be triggered // Reset flags triggered1 = false; triggered2 = false; // Unsubscribe handler1 event_mgr.unsubscribe(handler1_id); // Queue the same event again event_mgr.queue_event( MouseClickEvent {.mouse_pos = {100, 200}, .button = MouseButton::LEFT_MOUSE} ); // Dispatch events - only handler 2 should be triggered, handler 1 should NOT event_mgr.dispatch_events(); EXPECT_FALSE(triggered1); // Handler 1 should NOT be triggered EXPECT_TRUE(triggered2); // Handler 2 should be triggered // Reset flags triggered2 = false; // Unsubscribe handler2 event_mgr.unsubscribe(handler2_id); // Queue the event again event_mgr.queue_event( MouseClickEvent {.mouse_pos = {100, 200}, .button = MouseButton::LEFT_MOUSE} ); // Dispatch events - no handler should be triggered event_mgr.dispatch_events(); EXPECT_FALSE(triggered1); // Handler 1 should NOT be triggered EXPECT_FALSE(triggered2); // Handler 2 should NOT be triggered }