def test_timed_signal_with_eventbus(): time = datetime.now() # Create a signal a = TimedSignal('<1,2>', time) b = Bus() def callback(bus, signal=None): eq_(signal.time, time, "Expected same time value!") eq_(signal.neuron, '<1,2>', "Expected same neuron index!") b.subscribe('Fired', callback) # Fire the signal b.publish('Fired', signal=a)
class Limiter(object): def __init__(self, limiter_miss_timeout_ms=None): self.bus = Bus() self.limiter_miss_timeout_ms = limiter_miss_timeout_ms if self.limiter_miss_timeout_ms is None: self.limiter_miss_timeout_ms = 500 def handle_callbacks(self, callback): def handle(bus, *args, **kw): callback(*args, **kw) return handle def subscribe_to_lock_miss(self, callback): self.bus.subscribe('limiter.miss', self.handle_callbacks(callback)) def publish_lock_miss(self, url): self.bus.publish('limiter.miss', url)
class EventBus: def __init__(self): #TODO: convert to singleton global log self._bus = Bus() self._channel = 'default/' self._log_channel_key = 'log/' self._sensor_channel_key = 'sensor/' self._event_channel_key = 'event/' self._command_channel_key = 'command/' self._type = 'EventBus' self._capabilities = {'get_nodes':self.register_sensorbus, 'get_eventbus_nodes':self.register_sensorbus, 'get_commandbus_nodes':self.register_sensorbus, 'get_logbus_nodes':self.register_sensorbus, } self._container = {} #log.info('EventBus Initalized') def get_nodes(self): return def register_sensorbus(self, callback): self._bus.subscribe(self._sensor_channel_key, callback) log.debug(str(callback) + ' registered to sensor bus.' ) # todo: log subs def register_eventbus(self, callback): self._bus.subscribe(self._event_channel_key, callback) log.debug(str(callback) + ' registered to event bus.') # todo: log subs def register_logbus(self, callback): self._bus.subscribe(self._log_channel_key, callback) log.debug(str(callback) + ' registered to error bus.') # todo: log subs def register_commandbus(self, callback): self._bus.subscribe(self._command_channel_key, callback) log.debug(str(callback) + ' registered to command bus.') # todo: log subs def unregister(self, channel, callback): # todo: log unsub self._bus.unsubscribe(channel, callback) log.debug('%s unregistered from %s') % (str(callback), channel) def publish(self, data): self._bus.publish(self._sensor_channel_key, data) def publish_sensor(self, data): self._bus.publish(self._sensor_channel_key, data) def publish_log(self, data): self._bus.publish(self._log_channel_key, data) def publish_event(self, data): self._bus.publish(self._event_channel_key, data) def publish_command(self, data): self._bus.publish(self._command_channel_key, data)
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
proc = pickle.load(file) return proc # def eventHandler(self, msg): # self.updateLamportClock() # # # if msg.sourceID == self.uid or msg.sourceID == self.uid: # if msg.sourceID == self.uid: # localEvent(msg) # else: # remoteEvent(msg) class TestController(unittest.TestCase): def setUp(self): self.process1 = process(1, 2) self.process2 = process(2,2) pass def testJava(self): pass def busTester(self, text): print(str(text)) if __name__ == "__main__": bus = Bus() bus.subscribe("tester",busTester) bus.publish("tester",text="Hi there!")
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
class SpikingNeuron(object): def __init__(self, index, network_bus, efficacy_pause=2, efficacy_duration=4, arp=2, threshold=1.5): """ A :class:`SpikingNeuron` object is created with the bus for the current network as an argument. It communicates with the network solely through this bus. Neurons have their own event buses to which they broadcast their firings. To attach neurons to this bus, simply call the attach method on the pre-synaptic neuron passing the post-synaptic neuron as an argument. The firing of a neuron is contained within a :class:'TimedSignal' object. """ self._network_bus = network_bus self._firing_bus = Bus() self._index = index # Internal plumbing self._activation_signals = [] self._firing_times = [] # Neuron parameters self._efficacy_pause = efficacy_pause self._efficacy_duration = efficacy_duration self._arp = arp self._threshold = threshold def get_index(self): """ Returns the index for this neuron. This should be an immutable property. As such, only the get method is implemented.""" return self._index index = property(get_index) def _fire(self): """ Private method. Used to create a signal and to broadcast it to the private event bus of this neuron. """ time = datetime.now() signal = TimedSignal(self.index, time) # Append the current firing time to the _firing_times self._firing_times.append(time) # Broadcast the signal self._firing_bus.publish(NEURON_FIRE_EVENT_KEY, signal) def attach(self, post_synaptic_neuron): """ Attaches :obj:`post_synaptic_neuron` as a synaptic connection to which it will send signals. This is managed by simply adding :obj:`post_synaptic_neuron`.activate() to the private event bus for this neuron. """ self._firing_bus.subscribe(NEURON_FIRE_EVENT_KEY, post_synaptic_neuron.activate) return def activate(self, bus, signal=None): if signal is not None: # Add this activation to the _activation_signals list self._activation_signals.append(signal) def compute(self): """ Computes the activation level at this time. Considers the signals in :obj:`self._activation_signals`, reverse chronologically. Only considers those signals which were fired less than :obj:`self._efficacy_duration` ago. Beyond this value, all activation levels due to those signals should be zero. Additional notes: This implementation is based on a piecewise constant model as defined in Maass, 1995 | Analog Computations on Networks of Spiking Neurons Type A """ level = 0 current_time = datetime.now() for signal in reversed(self._activation_signals): delta = current_time - signal.time delta = delta.seconds * 1000 + delta.microseconds * 0.001 # Adjust to miliseconds if delta > self._efficacy_duration: # If the signal was fired more than self._efficacy_duration ms # ago, it and all the signals before it will have no effect on # the computation. break if delta < self._efficacy_duration and \ delta > self._efficacy_pause: # Only consider if the signal has started having effects at # all. level += NEURON_ACTIVATION_LEVEL return level def touch(self): """ Checks whether the current value of the activation is higher than the threshold. If so, and the current time is more than the absolute refractory period since the last firing, neuron sends out a synapse. """ if len(self._firing_times) != 0: # Makes sense to compute delta_t only if there have been firings current_time = datetime.now() delta = current_time - self._firing_times[-1] delta = delta.seconds * 1000 + delta.microseconds * 0.001 if delta < self._arp: # No point in computing the activation level if still in the # absolute refractory period return activation_level = self.compute() if activation_level > self._threshold: self._fire()
return proc # def eventHandler(self, msg): # self.updateLamportClock() # # # if msg.sourceID == self.uid or msg.sourceID == self.uid: # if msg.sourceID == self.uid: # localEvent(msg) # else: # remoteEvent(msg) class TestController(unittest.TestCase): def setUp(self): self.process1 = process(1, 2) self.process2 = process(2, 2) pass def testJava(self): pass def busTester(self, text): print(str(text)) if __name__ == "__main__": bus = Bus() bus.subscribe("tester", busTester) bus.publish("tester", text="Hi there!")
if eventType == "exit" or eventType == "cancel": foreverLoop = False elif eventType == "select": contactIndex = idx contact = Items[idx] setScreen("callConfirmation") screens["callConfirmation"].focus = 0 if menuName == "callConfirmation": if eventType == "select" and item[1] == "call": setScreen("call") else: setScreen("contactsList") if menuName == "call": setScreen("contactsList") setScreen("contactsList") while foreverLoop: dt = pygame.time.Clock().tick(10) for event in pygame.event.get(): if event.type == pygame.QUIT: bus.publish('gui.global', when=displayMode, eventType=pygame.QUIT) elif event.type == pygame.KEYDOWN: bus.publish('gui.key', when=displayMode, eventKey=event.key) screens[displayMode].run() pygame.quit()
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'
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
class AeroApp(tornado.web.Application): def __init__(self, handlers=[], **settings): handlers = list(handlers) self.bus = Bus() self.apps = [] if not settings: settings = {} if "installed_apps" in settings: apps = settings["installed_apps"] for app_module_name in apps: self.apps.append(self.__load_app(app_module_name)) for app in self.apps: for url in app["urls"]: handlers.append(url) if "template_path" in settings: self.loader = AppTemplateLoader(self, settings["template_path"]) else: self.loader = AppTemplateLoader(self) settings["template_loader"] = self.loader handlers.append( ( r"/static/(.*)", AeroStaticFileHandler, {"path": "static_path" in settings and settings["static_path"] or None, "apps": self.apps}, ) ) if "static_path" in settings: settings.pop("static_path") for app in self.apps: if not app["has_listeners"]: continue if hasattr(app["listeners"], "listen"): app["listeners"].listen(self) super(AeroApp, self).__init__(handlers, **settings) self.publish("app_started", app=self) def subscribe(self, key, callback, force=False): return self.bus.subscribe(key, callback, force) def publish(self, key, *args, **kwargs): return self.bus.publish(key, *args, **kwargs) def importable(self, module): try: __import__(module) return True except ImportError: return False def __load_app(self, app_name): try: module = reduce(getattr, app_name.split(".")[1:], __import__(app_name)) except ImportError, err: print "Could not import app %s! Error:" % app_name raise err app_path = abspath(dirname(module.__file__)) urls = [] urls_module = None urls_app_name = "%s.urls" % app_name if self.importable(urls_app_name): urls_module = reduce(getattr, urls_app_name.split(".")[1:], __import__(urls_app_name)) if hasattr(urls_module, "urls"): for url in urls_module.urls: urls.append(url) listeners_module = None listeners_module_name = "%s.listeners" % app_name if self.importable(listeners_module_name): listeners_module = reduce(getattr, listeners_module_name.split(".")[1:], __import__(listeners_module_name)) template_path = abspath(join(dirname(module.__file__), "templates")) has_templates = exists(template_path) static_path = abspath(join(dirname(module.__file__), "static")) has_static = exists(static_path) return { "name": app_name, "module": module, "path": app_path, "urls_module": urls_module, "urls": urls, "has_listeners": listeners_module is not None, "listeners": listeners_module, "has_templates": has_templates, "template_path": template_path, "has_static": has_static, "static_path": static_path, }