def test_emit_event_implementing_handler(self): EVENT_NAME = "event.hello.world" callback_tracker = [''] def my_callback(*args, **kwargs): self.assertSequenceEqual(args, ['first_pos_arg']) self.assertDictEqual(kwargs, {'a_keyword_arg': 'another_thing'}) callback_tracker[0] += "impl" return "world" dispatcher = SimpleEventDispatcher() handler = dispatcher.implement(event_pattern=EVENT_NAME, priority=1000, callback=my_callback) self.assertIsInstance(handler, EventHandler) result = dispatcher.dispatch(self, EVENT_NAME, 'first_pos_arg', a_keyword_arg='another_thing') self.assertEqual( callback_tracker[0], "impl", "callback should have been invoked" "once and contain value `intcpt` but tracker value is {0}".format( callback_tracker[0])) self.assertEqual( result, "world", "Result should be `world` as this" " is an implementing handler")
def test_emit_event_intercept_follows_intercept(self): EVENT_NAME = "event.hello.world" callback_tracker = [''] def my_callback_intcpt1(event_args, *args, **kwargs): self.assertEqual(event_args.get('sender'), self) next_handler = event_args.get('next_handler') self.assertEqual(next_handler.priority, 2020) self.assertEqual(next_handler.callback.__name__, "my_callback_intcpt2") callback_tracker[0] += "intcpt1_" # invoke next handler but ignore return value return "hello" + next_handler.invoke(event_args, *args, **kwargs) def my_callback_intcpt2(event_args, *args, **kwargs): self.assertDictEqual(event_args, { 'sender': self, 'event': EVENT_NAME, 'next_handler': None }) callback_tracker[0] += "intcpt2_" return "world" dispatcher = SimpleEventDispatcher() dispatcher.intercept(EVENT_NAME, 2000, my_callback_intcpt1) dispatcher.intercept(EVENT_NAME, 2020, my_callback_intcpt2) result = dispatcher.dispatch(self, EVENT_NAME) self.assertEqual( callback_tracker[0], "intcpt1_intcpt2_", "callback was not invoked" " in expected order. Should have been intcpt1_intcpt2_ but is" " {0}".format(callback_tracker[0])) self.assertEqual( result, "helloworld", "Result should be `helloworld` " "as this is the expected return value from the chain")
def test_emit_event_observing_handler(self): EVENT_NAME = "event.hello.world" callback_tracker = [''] def my_callback(event_args, *args, **kwargs): self.assertDictEqual(event_args, { 'sender': self, 'event': EVENT_NAME }) self.assertSequenceEqual(args, ['first_pos_arg']) self.assertDictEqual(kwargs, {'a_keyword_arg': 'another_thing'}) callback_tracker[0] += 'obs' return "hello" dispatcher = SimpleEventDispatcher() handler = dispatcher.observe(event_pattern=EVENT_NAME, priority=1000, callback=my_callback) assert handler.event_pattern == EVENT_NAME assert handler.priority == 1000 assert handler.callback == my_callback self.assertIsInstance(handler, EventHandler) result = dispatcher.dispatch(self, EVENT_NAME, 'first_pos_arg', a_keyword_arg='another_thing') self.assertEqual( callback_tracker[0], "obs", "callback should have been invoked" "once and contain value `obs` but tracker value is {0}".format( callback_tracker[0])) self.assertIsNone( result, "Result should be none as this is an" " observing handler")
def test_messages_logged(self): EVENT_NAME = "an.exceptional.event" class SomeDummyClass(object): @implement(event_pattern=EVENT_NAME, priority=2500) def return_some_value(self, *args, **kwargs): return "hello world" dispatcher = SimpleEventDispatcher() manager = SimpleMiddlewareManager(dispatcher) middleware = EventDebugLoggingMiddleware() manager.add(middleware) some_obj = SomeDummyClass() manager.add(some_obj) with self.assertLogs('cloudbridge.cloud.base.middleware', level='DEBUG') as cm: dispatcher.dispatch(self, EVENT_NAME, "named_param", keyword_param="hello") self.assertTrue( "named_param" in cm.output[0] and "keyword_param" in cm.output[0] and "hello" in cm.output[0], "Log output {0} not as expected".format(cm.output[0])) self.assertTrue( "hello world" in cm.output[1], "Log output {0} does not contain result".format(cm.output[1]))
def test_subscribe_after_emit(self): callback_tracker = [''] def my_callback1(event_args, *args, **kwargs): callback_tracker[0] += "event1_" next_handler = event_args.get('next_handler') if next_handler: return "hello" + next_handler.invoke(event_args, *args, ** kwargs) else: return "hello" def my_callback2(*args, **kwargs): callback_tracker[0] += "event2_" return "some" dispatcher = SimpleEventDispatcher() dispatcher.intercept("event.hello.world", 1000, my_callback1) dispatcher.dispatch(self, "event.hello.world") dispatcher.intercept("event.hello.*", 1001, my_callback2) result = dispatcher.dispatch(self, "event.hello.world") self.assertEqual( callback_tracker[0], "event1_event1_event2_", "Event handlers executed in unexpected order {0}".format( callback_tracker[0])) self.assertEqual(result, "hellosome")
def test_subscribe_multiple_events(self): EVENT_NAME = "event.hello.world" callback_tracker = [''] def my_callback1(event_args, *args, **kwargs): self.assertDictEqual(event_args, { 'sender': self, 'event': EVENT_NAME }) callback_tracker[0] += "event1_" return "hello" def my_callback2(event_args, *args, **kwargs): self.assertDictEqual(event_args, { 'sender': self, 'event': "event.hello.anotherworld" }) callback_tracker[0] += "event2_" return "another" def my_callback3(event_args, *args, **kwargs): self.assertDictEqual( event_args, { 'sender': self, 'event': "event.hello.anotherworld", 'next_handler': None }) callback_tracker[0] += "event3_" return "world" dispatcher = SimpleEventDispatcher() dispatcher.observe(EVENT_NAME, 2000, my_callback1) # register to a different event with the same priority dispatcher.observe("event.hello.anotherworld", 2000, my_callback2) dispatcher.intercept("event.hello.anotherworld", 2020, my_callback3) result = dispatcher.dispatch(self, EVENT_NAME) self.assertEqual( callback_tracker[0], "event1_", "only `event.hello.world` handlers" " should have been triggered but received {0}".format( callback_tracker[0])) self.assertEqual( result, None, "Result should be `helloworld` " "as this is the expected return value from the chain") result = dispatcher.dispatch(self, "event.hello.anotherworld") self.assertEqual( callback_tracker[0], "event1_event2_event3_", "only handlers for" " event `event.hello.anotherworld` should have been triggered" " but received {0}".format(callback_tracker[0])) self.assertEqual( result, "world", "Result should be `world` " "as this is the expected return value from the chain")
def test_basic_middleware(self): class DummyMiddleWare(Middleware): def __init__(self): self.invocation_order = "" def install(self, event_manager): self.event_manager = event_manager self.invocation_order += "install_" def uninstall(self): self.invocation_order += "uninstall" dispatcher = SimpleEventDispatcher() manager = SimpleMiddlewareManager(dispatcher) middleware = DummyMiddleWare() manager.add(middleware) self.assertEqual(middleware.invocation_order, "install_", "install should be called when adding new middleware") manager.remove(middleware) self.assertEqual(middleware.invocation_order, "install_uninstall", "uninstall should be called when removing middleware")
def test_subscribe_event_duplicate_wildcard_priority(self): def my_callback(event_args, *args, **kwargs): pass dispatcher = SimpleEventDispatcher() dispatcher.intercept("event.hello.world", 1000, my_callback) dispatcher.intercept("event.hello.*", 1000, my_callback) with self.assertRaises(HandlerException): dispatcher.dispatch(self, "event.hello.world")
def test_unubscribe(self): EVENT_NAME = "event.hello.world" callback_tracker = [''] def my_callback1(event_args, *args, **kwargs): callback_tracker[0] += "event1_" next_handler = event_args.get('next_handler') if next_handler: return "hello" + next_handler.invoke(event_args, *args, ** kwargs) else: return "hello" def my_callback2(*args, **kwargs): callback_tracker[0] += "event2_" return "some" dispatcher = SimpleEventDispatcher() hndlr1 = dispatcher.intercept(EVENT_NAME, 1000, my_callback1) dispatcher.dispatch(self, EVENT_NAME) hndlr2 = dispatcher.intercept("event.hello.*", 1001, my_callback2) # Both handlers should be registered self.assertListEqual([my_callback1, my_callback2], [ handler.callback for handler in dispatcher.get_handlers_for_event(EVENT_NAME) ]) hndlr1.unsubscribe() # unsubscribing twice should succeed hndlr1.unsubscribe() # Only my_callback2 should be registered after unsubscribe self.assertListEqual([my_callback2], [ handler.callback for handler in dispatcher.get_handlers_for_event(EVENT_NAME) ]) result = dispatcher.dispatch(self, EVENT_NAME) self.assertEqual( callback_tracker[0], "event1_event2_", "Event handlers executed in unexpected order {0}".format( callback_tracker[0])) self.assertEqual(result, "some") hndlr2.unsubscribe() result = dispatcher.dispatch(self, "event.hello.world") self.assertEqual(result, None)
def test_emit_event_implement_follows_intercept(self): EVENT_NAME = "event.hello.world" callback_tracker = [''] def my_callback_intcpt(event_args, *args, **kwargs): self.assertEqual(event_args.get('sender'), self) next_handler = event_args.get('next_handler') self.assertEqual(next_handler.priority, 2020) self.assertEqual(next_handler.callback.__name__, "my_callback_impl") callback_tracker[0] += "intcpt_" # invoke next handler but ignore return value return "hello" + next_handler.invoke(event_args, *args, **kwargs) def my_callback_impl(*args, **kwargs): self.assertSequenceEqual(args, ['first_pos_arg']) self.assertDictEqual(kwargs, {'a_keyword_arg': 'another_thing'}) callback_tracker[0] += "impl_" return "world" dispatcher = SimpleEventDispatcher() dispatcher.intercept(EVENT_NAME, 2000, my_callback_intcpt) dispatcher.implement(EVENT_NAME, 2020, my_callback_impl) result = dispatcher.dispatch(self, EVENT_NAME, 'first_pos_arg', a_keyword_arg='another_thing') self.assertEqual( callback_tracker[0], "intcpt_impl_", "callback was not invoked" " in expected order. Should have been intcpt_impl_ but is" " {0}".format(callback_tracker[0])) self.assertEqual( result, "helloworld", "Result should be `helloworld` " "as this is the expected return value from the chain")
def test_cloudbridge_exception_is_passed_through(self): EVENT_NAME = "an.exceptional.event" class SomeDummyClass(object): @implement(event_pattern=EVENT_NAME, priority=2500) def raise_a_cloudbridge_exception(self, *args, **kwargs): raise InvalidConfigurationException() dispatcher = SimpleEventDispatcher() manager = SimpleMiddlewareManager(dispatcher) some_obj = SomeDummyClass() manager.add(some_obj) middleware = ExceptionWrappingMiddleware() manager.add(middleware) with self.assertRaises(InvalidConfigurationException): dispatcher.dispatch(self, EVENT_NAME)
def test_middleware_dispatcher(self): dispatcher = SimpleEventDispatcher() manager = SimpleMiddlewareManager(dispatcher) assert manager.events == dispatcher # If a dispatcher is not provided, a new one should be created manager2 = SimpleMiddlewareManager() assert manager2.events != dispatcher # dispatching should work manager2.events.dispatch(self, "dummyevent")
def test_subscribe_event_duplicate_wildcard_priority_allowed(self): # duplicate priorities for different wildcard namespaces allowed def my_callback(event_args, *args, **kwargs): pass dispatcher = SimpleEventDispatcher() dispatcher.intercept("event.hello.world", 1000, my_callback) dispatcher.intercept("someevent.hello.*", 1000, my_callback) # emit should work fine in this case with no exceptions dispatcher.dispatch(self, "event.hello.world")
def test_emit_event_observe_follows_intercept(self): EVENT_NAME = "event.hello.world" callback_tracker = [''] def my_callback_intcpt(event_args, *args, **kwargs): self.assertSequenceEqual(args, ['first_pos_arg']) self.assertDictEqual(kwargs, {'a_keyword_arg': 'another_thing'}) self.assertEqual(event_args.get('sender'), self) self.assertEqual(event_args.get('next_handler').priority, 1001) self.assertEqual( event_args.get('next_handler').callback.__name__, "my_callback_obs") callback_tracker[0] += "intcpt_" # invoke next handler next_handler = event_args.get('next_handler') assert next_handler.priority == 1001 assert next_handler.event_pattern == EVENT_NAME assert next_handler.callback == my_callback_obs retval = next_handler.invoke(event_args, *args, **kwargs) self.assertIsNone( retval, "Return values of observable handlers" " should not be propagated.") return "world" def my_callback_obs(event_args, *args, **kwargs): self.assertSequenceEqual(args, ['first_pos_arg']) self.assertDictEqual(kwargs, {'a_keyword_arg': 'another_thing'}) self.assertDictEqual(event_args, { 'sender': self, 'event': EVENT_NAME }) callback_tracker[0] += "obs_" return "hello" dispatcher = SimpleEventDispatcher() # register priorities out of order to test that too dispatcher.observe(EVENT_NAME, 1001, my_callback_obs) dispatcher.intercept(EVENT_NAME, 1000, my_callback_intcpt) result = dispatcher.dispatch(self, EVENT_NAME, 'first_pos_arg', a_keyword_arg='another_thing') self.assertEqual( callback_tracker[0], "intcpt_obs_", "callback was not invoked in " "expected order. Should have been intcpt_obs_ but is {0}".format( callback_tracker[0])) self.assertEqual( result, "world", "Result should be `world` as this" " is the return value of the intercepting handler")
def test_base_middleware(self): EVENT_NAME = "some.event.occurred" class DummyMiddleWare(BaseMiddleware): def __init__(self): self.invocation_order = "" @intercept(event_pattern="some.event.*", priority=900) def my_callback_intcpt(self, event_args, *args, **kwargs): self.invocation_order += "intcpt_" assert 'first_pos_arg' in args assert kwargs.get('a_keyword_arg') == "something" next_handler = event_args.get('next_handler') return next_handler.invoke(event_args, *args, **kwargs) @implement(event_pattern="some.event.*", priority=950) def my_callback_impl(self, *args, **kwargs): self.invocation_order += "impl_" assert 'first_pos_arg' in args assert kwargs.get('a_keyword_arg') == "something" return "hello" @observe(event_pattern="some.event.*", priority=1000) def my_callback_obs(self, event_args, *args, **kwargs): self.invocation_order += "obs" assert 'first_pos_arg' in args assert event_args['result'] == "hello" assert kwargs.get('a_keyword_arg') == "something" dispatcher = SimpleEventDispatcher() manager = SimpleMiddlewareManager(dispatcher) middleware = DummyMiddleWare() manager.add(middleware) dispatcher.dispatch(self, EVENT_NAME, 'first_pos_arg', a_keyword_arg='something') self.assertEqual(middleware.invocation_order, "intcpt_impl_obs") self.assertListEqual( [middleware.my_callback_intcpt, middleware.my_callback_impl, middleware.my_callback_obs], [handler.callback for handler in dispatcher.get_handlers_for_event(EVENT_NAME)]) manager.remove(middleware) self.assertListEqual([], dispatcher.get_handlers_for_event(EVENT_NAME))
def test_automatic_middleware(self): EVENT_NAME = "another.interesting.event.occurred" class SomeDummyClass(object): @observe(event_pattern="another.really.*", priority=1000) def not_a_match(self, *args, **kwargs): pass @intercept(event_pattern="another.*", priority=900) def my_callback_intcpt2(self, *args, **kwargs): pass def not_an_event_handler(self, *args, **kwargs): pass @observe(event_pattern="another.interesting.*", priority=1000) def my_callback_obs1(self, *args, **kwargs): pass @implement(event_pattern="another.interesting.*", priority=1050) def my_callback_impl(self, *args, **kwargs): pass dispatcher = SimpleEventDispatcher() manager = SimpleMiddlewareManager(dispatcher) some_obj = SomeDummyClass() middleware = manager.add(some_obj) dispatcher.dispatch(self, EVENT_NAME) # Middleware should be discovered even if class containing interceptors # doesn't inherit from Middleware self.assertListEqual( [some_obj.my_callback_intcpt2, some_obj.my_callback_obs1, some_obj.my_callback_impl], [handler.callback for handler in dispatcher.get_handlers_for_event(EVENT_NAME)]) manager.remove(middleware) # Callbacks should be correctly removed self.assertListEqual( [], [handler.callback for handler in dispatcher.get_handlers_for_event(EVENT_NAME)])
def test_emit_event_observe_precedes_intercept(self): EVENT_NAME = "event.hello.world" callback_tracker = [''] def my_callback_obs(event_args, *args, **kwargs): self.assertDictEqual(event_args, { 'sender': self, 'event': EVENT_NAME }) self.assertSequenceEqual(args, ['first_pos_arg']) self.assertDictEqual(kwargs, {'a_keyword_arg': 'another_thing'}) callback_tracker[0] += "obs_" return "hello" def my_callback_intcpt(event_args, *args, **kwargs): self.assertDictEqual(event_args, { 'sender': self, 'event': EVENT_NAME, 'next_handler': None }) self.assertSequenceEqual(args, ['first_pos_arg']) self.assertDictEqual(kwargs, {'a_keyword_arg': 'another_thing'}) callback_tracker[0] += "intcpt_" return "world" dispatcher = SimpleEventDispatcher() dispatcher.observe(EVENT_NAME, 1000, my_callback_obs) dispatcher.intercept(EVENT_NAME, 1001, my_callback_intcpt) result = dispatcher.dispatch(self, EVENT_NAME, 'first_pos_arg', a_keyword_arg='another_thing') self.assertEqual( callback_tracker[0], "obs_intcpt_", "callback was not invoked in " "expected order. Should have been obs_intcpt_ but is {0}".format( callback_tracker[0])) self.assertEqual( result, "world", "Result should be `world` as this" " is the return value of the intercepting handler")
def test_event_decorator_no_event_property(self): EVENT_NAME = "some.event.occurred" class SomeDummyClass(object): @dispatch(event=EVENT_NAME, priority=2500) def my_callback_impl(self, *args, **kwargs): assert 'first_pos_arg' in args assert kwargs.get('a_keyword_arg') == "something" return "hello" obj = SomeDummyClass() events = SimpleEventDispatcher() manager = SimpleMiddlewareManager(events) manager.add(obj) # calling my_implementation should raise an exception with self.assertRaises(HandlerException): obj.my_callback_impl('first_pos_arg', a_keyword_arg='something') obj.events = events result = obj.my_callback_impl('first_pos_arg', a_keyword_arg='something') self.assertEqual(result, "hello")
def test_emit_event_implement_precedes_intercept(self): EVENT_NAME = "event.hello.world" callback_tracker = [''] def my_callback_intcpt(event_args, *args, **kwargs): # Impl result should be accessible to intercepts that follow self.assertDictEqual( event_args, { 'sender': self, 'event': EVENT_NAME, 'result': 'world', 'next_handler': None }) self.assertSequenceEqual(args, ['first_pos_arg']) self.assertDictEqual(kwargs, {'a_keyword_arg': 'another_thing'}) callback_tracker[0] += "intcpt_" return "hello" def my_callback_impl(*args, **kwargs): self.assertSequenceEqual(args, ['first_pos_arg']) self.assertDictEqual(kwargs, {'a_keyword_arg': 'another_thing'}) callback_tracker[0] += "impl_" return "world" dispatcher = SimpleEventDispatcher() dispatcher.implement(EVENT_NAME, 2000, my_callback_impl) dispatcher.intercept(EVENT_NAME, 2020, my_callback_intcpt) result = dispatcher.dispatch(self, EVENT_NAME, 'first_pos_arg', a_keyword_arg='another_thing') self.assertEqual( callback_tracker[0], "impl_intcpt_", "callback was not invoked" " in expected order. Should have been intcpt_intcpt_ but is" " {0}".format(callback_tracker[0])) self.assertEqual( result, "world", "Result should be `world` " "as this is the expected return value from the chain")
def test_unknown_exception_is_wrapped(self): EVENT_NAME = "an.exceptional.event" class SomeDummyClass(object): @implement(event_pattern=EVENT_NAME, priority=2500) def raise_a_non_cloudbridge_exception(self, *args, **kwargs): raise Exception("Some unhandled exception") dispatcher = SimpleEventDispatcher() manager = SimpleMiddlewareManager(dispatcher) middleware = ExceptionWrappingMiddleware() manager.add(middleware) # no exception should be raised when there's no next handler dispatcher.dispatch(self, EVENT_NAME) some_obj = SomeDummyClass() manager.add(some_obj) with self.assertRaises(CloudBridgeBaseException): dispatcher.dispatch(self, EVENT_NAME)
def test_multiple_middleware(self): EVENT_NAME = "some.really.interesting.event.occurred" class DummyMiddleWare1(BaseMiddleware): @observe(event_pattern="some.really.*", priority=1000) def my_obs1_3(self, *args, **kwargs): pass @implement(event_pattern="some.*", priority=970) def my_impl1_2(self, *args, **kwargs): return "hello" @intercept(event_pattern="some.*", priority=900) def my_intcpt1_1(self, event_args, *args, **kwargs): next_handler = event_args.get('next_handler') return next_handler.invoke(event_args, *args, **kwargs) class DummyMiddleWare2(BaseMiddleware): @observe(event_pattern="some.really.*", priority=1050) def my_obs2_3(self, *args, **kwargs): pass @intercept(event_pattern="*", priority=950) def my_intcpt2_2(self, event_args, *args, **kwargs): next_handler = event_args.get('next_handler') return next_handler.invoke(event_args, *args, **kwargs) @implement(event_pattern="some.really.*", priority=920) def my_impl2_1(self, *args, **kwargs): pass dispatcher = SimpleEventDispatcher() manager = SimpleMiddlewareManager(dispatcher) middleware1 = DummyMiddleWare1() middleware2 = DummyMiddleWare2() manager.add(middleware1) manager.add(middleware2) dispatcher.dispatch(self, EVENT_NAME) # Callbacks in both middleware classes should be registered self.assertListEqual( [middleware1.my_intcpt1_1, middleware2.my_impl2_1, middleware2.my_intcpt2_2, middleware1.my_impl1_2, middleware1.my_obs1_3, middleware2.my_obs2_3], [handler.callback for handler in dispatcher.get_handlers_for_event(EVENT_NAME)]) manager.remove(middleware1) # Only middleware2 callbacks should be registered self.assertListEqual( [middleware2.my_impl2_1, middleware2.my_intcpt2_2, middleware2.my_obs2_3], [handler.callback for handler in dispatcher.get_handlers_for_event(EVENT_NAME)]) # add middleware back to check that internal state is properly handled manager.add(middleware1) # should one again equal original list self.assertListEqual( [middleware1.my_intcpt1_1, middleware2.my_impl2_1, middleware2.my_intcpt2_2, middleware1.my_impl1_2, middleware1.my_obs1_3, middleware2.my_obs2_3], [handler.callback for handler in dispatcher.get_handlers_for_event(EVENT_NAME)])
def test_emit_event_no_handlers(self): dispatcher = SimpleEventDispatcher() result = dispatcher.dispatch(self, "event.hello.world") self.assertIsNone( result, "Result should be none as there are no" "registered handlers")
def __init__(self): self.invocation_order = "" self.events = SimpleEventDispatcher()
def test_subscribe_wildcard(self): callback_tracker = [''] def my_callback1(event_args, *args, **kwargs): callback_tracker[0] += "event1_" next_handler = event_args.get('next_handler') return "hello" + next_handler.invoke(event_args, *args, **kwargs) def my_callback2(event_args, *args, **kwargs): callback_tracker[0] += "event2_" next_handler = event_args.get('next_handler') return "some" + next_handler.invoke(event_args, *args, **kwargs) def my_callback3(event_args, *args, **kwargs): callback_tracker[0] += "event3_" next_handler = event_args.get('next_handler') return "other" + next_handler.invoke(event_args, *args, **kwargs) def my_callback4(*args, **kwargs): callback_tracker[0] += "event4_" return "world" dispatcher = SimpleEventDispatcher() dispatcher.intercept("event.*", 2000, my_callback1) # register to a different event with the same priority dispatcher.intercept("event.hello.*", 2010, my_callback2) dispatcher.intercept("event.hello.there", 2030, my_callback4) dispatcher.intercept("event.*.there", 2020, my_callback3) dispatcher.intercept("event.*.world", 2020, my_callback4) dispatcher.intercept("someevent.hello.there", 2030, my_callback3) # emit a series of events result = dispatcher.dispatch(self, "event.hello.there") self.assertEqual( callback_tracker[0], "event1_event2_event3_event4_", "Event handlers executed in unexpected order {0}".format( callback_tracker[0])) self.assertEqual(result, "hellosomeotherworld") result = dispatcher.dispatch(self, "event.test.hello.world") self.assertEqual( callback_tracker[0], "event1_event2_event3_event4_event1_event4_", "Event handlers executed in unexpected order {0}".format( callback_tracker[0])) self.assertEqual(result, "helloworld")
def __init__(self): self.__events = SimpleEventDispatcher()