예제 #1
0
class TestBus(unittest.TestCase):
    def callback(self, bus, argument):
        self.called_bus = bus
        self.has_run = True
        self.argument = argument
        self.callback_count = self.callback_count + 1

    def setUp(self):
        self.bus = Bus()
        self.reset_test()

    def reset_test(self):
        self.has_run = False
        self.called_bus = None
        self.argument = ""
        self.callback_count = 0

    def test_can_haz_bus(self):
        assert self.bus

    def test_has_no_subscriptions(self):
        assert not self.bus.subscriptions

    def test_subscribe_is_chainable(self):
        bus = self.bus.subscribe('test.key', self.callback)
        assert bus == self.bus

    def test_can_subscribe_to_event(self):
        self.bus.subscribe('test.key', self.callback)
        expected = [{ 'key': 'test.key', 'callback': self.callback }]

        assert 'test.key' in self.bus.subscriptions
        assert self.bus.subscriptions['test.key']
        assert expected == self.bus.subscriptions['test.key']

    def test_subscribing_twice_with_same_subject_and_callback_ignores_second_call(self):
        self.bus.subscribe('test.key', self.callback).subscribe('test.key', self.callback)

        assert len(self.bus.subscriptions['test.key']) == 1, len(self.bus.subscriptions['test.key'])

    def test_subscribing_by_force(self):
        self.bus.subscribe('test.key', self.callback).subscribe('test.key', self.callback, force=True)

        assert len(self.bus.subscriptions['test.key']) == 2, len(self.bus.subscriptions['test.key'])

    def test_subscribe_to_all_events(self):
        self.bus.subscribe('*', self.callback)

        self.bus.publish('test.key1')
        assert self.has_run and self.argument == 'test.key1'

        self.has_run = False
        self.bus.publish('test.key2')
        assert self.has_run and self.argument == 'test.key2'


    def test_unsubscribe_is_chainable(self):
        bus = self.bus.unsubscribe('test.key', self.callback)
        assert bus == self.bus

    def test_unsubscribe_to_invalid_subject_does_nothing(self):
        self.bus.unsubscribe('test.key', self.callback)

        assert 'test.key' not in self.bus.subscriptions

    def test_unsubscribe_to_invalid_callback_does_nothing(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.unsubscribe('test.key', lambda obj: obj)

        assert len(self.bus.subscriptions['test.key']) == 1, len(self.bus.subscriptions['test.key'])

    def test_can_unsubscribe_to_event(self):
        self.bus.subscribe('test.key', self.callback).unsubscribe('test.key', self.callback)

        assert len(self.bus.subscriptions['test.key']) == 0, len(self.bus.subscriptions['test.key'])

    def test_unsubscribe_all_does_nothing_for_nonexistent_key(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.unsubscribe_all('other.key')

        assert len(self.bus.subscriptions['test.key']) == 1, len(self.bus.subscriptions['test.key'])

    def test_unsubscribe_all_is_chainable(self):
        bus = self.bus.unsubscribe_all('test.key')
        assert bus == self.bus

    def test_unsubscribe_all(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.subscribe('test.key', lambda obj: obj)

        self.bus.unsubscribe_all('test.key')

        assert len(self.bus.subscriptions['test.key']) == 0, len(self.bus.subscriptions['test.key'])

    def test_has_subscription(self):
        self.bus.subscribe('test.key', self.callback)

        assert self.bus.has_subscription('test.key', self.callback)

        self.bus.unsubscribe('test.key', self.callback)

        assert not self.bus.has_subscription('test.key', self.callback)

    def test_does_not_have_subscription_for_invalid_key(self):
        assert not self.bus.has_subscription('test.key', self.callback)

    def test_does_not_have_subscription_for_invalid_calback(self):
        self.bus.subscribe('test.key', self.callback)

        assert not self.bus.has_subscription('test.key', lambda obj: obj)

    def test_has_any_subscriptions_for_invalid_key(self):
        assert not self.bus.has_any_subscriptions('test.key')

    def test_has_any_subscriptions(self):
        self.bus.subscribe('test.key', self.callback)

        assert self.bus.has_any_subscriptions('test.key')

        self.bus.unsubscribe('test.key', self.callback)

        assert not self.bus.has_any_subscriptions('test.key')

    def test_can_publish(self):
        self.bus.subscribe('test.key', self.callback)

        self.bus.publish('test.key', argument="something")

        assert self.has_run
        assert self.argument == "something"
        assert self.called_bus == self.bus

    def test_can_publish_with_noone_listening(self):
        self.bus.publish('test.key', something="whatever")

    def test_publish_is_chainable(self):
        bus = self.bus.publish('test.key', something="whatever")
        assert bus == self.bus

    def test_subscribing_to_different_keys(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.subscribe('test.key2', self.callback)
        self.bus.subscribe('test.key3', self.callback)

        assert 'test.key' in self.bus.subscriptions
        assert 'test.key2' in self.bus.subscriptions
        assert 'test.key3' in self.bus.subscriptions

        assert self.bus.subscriptions['test.key']
        assert self.bus.subscriptions['test.key2']
        assert self.bus.subscriptions['test.key3']

    def test_can_reset_bus(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.subscribe('test.key2', self.callback)
        self.bus.subscribe('test.key3', self.callback)

        self.bus.reset()

        assert 'test.key' not in self.bus.subscriptions
        assert 'test.key2' not in self.bus.subscriptions
        assert 'test.key3' not in self.bus.subscriptions

    def test_only_one_instance_of_the_bus(self):
        bus_a = Bus.get_or_create('bus_a')
        bus_b = Bus.get_bus('bus_a')
        bus_c = Bus.get_or_create('bus_c')
        bus_d = Bus()

        assert bus_a is bus_b
        assert bus_a is not bus_c
        assert bus_d is not bus_a

    def test_get_or_create_only_once(self):
        bus_a = Bus.get_or_create('bus_a')
        bus_b = Bus.get_or_create('bus_a')

        assert bus_a is bus_b

    def test_delete_bus_instances(self):
        bus_x = Bus.get_or_create('bus_x')

        assert bus_x in Bus._instances.values()

        Bus.delete_bus('bus_x')

        assert bus_x not in Bus._instances.values()

        with self.assertRaises(KeyError):
            Bus.delete_bus('bus_x')

    def test_bus_is_not_specific(self):
        bus_y = Bus()
        bus_z = Bus.get_or_create('bus_z')

        assert bus_y is not bus_z

    def test_get_bus_name_none(self):
        bus_name = Bus.get_bus_name(self.bus)
        assert bus_name is None

    def test_get_bus_name_string(self):
        bus_x = Bus('bus_x')
        assert Bus.get_bus_name(bus_x) == 'bus_x'

    def test_subkey_subscriptions_simple(self):
        self.bus.subscribe('level1a.level2a', self.callback)

        # we have subscribed to a parent level thus we should receive this publish
        self.bus.publish('level1a.level2a.level3a', argument="something")

        assert self.has_run
        assert self.argument == "something"
        assert self.called_bus == self.bus
        assert self.callback_count == 1

    def test_subkey_subscriptions_no_start_match(self):
        # make sure that we only get publishes if the start of the key is an exact match
        self.reset_test()

        self.bus.subscribe('level1a.level2a', self.callback)
        self.bus.publish('blah.level1a.level2a.level3a', argument="something")

        assert not self.has_run
        assert self.argument == ""
        assert self.called_bus == None
        assert self.callback_count == 0

    def test_subkey_subscriptions_complex(self):
        self.reset_test()
        self.bus.subscribe('level1a.level2a', self.callback)
        self.bus.subscribe('level1a.level2a.level3a', self.callback)
        self.bus.subscribe('level1a.level2a.level3b', self.callback)

        # we have subscribed to a parent level thus we should receive this publish
        self.bus.publish('level1a.level2a.level3a', argument="something")

        assert self.has_run
        assert self.argument == "something"
        assert self.called_bus == self.bus
        assert self.callback_count == 2

        # following test should get callback for level1a.level2a and level1a.level2a.level3a
        self.reset_test()
        self.bus.publish('level1a.level2a.level3b', argument="something2")

        assert self.has_run
        assert self.argument == "something2"
        assert self.called_bus == self.bus
        assert self.callback_count == 2

        self.reset_test()
        self.bus.subscribe('level1a', self.callback)
        self.bus.publish('level1a.level2b', argument="something2")

        assert self.has_run
        assert self.argument == "something2"
        assert self.called_bus == self.bus
        assert self.callback_count == 1

    def test_messages_across_threads_thread_subscribe1(self):
        # in this example we create a thread and then from outside that thread we create a subscription to one of the
        # threads functions
        bus_a = Bus.get_or_create('bus_a')
        new_thread = ThreadClass1()
        new_thread.start()

        bus_a.subscribe('level1a.level2a', new_thread.message_callback)

        # we have subscribed to a parent level thus we should receive this publish
        bus_a.publish('level1a.level2a.level3a', argument="hello")

        #assert self.has_run
        assert new_thread.get_latest_argument() == "hello"
        assert new_thread.get_bus() == bus_a
        assert new_thread.get_latest_counter() == 1

        new_thread.stop()

    def test_messages_across_threads_thread_subscribe2(self):
        # in this example we create a thread and then from outside that thread we create a subscription to one of the
        # threads functions
        bus_a = Bus.get_or_create('bus_a')
        new_thread = ThreadClass2()
        new_thread.start()

        while not new_thread.running():
            time.sleep(0.05)

        # we have subscribed to a parent level thus we should receive this publish
        bus_a.publish('level1a.level2a.level3a', argument="hello_there")

        new_thread.stop()

        #assert self.has_run
        assert new_thread.get_latest_argument() == "hello_there"
        assert new_thread.get_bus() == bus_a
        assert new_thread.get_latest_counter() == 1

    def test_messages_across_threads_thread_publish(self):
        # in this example we create a thread and then from inside that thread we perform a publish which eventuates
        # in this main thread
        self.reset_test()
        bus_a = Bus.get_or_create('bus_a')
        bus_a.subscribe('level1a.level2a', self.callback)

        new_thread = ThreadClass3()
        new_thread.start()

        while not new_thread.running():
            time.sleep(0.05)
            
        new_thread.stop()

        assert self.has_run
        assert self.argument == "hello from thread"
        assert self.called_bus == bus_a
        assert self.callback_count == 1
예제 #2
0
class TestBus(unittest.TestCase):
    def callback(self, bus, argument):
        self.called_bus = bus
        self.has_run = True
        self.argument = argument

    def setUp(self):
        self.bus = Bus()
        self.has_run = False
        self.called_bus = None

    def test_can_haz_bus(self):
        assert self.bus

    def test_has_no_subscriptions(self):
        assert not self.bus.subscriptions

    def test_subscribe_is_chainable(self):
        bus = self.bus.subscribe('test.key', self.callback)
        assert bus == self.bus

    def test_can_subscribe_to_event(self):
        self.bus.subscribe('test.key', self.callback)
        expected = [{'key': 'test.key', 'callback': self.callback}]

        assert 'test.key' in self.bus.subscriptions
        assert self.bus.subscriptions['test.key']
        assert expected == self.bus.subscriptions['test.key']

    def test_subscribing_twice_with_same_subject_and_callback_ignores_second_call(
            self):
        self.bus.subscribe('test.key',
                           self.callback).subscribe('test.key', self.callback)

        assert len(self.bus.subscriptions['test.key']) == 1, len(
            self.bus.subscriptions['test.key'])

    def test_subscribing_by_force(self):
        self.bus.subscribe('test.key', self.callback).subscribe('test.key',
                                                                self.callback,
                                                                force=True)

        assert len(self.bus.subscriptions['test.key']) == 2, len(
            self.bus.subscriptions['test.key'])

    def test_subscribe_to_all_events(self):
        self.bus.subscribe('*', self.callback)

        self.bus.publish('test.key1')
        assert self.has_run and self.argument == 'test.key1'

        self.has_run = False
        self.bus.publish('test.key2')
        assert self.has_run and self.argument == 'test.key2'

    def test_unsubscribe_is_chainable(self):
        bus = self.bus.unsubscribe('test.key', self.callback)
        assert bus == self.bus

    def test_unsubscribe_to_invalid_subject_does_nothing(self):
        self.bus.unsubscribe('test.key', self.callback)

        assert 'test.key' not in self.bus.subscriptions

    def test_unsubscribe_to_invalid_callback_does_nothing(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.unsubscribe('test.key', lambda obj: obj)

        assert len(self.bus.subscriptions['test.key']) == 1, len(
            self.bus.subscriptions['test.key'])

    def test_can_unsubscribe_to_event(self):
        self.bus.subscribe('test.key',
                           self.callback).unsubscribe('test.key',
                                                      self.callback)

        assert len(self.bus.subscriptions['test.key']) == 0, len(
            self.bus.subscriptions['test.key'])

    def test_unsubscribe_all_does_nothing_for_nonexistent_key(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.unsubscribe_all('other.key')

        assert len(self.bus.subscriptions['test.key']) == 1, len(
            self.bus.subscriptions['test.key'])

    def test_unsubscribe_all_is_chainable(self):
        bus = self.bus.unsubscribe_all('test.key')
        assert bus == self.bus

    def test_unsubscribe_all(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.subscribe('test.key', lambda obj: obj)

        self.bus.unsubscribe_all('test.key')

        assert len(self.bus.subscriptions['test.key']) == 0, len(
            self.bus.subscriptions['test.key'])

    def test_has_subscription(self):
        self.bus.subscribe('test.key', self.callback)

        assert self.bus.has_subscription('test.key', self.callback)

        self.bus.unsubscribe('test.key', self.callback)

        assert not self.bus.has_subscription('test.key', self.callback)

    def test_does_not_have_subscription_for_invalid_key(self):
        assert not self.bus.has_subscription('test.key', self.callback)

    def test_does_not_have_subscription_for_invalid_calback(self):
        self.bus.subscribe('test.key', self.callback)

        assert not self.bus.has_subscription('test.key', lambda obj: obj)

    def test_has_any_subscriptions_for_invalid_key(self):
        assert not self.bus.has_any_subscriptions('test.key')

    def test_has_any_subscriptions(self):
        self.bus.subscribe('test.key', self.callback)

        assert self.bus.has_any_subscriptions('test.key')

        self.bus.unsubscribe('test.key', self.callback)

        assert not self.bus.has_any_subscriptions('test.key')

    def test_can_publish(self):
        self.bus.subscribe('test.key', self.callback)

        self.bus.publish('test.key', argument="something")

        assert self.has_run
        assert self.argument == "something"
        assert self.called_bus == self.bus

    def test_can_publish_with_noone_listening(self):
        self.bus.publish('test.key', something="whatever")

    def test_publish_is_chainable(self):
        bus = self.bus.publish('test.key', something="whatever")
        assert bus == self.bus

    def test_subscribing_to_different_keys(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.subscribe('test.key2', self.callback)
        self.bus.subscribe('test.key3', self.callback)

        assert 'test.key' in self.bus.subscriptions
        assert 'test.key2' in self.bus.subscriptions
        assert 'test.key3' in self.bus.subscriptions

        assert self.bus.subscriptions['test.key']
        assert self.bus.subscriptions['test.key2']
        assert self.bus.subscriptions['test.key3']

    def test_can_reset_bus(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.subscribe('test.key2', self.callback)
        self.bus.subscribe('test.key3', self.callback)

        self.bus.reset()

        assert 'test.key' not in self.bus.subscriptions
        assert 'test.key2' not in self.bus.subscriptions
        assert 'test.key3' not in self.bus.subscriptions

    def test_only_one_instance_of_the_bus(self):
        bus_a = Bus.get_or_create('bus_a')
        bus_b = Bus.get_bus('bus_a')
        bus_c = Bus.get_or_create('bus_c')
        bus_d = Bus()

        assert bus_a is bus_b
        assert bus_a is not bus_c
        assert bus_d is not bus_a

    def test_get_or_create_only_once(self):
        bus_a = Bus.get_or_create('bus_a')
        bus_b = Bus.get_or_create('bus_a')

        assert bus_a is bus_b

    def test_delete_bus_instances(self):
        bus_x = Bus.get_or_create('bus_x')

        assert bus_x in Bus._instances.values()

        Bus.delete_bus('bus_x')

        assert bus_x not in Bus._instances.values()

        with self.assertRaises(KeyError):
            Bus.delete_bus('bus_x')

    def test_bus_is_not_specific(self):
        bus_y = Bus()
        bus_z = Bus.get_or_create('bus_z')

        assert bus_y is not bus_z

    def test_get_bus_name_none(self):
        bus_name = Bus.get_bus_name(self.bus)
        assert bus_name is None

    def test_get_bus_name_string(self):
        bus_x = Bus('bus_x')
        assert Bus.get_bus_name(bus_x) == 'bus_x'
예제 #3
0
class TestBus(unittest.TestCase):
    def callback(self, bus, argument):
        self.called_bus = bus
        self.has_run = True
        self.argument = argument

    def setUp(self):
        self.bus = Bus()
        self.has_run = False
        self.called_bus = None

    def test_can_haz_bus(self):
        assert self.bus

    def test_has_no_subscriptions(self):
        assert not self.bus.subscriptions

    def test_subscribe_is_chainable(self):
        bus = self.bus.subscribe('test.key', self.callback)
        assert bus == self.bus

    def test_can_subscribe_to_event(self):
        self.bus.subscribe('test.key', self.callback)
        expected = [{ 'key': 'test.key', 'callback': self.callback }]

        assert 'test.key' in self.bus.subscriptions
        assert self.bus.subscriptions['test.key']
        assert expected == self.bus.subscriptions['test.key']

    def test_subscribing_twice_with_same_subject_and_callback_ignores_second_call(self):
        self.bus.subscribe('test.key', self.callback).subscribe('test.key', self.callback)

        assert len(self.bus.subscriptions['test.key']) == 1, len(self.bus.subscriptions['test.key'])

    def test_subscribing_by_force(self):
        self.bus.subscribe('test.key', self.callback).subscribe('test.key', self.callback, force=True)

        assert len(self.bus.subscriptions['test.key']) == 2, len(self.bus.subscriptions['test.key'])

    def test_unsubscribe_is_chainable(self):
        bus = self.bus.unsubscribe('test.key', self.callback)
        assert bus == self.bus

    def test_unsubscribe_to_invalid_subject_does_nothing(self):
        self.bus.unsubscribe('test.key', self.callback)

        assert 'test.key' not in self.bus.subscriptions

    def test_unsubscribe_to_invalid_callback_does_nothing(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.unsubscribe('test.key', lambda obj: obj)

        assert len(self.bus.subscriptions['test.key']) == 1, len(self.bus.subscriptions['test.key'])

    def test_can_unsubscribe_to_event(self):
        self.bus.subscribe('test.key', self.callback).unsubscribe('test.key', self.callback)

        assert len(self.bus.subscriptions['test.key']) == 0, len(self.bus.subscriptions['test.key'])

    def test_unsubscribe_all_does_nothing_for_nonexistent_key(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.unsubscribe_all('other.key')

        assert len(self.bus.subscriptions['test.key']) == 1, len(self.bus.subscriptions['test.key'])

    def test_unsubscribe_all_is_chainable(self):
        bus = self.bus.unsubscribe_all('test.key')
        assert bus == self.bus

    def test_unsubscribe_all(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.subscribe('test.key', lambda obj: obj)

        self.bus.unsubscribe_all('test.key')

        assert len(self.bus.subscriptions['test.key']) == 0, len(self.bus.subscriptions['test.key'])

    def test_has_subscription(self):
        self.bus.subscribe('test.key', self.callback)

        assert self.bus.has_subscription('test.key', self.callback)

        self.bus.unsubscribe('test.key', self.callback)

        assert not self.bus.has_subscription('test.key', self.callback)

    def test_does_not_have_subscription_for_invalid_key(self):
        assert not self.bus.has_subscription('test.key', self.callback)

    def test_does_not_have_subscription_for_invalid_calback(self):
        self.bus.subscribe('test.key', self.callback)

        assert not self.bus.has_subscription('test.key', lambda obj: obj)

    def test_has_any_subscriptions_for_invalid_key(self):
        assert not self.bus.has_any_subscriptions('test.key')

    def test_has_any_subscriptions(self):
        self.bus.subscribe('test.key', self.callback)

        assert self.bus.has_any_subscriptions('test.key')

        self.bus.unsubscribe('test.key', self.callback)

        assert not self.bus.has_any_subscriptions('test.key')

    def test_can_publish(self):
        self.bus.subscribe('test.key', self.callback)

        self.bus.publish('test.key', argument="something")

        assert self.has_run
        assert self.argument == "something"
        assert self.called_bus == self.bus

    def test_can_publish_with_noone_listening(self):
        self.bus.publish('test.key', something="whatever")

    def test_publish_is_chainable(self):
        bus = self.bus.publish('test.key', something="whatever")
        assert bus == self.bus

    def test_subscribing_to_different_keys(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.subscribe('test.key2', self.callback)
        self.bus.subscribe('test.key3', self.callback)

        assert 'test.key' in self.bus.subscriptions
        assert 'test.key2' in self.bus.subscriptions
        assert 'test.key3' in self.bus.subscriptions

        assert self.bus.subscriptions['test.key']
        assert self.bus.subscriptions['test.key2']
        assert self.bus.subscriptions['test.key3']

    def test_can_reset_bus(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.subscribe('test.key2', self.callback)
        self.bus.subscribe('test.key3', self.callback)

        self.bus.reset()

        assert 'test.key' not in self.bus.subscriptions
        assert 'test.key2' not in self.bus.subscriptions
        assert 'test.key3' not in self.bus.subscriptions
예제 #4
0
class TestBus(unittest.TestCase):
    def callback(self, bus, argument):
        self.called_bus = bus
        self.has_run = True
        self.argument = argument

    def setUp(self):
        self.bus = Bus()
        self.has_run = False
        self.called_bus = None

    def test_can_haz_bus(self):
        assert self.bus

    def test_has_no_subscriptions(self):
        assert not self.bus.subscriptions

    def test_subscribe_is_chainable(self):
        bus = self.bus.subscribe('test.key', self.callback)
        assert bus == self.bus

    def test_can_subscribe_to_event(self):
        self.bus.subscribe('test.key', self.callback)
        expected = [{'key': 'test.key', 'callback': self.callback}]

        assert 'test.key' in self.bus.subscriptions
        assert self.bus.subscriptions['test.key']
        assert expected == self.bus.subscriptions['test.key']

    def test_subscribing_twice_with_same_subject_and_callback_ignores_second_call(
            self):
        self.bus.subscribe('test.key',
                           self.callback).subscribe('test.key', self.callback)

        assert len(self.bus.subscriptions['test.key']) == 1, len(
            self.bus.subscriptions['test.key'])

    def test_subscribing_by_force(self):
        self.bus.subscribe('test.key', self.callback).subscribe('test.key',
                                                                self.callback,
                                                                force=True)

        assert len(self.bus.subscriptions['test.key']) == 2, len(
            self.bus.subscriptions['test.key'])

    def test_unsubscribe_is_chainable(self):
        bus = self.bus.unsubscribe('test.key', self.callback)
        assert bus == self.bus

    def test_unsubscribe_to_invalid_subject_does_nothing(self):
        self.bus.unsubscribe('test.key', self.callback)

        assert 'test.key' not in self.bus.subscriptions

    def test_unsubscribe_to_invalid_callback_does_nothing(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.unsubscribe('test.key', lambda obj: obj)

        assert len(self.bus.subscriptions['test.key']) == 1, len(
            self.bus.subscriptions['test.key'])

    def test_can_unsubscribe_to_event(self):
        self.bus.subscribe('test.key',
                           self.callback).unsubscribe('test.key',
                                                      self.callback)

        assert len(self.bus.subscriptions['test.key']) == 0, len(
            self.bus.subscriptions['test.key'])

    def test_unsubscribe_all_does_nothing_for_nonexistent_key(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.unsubscribe_all('other.key')

        assert len(self.bus.subscriptions['test.key']) == 1, len(
            self.bus.subscriptions['test.key'])

    def test_unsubscribe_all_is_chainable(self):
        bus = self.bus.unsubscribe_all('test.key')
        assert bus == self.bus

    def test_unsubscribe_all(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.subscribe('test.key', lambda obj: obj)

        self.bus.unsubscribe_all('test.key')

        assert len(self.bus.subscriptions['test.key']) == 0, len(
            self.bus.subscriptions['test.key'])

    def test_has_subscription(self):
        self.bus.subscribe('test.key', self.callback)

        assert self.bus.has_subscription('test.key', self.callback)

        self.bus.unsubscribe('test.key', self.callback)

        assert not self.bus.has_subscription('test.key', self.callback)

    def test_does_not_have_subscription_for_invalid_key(self):
        assert not self.bus.has_subscription('test.key', self.callback)

    def test_does_not_have_subscription_for_invalid_calback(self):
        self.bus.subscribe('test.key', self.callback)

        assert not self.bus.has_subscription('test.key', lambda obj: obj)

    def test_has_any_subscriptions_for_invalid_key(self):
        assert not self.bus.has_any_subscriptions('test.key')

    def test_has_any_subscriptions(self):
        self.bus.subscribe('test.key', self.callback)

        assert self.bus.has_any_subscriptions('test.key')

        self.bus.unsubscribe('test.key', self.callback)

        assert not self.bus.has_any_subscriptions('test.key')

    def test_can_publish(self):
        self.bus.subscribe('test.key', self.callback)

        self.bus.publish('test.key', argument="something")

        assert self.has_run
        assert self.argument == "something"
        assert self.called_bus == self.bus

    def test_can_publish_with_noone_listening(self):
        self.bus.publish('test.key', something="whatever")

    def test_publish_is_chainable(self):
        bus = self.bus.publish('test.key', something="whatever")
        assert bus == self.bus

    def test_subscribing_to_different_keys(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.subscribe('test.key2', self.callback)
        self.bus.subscribe('test.key3', self.callback)

        assert 'test.key' in self.bus.subscriptions
        assert 'test.key2' in self.bus.subscriptions
        assert 'test.key3' in self.bus.subscriptions

        assert self.bus.subscriptions['test.key']
        assert self.bus.subscriptions['test.key2']
        assert self.bus.subscriptions['test.key3']

    def test_can_reset_bus(self):
        self.bus.subscribe('test.key', self.callback)
        self.bus.subscribe('test.key2', self.callback)
        self.bus.subscribe('test.key3', self.callback)

        self.bus.reset()

        assert 'test.key' not in self.bus.subscriptions
        assert 'test.key2' not in self.bus.subscriptions
        assert 'test.key3' not in self.bus.subscriptions