def test_remove_non_existing_listeners(self):
        dispatcher = EventDispatcher()

        key = dispatcher.add_listener(TestEvent, 0, lambda event: None)

        # Valid key on invalid event type.
        self.assertRaises(KeyError, dispatcher.remove_listener, OtherEvent, key)

        # Invalid key on valid event type.
        self.assertRaises(KeyError, dispatcher.remove_listener, TestEvent, key._replace(priority=99))

        # Really remove listener.
        dispatcher.remove_listener(TestEvent, key)

        # Double removal with valid key on valid event type.
        self.assertRaises(KeyError, dispatcher.remove_listener, TestEvent, key)
    def test_manage_listeners(self):
        dispatcher = EventDispatcher()

        listeners = list(dispatcher.get_listeners(TestEvent))
        self.assertEqual(len(listeners), 0)

        test_callback_prio_0_cb_0 = Mock()
        test_callback_prio_0_cb_1 = Mock()
        test_callback_prio_1_cb_0 = Mock()
        other_callback_prio_2_cb_0 = Mock()

        # Register callbacks, first priority 1 ...
        dispatcher.add_listener(TestEvent, 1, test_callback_prio_1_cb_0)

        # ... aftwerwards priority 0 ...
        key_prio_0_cb_0 = dispatcher.add_listener(TestEvent, 0, test_callback_prio_0_cb_0)
        dispatcher.add_listener(TestEvent, 0, test_callback_prio_0_cb_1)

        # ... and finally priority 2 for another event.
        dispatcher.add_listener(OtherEvent, 2, other_callback_prio_2_cb_0)

        # Collect callbacks from listeners list.
        actual_handlers = [(key.priority, handler.callback) for key, handler in dispatcher.get_listeners(TestEvent)]
        expected_handlers = [
            (0, test_callback_prio_0_cb_0),
            (0, test_callback_prio_0_cb_1),
            (1, test_callback_prio_1_cb_0),
        ]

        self.assertEqual(expected_handlers, actual_handlers)

        # Remove one listener.
        dispatcher.remove_listener(TestEvent, key_prio_0_cb_0)

        # Collect callbacks from listeners list.
        actual_handlers = [(key.priority, handler.callback) for key, handler in dispatcher.get_listeners(TestEvent)]
        expected_handlers = [
            (0, test_callback_prio_0_cb_1),
            (1, test_callback_prio_1_cb_0),
        ]

        self.assertEqual(expected_handlers, actual_handlers)
    def test_dispatch_event(self):
        dispatcher = EventDispatcher()

        test_callback_prio_0_cb_0 = Mock()
        test_callback_prio_0_cb_1 = Mock()
        test_callback_prio_1_cb_0 = Mock()
        other_callback_prio_2_cb_0 = Mock()

        dispatcher.add_listener(TestEvent, 0, test_callback_prio_0_cb_0)
        key_prio_0_cb_1 = dispatcher.add_listener(TestEvent, 0, test_callback_prio_0_cb_1)
        dispatcher.add_listener(TestEvent, 1, test_callback_prio_1_cb_0)
        dispatcher.add_listener(OtherEvent, 2, other_callback_prio_2_cb_0)

        event = TestEvent()
        d = dispatcher.dispatch(event)
        self.assertTrue(d.called)

        test_callback_prio_0_cb_0.assert_called_once_with(event)
        test_callback_prio_0_cb_1.assert_called_once_with(event)
        test_callback_prio_1_cb_0.assert_called_once_with(event)
        self.assertEqual(other_callback_prio_2_cb_0.call_count, 0)

        dispatcher.remove_listener(TestEvent, key_prio_0_cb_1)

        test_callback_prio_0_cb_0.reset_mock()
        test_callback_prio_0_cb_1.reset_mock()
        test_callback_prio_1_cb_0.reset_mock()
        other_callback_prio_2_cb_0.reset_mock()

        event = TestEvent()
        d = dispatcher.dispatch(event)
        self.assertTrue(d.called)

        test_callback_prio_0_cb_0.assert_called_once_with(event)
        self.assertEqual(test_callback_prio_0_cb_1.call_count, 0)
        test_callback_prio_1_cb_0.assert_called_once_with(event)
        self.assertEqual(other_callback_prio_2_cb_0.call_count, 0)