#include "api/EventManager.h" #include "api/Event.h" #include "api/IKeyListener.h" #include "api/IMouseListener.h" #include #include #include using namespace std; using namespace std::chrono_literals; using namespace crepe; class EventManagerTest : public ::testing::Test { protected: void SetUp() override { // Clear any existing subscriptions or events before each test EventManager::get_instance().clear(); } void TearDown() override { // Ensure cleanup after each test EventManager::get_instance().clear(); } }; class MockKeyListener : public IKeyListener { public: MOCK_METHOD(bool, on_key_pressed, (const KeyPressEvent& event), (override)); MOCK_METHOD(bool, on_key_released, (const KeyReleaseEvent& event), (override)); }; class MockMouseListener : public IMouseListener { public: MOCK_METHOD(bool, on_mouse_clicked, (const MouseClickEvent& event), (override)); MOCK_METHOD(bool, on_mouse_pressed, (const MousePressEvent& event), (override)); MOCK_METHOD(bool, on_mouse_released, (const MouseReleaseEvent& event), (override)); MOCK_METHOD(bool, on_mouse_moved, (const MouseMoveEvent& event), (override)); }; TEST_F(EventManagerTest, EventSubscription) { EventHandler key_handler = [](const KeyPressEvent& e) { std::cout << "Key Event Triggered" << std::endl; return true; }; // Subscribe to KeyPressEvent EventManager::get_instance().subscribe(key_handler, 1); // Verify subscription (not directly verifiable; test by triggering event) EventManager::get_instance().trigger_event(KeyPressEvent{ .repeat = true, .key = Keycode::A, }, 1); EventManager::get_instance().trigger_event(KeyPressEvent{ .repeat = true, .key = Keycode::A, }, CHANNEL_ALL); } TEST_F(EventManagerTest, EventManagerTest_trigger_all_channels) { bool triggered = false; EventHandler mouse_handler = [&](const MouseClickEvent& e) { triggered = true; std::cout << "mouse handled" <(mouse_handler, CHANNEL_ALL); MouseClickEvent click_event{ .mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE }; EventManager::get_instance().trigger_event(click_event, CHANNEL_ALL); EXPECT_TRUE(triggered); } TEST_F(EventManagerTest, EventManagerTest_priority_order) { EventManager& event_manager = EventManager::get_instance(); // Vector to track call order std::vector call_order; // Handlers with different priorities EventHandler handler_priority_3 = [&](const MouseClickEvent& e) { call_order.push_back(3); return false; // Allow propagation }; EventHandler handler_priority_1 = [&](const MouseClickEvent& e) { call_order.push_back(1); return false; // Allow propagation }; EventHandler handler_priority_2 = [&](const MouseClickEvent& e) { call_order.push_back(2); return false; // Allow propagation }; // Subscribe handlers with different priorities event_manager.subscribe(handler_priority_1, CHANNEL_ALL, 1); event_manager.subscribe(handler_priority_2, CHANNEL_ALL, 2); event_manager.subscribe(handler_priority_3, CHANNEL_ALL, 3); // Trigger the event event_manager.trigger_event(MouseClickEvent{ .mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE }, CHANNEL_ALL); // Check the call order matches the expected priority order std::vector expected_order = {3, 2, 1}; EXPECT_EQ(call_order, expected_order); } TEST_F(EventManagerTest, EventManagerTest_callback_propagation) { EventManager& event_manager = EventManager::get_instance(); // 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_x, 100); EXPECT_EQ(e.mouse_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_x, 100); EXPECT_EQ(e.mouse_y, 200); EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); return false; // Allows propagation }; // Test event MouseClickEvent click_event{ .mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE }; // First Scenario: True handler has higher priority event_manager.subscribe(mouse_handler_true, CHANNEL_ALL, 1); event_manager.subscribe(mouse_handler_false, CHANNEL_ALL, 0); // Trigger event event_manager.trigger_event(click_event, 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_manager.clear(); // Second Scenario: False handler has higher priority event_manager.subscribe(mouse_handler_true, CHANNEL_ALL, 0); event_manager.subscribe(mouse_handler_false, CHANNEL_ALL, 1); // Trigger event again event_manager.trigger_event(click_event, CHANNEL_ALL); // Check that both handlers were triggered EXPECT_TRUE(triggered_true); EXPECT_TRUE(triggered_false); } TEST_F(EventManagerTest, EventManagerTest_queue_dispatch) { EventManager& event_manager = EventManager::get_instance(); bool triggered1 = false; bool triggered2 = false; int test_channel = 1; EventHandler mouse_handler1 = [&](const MouseClickEvent& e) { triggered1 = true; EXPECT_EQ(e.mouse_x, 100); EXPECT_EQ(e.mouse_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_x, 100); EXPECT_EQ(e.mouse_y, 200); EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); return false; // Allows propagation }; event_manager.subscribe(mouse_handler1); event_manager.subscribe(mouse_handler2,test_channel); event_manager.queue_event(MouseClickEvent{ .mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE }); event_manager.queue_event(MouseClickEvent{ .mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE },test_channel); event_manager.dispatch_events(); EXPECT_TRUE(triggered1); EXPECT_TRUE(triggered2); } TEST_F(EventManagerTest, EventManagerTest_dispatch_priority) { EventManager& event_manager = EventManager::get_instance(); std::vector call_order; int test_channel = 1; EventHandler mouse_handler1 = [&](const MouseClickEvent& e) { call_order.push_back(1); EXPECT_EQ(e.mouse_x, 100); EXPECT_EQ(e.mouse_y, 200); EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); return false; // Allows propagation }; EventHandler mouse_handler2 = [&](const MouseClickEvent& e) { call_order.push_back(2); EXPECT_EQ(e.mouse_x, 100); EXPECT_EQ(e.mouse_y, 200); EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); return false; // Allows propagation }; EventHandler mouse_handler3 = [&](const MouseClickEvent& e) { call_order.push_back(3); EXPECT_EQ(e.mouse_x, 100); EXPECT_EQ(e.mouse_y, 200); EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); return false; // Allows propagation }; event_manager.subscribe(mouse_handler1,CHANNEL_ALL,1); event_manager.subscribe(mouse_handler2,CHANNEL_ALL,2); event_manager.subscribe(mouse_handler2,CHANNEL_ALL,3); event_manager.queue_event(MouseClickEvent{ .mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE }); event_manager.dispatch_events(); std::vector expected_order = {3, 2, 1}; EXPECT_EQ(call_order, expected_order); } TEST_F(EventManagerTest, EventManagerTest_unsubscribe) { EventManager& event_manager = EventManager::get_instance(); // 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_x, 100); EXPECT_EQ(e.mouse_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_x, 100); EXPECT_EQ(e.mouse_y, 200); EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE); return false; // Allows propagation }; // Subscribe handlers event_manager.subscribe(mouse_handler1); event_manager.subscribe(mouse_handler2); // Queue events event_manager.queue_event(MouseClickEvent{ .mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE }); // Dispatch events - both handlers should be triggered event_manager.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_manager.unsubscribe(mouse_handler1); // Queue the same event again event_manager.queue_event(MouseClickEvent{ .mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE }); // Dispatch events - only handler 2 should be triggered, handler 1 should NOT event_manager.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_manager.unsubscribe(mouse_handler2); // Queue the event again event_manager.queue_event(MouseClickEvent{ .mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE }); // Dispatch events - no handler should be triggered event_manager.dispatch_events(); EXPECT_FALSE(triggered1); // Handler 1 should NOT be triggered EXPECT_FALSE(triggered2); // Handler 2 should NOT be triggered } // TEST_F(EventManagerTest, OnKeyPressedTest) { // MockKeyListener mock_key_listener; // EventManager& event_manager = EventManager::get_instance(); // // Create the KeyPressEvent object // KeyPressEvent key_event = KeyPressEvent{ // .key = Keycode::A, // .repeat = false // }; // // Set up the mock expectation with direct object passing // EXPECT_CALL(mock_key_listener, on_key_pressed(key_event)) // .Times(1) // Expect it to be called exactly once // .WillOnce(::testing::Return(true)); // Return value (can be true/false) // // Queue the event // event_manager.queue_event(key_event); // // Dispatch the event to trigger the mock // event_manager.dispatch_events(); // Trigger event dispatch // // The mock will ensure the on_key_pressed method is called // } // TEST_F(EventManagerTest, OnKeyReleaseTest) { // MockKeyListener mock_key_listener; // EventManager& event_manager = EventManager::get_instance(); // // Create the KeyPressEvent object // KeyReleaseEvent key_event = KeyReleaseEvent{ // .key = Keycode::A, // }; // // Set up the mock expectation with direct object passing // EXPECT_CALL(mock_key_listener, on_key_released(key_event)) // .Times(1) // Expect it to be called exactly once // .WillOnce(::testing::Return(true)); // Return value (can be true/false) // // Queue the event // event_manager.queue_event(key_event); // // Dispatch the event to trigger the mock // event_manager.dispatch_events(); // Trigger event dispatch // // The mock will ensure the on_key_pressed method is called // } // TEST_F(EventManagerTest, UnsubscribeEventsTest) { // EventManager& event_manager = EventManager::get_instance(); // KeyPressEvent key_event{ // .key = Keycode::A, // .repeat = false // }; // // Create the mock listener // MockKeyListener mock_key_listener; // // Set up the mock expectation that on_key_pressed will be called once initially // EXPECT_CALL(mock_key_listener, on_key_pressed(key_event)) // .Times(1) // Expect it to be called exactly once // .WillOnce(::testing::Return(true)); // Return value (can be true/false) // event_manager.queue_event(key_event); // event_manager.dispatch_events(); // Should trigger on_key_pressed once // // Now unsubscribe the listener // event_manager.unsubscribe(std::bind(&MockKeyListener::on_key_pressed, &mock_key_listener, std::placeholders::_1)); // // Set up the expectation that on_key_pressed will NOT be called after unsubscribing // EXPECT_CALL(mock_key_listener, on_key_pressed(key_event)) // .Times(0); // Should not be called after unsubscribe // // Queue and dispatch the event again (after unsubscribe) // event_manager.queue_event(key_event); // event_manager.dispatch_events(); // Should NOT trigger on_key_pressed after unsubscribe // } // TEST_F(EventManagerTest, OnMouseButtonPressedTest) { // MockMouseListener mock_mouse_listener; // EventManager& event_manager = EventManager::get_instance(); // // Create the MouseButtonPressEvent object // MousePressEvent mouse_event{ // .mouse_x = 100, // .mouse_y = 150, // .button = MouseButton::LEFT_MOUSE // }; // // Set up the mock expectation with direct object passing // EXPECT_CALL(mock_mouse_listener, on_mouse_pressed(mouse_event)) // .Times(1) // Expect it to be called exactly once // .WillOnce(::testing::Return(true)); // Return value (can be true/false) // // Queue the event // event_manager.queue_event(mouse_event); // // Dispatch the event to trigger the mock // event_manager.dispatch_events(); // Should trigger on_mouse_button_pressed once // } // TEST_F(EventManagerTest, UnsubscribeMouseEventsTest) { // EventManager& event_manager = EventManager::get_instance(); // MousePressEvent mouse_event{ // .mouse_x = 100, // .mouse_y = 150, // .button = MouseButton::LEFT_MOUSE // }; // // Create the mock listener // MockMouseListener mock_mouse_listener; // // Set up the mock expectation that on_mouse_button_pressed will be called once initially // EXPECT_CALL(mock_mouse_listener, on_mouse_pressed(mouse_event)) // .Times(1) // Expect it to be called exactly once // .WillOnce(::testing::Return(true)); // Return value (can be true/false) // // Queue and dispatch the event (should trigger on_mouse_button_pressed) // event_manager.queue_event(mouse_event); // event_manager.dispatch_events(); // Should trigger on_mouse_button_pressed once // // Now unsubscribe the listener // event_manager.unsubscribe(std::bind(&MockMouseListener::on_mouse_pressed, &mock_mouse_listener, std::placeholders::_1)); // // Set up the expectation that on_mouse_button_pressed will NOT be called after unsubscribing // EXPECT_CALL(mock_mouse_listener, on_mouse_pressed(mouse_event)) // .Times(0); // Should not be called after unsubscribe // // Queue and dispatch the event again (after unsubscribe) // event_manager.queue_event(mouse_event); // event_manager.dispatch_events(); // Should NOT trigger on_mouse_button_pressed after unsubscribe // }