def test_get_item(self): container = IocContainer({ 'definitions': { 'test': { 'item': 'tests.watson.di.support.SampleDependency', 'type': 'singleton', }, 'test2': { 'item': 'tests.watson.di.support.sample_dependency', 'type': 'singleton', }, 'test3': { 'item': 'tests.watson.di.support.sample_dependency_with_args', 'type': 'singleton', 'init': { 'arg': 'some arg' } } } }) container.add('def', lambda container: 'something') assert isinstance(container.get('test'), SampleDependency) assert container.get('test2') == 'test' assert container.get('def') == 'something' assert container.get('def') == 'something' assert container.get('test3') == 'some arg'
def test_definition_item_doesnt_exist(self): container = IocContainer({ 'definitions': { 'test': {} } }) container.get('test')
def test_prototype_add(self): container = IocContainer() dep = SampleDependency() container.add('test', dep) assert container.get('test') == dep dep2 = SampleDependency() container.add('test', dep2) assert container.get('test') == dep2
def test_get_builtin(self): container = IocContainer({ 'definitions': { 'test': { 'item': {'test': 'test'} } } }) assert isinstance(container.get('test'), dict)
def test_prototype(self): container = IocContainer({ 'definitions': { 'test': { 'item': 'tests.watson.di.support.SampleDependency', 'type': 'prototype' } } }) test1 = container.get('test') test2 = container.get('test') assert test1 != test2
def test_get_item(self): container = IocContainer({ 'definitions': { 'test': { 'item': 'tests.watson.di.support.SampleDependency', 'type': 'singleton', }, 'test2': { 'item': 'tests.watson.di.support.sample_dependency', 'type': 'singleton', }, 'test3': { 'item': 'tests.watson.di.support.sample_dependency_with_args', 'type': 'singleton', 'init': { 'arg': 'some arg' } }, 'lambda': { 'item': lambda container: container.get('test') }, 'lambda_init': { 'item': 'tests.watson.di.support.SampleLambdaWithInit', 'init': lambda container: container.get('config') } } }) container.add_definition('def', {'item': lambda container: 'something'}) container.add_definition('config', {'item': {'test': 'value'}}) assert isinstance(container.get('test'), SampleDependency) assert container.get('test2') == 'test' assert container.get('def') == 'something' assert container.get('def') == 'something' assert container.get('def') is container.get('def') assert container.get('test3') == 'some arg' assert isinstance(container.get('lambda'), SampleDependency) assert container.get('lambda_init').test == 'value' assert len(container.instantiated) == 7
def test_param_from_container(self): container = IocContainer({ 'params': { 'test': 'sample2' }, 'definitions': { 'sample': { 'item': 'tests.watson.di.support.SampleDependency', 'property': { 'test': 'test', 'test2': sample_dependency } }, 'sample2': { 'item': 'tests.watson.di.support.sample_dependency' } } }) sample = container.get('sample') assert sample assert sample.test assert sample.test2 == 'test'
def test_add_definition(self): container = IocContainer() container.add_definition('dep', {'item': lambda container: 'something'}) assert container.get('dep') == 'something'
def test_add_item(self): container = IocContainer() container.add('dep', lambda container: 'something') assert container.get('dep') == 'something'
class Base(ContainerAware, EventDispatcherAware, metaclass=abc.ABCMeta): """The core application structure for a Watson application. It makes heavy use of the IocContainer and EventDispatcher classes to handle the wiring and executing of methods. The default configuration for Watson applications can be seen at watson.mvc.config. """ _config = None @property def config(self): """Returns the configuration of the application. """ return self._config @config.setter def config(self, config): """Sets the configuration for the application. Usage: app = Base() app.config = {'some': 'settings'} Args: mixed config: The configuration to use. """ if isinstance(config, ModuleType): conf = module_to_dict(config, '__') else: conf = config or {} self._config = dict_deep_update(module_to_dict(DefaultConfig, '__'), conf) self.container.add('application.config', self.config) @property def container(self): """Returns the applications IocContainer. If no container has been created, a new container will be created based on the dependencies within the application configuration. """ if not self._container: self.container = IocContainer(self.config['dependencies']) return self._container @container.setter def container(self, container): """Sets the application IocContainer. Adds the application to the container, which can then be accessed via the 'application' key. """ container.add('application', self) self._container = container def __init__(self, config=None): """Initializes the application. Registers any events that are within the application configuration. Usage: app = Base() Events: Dispatches the INIT. Args: mixed config: See the Base.config properties. """ self.config = config or {} self.dispatcher = self.container.get('shared_event_dispatcher') for event, listeners in self.config['events'].items(): for callback_priority_pair in listeners: try: priority = callback_priority_pair.priority except: priority = 1 try: once_only = callback_priority_pair.once_only except: once_only = False self.dispatcher.add( event, self.container.get(callback_priority_pair[0]), priority, once_only) self.dispatcher.trigger(Event(events.INIT, target=self)) super(Base, self).__init__() def __call__(self, *args, **kwargs): return self.run(*args, **kwargs) @abc.abstractmethod def run(self): raise NotImplementedError( 'You must implement __call__') # pragma: no cover
class Base(ContainerAware, EventDispatcherAware, metaclass=abc.ABCMeta): """The core application structure for a Watson application. It makes heavy use of the IocContainer and EventDispatcher classes to handle the wiring and executing of methods. The default configuration for Watson applications can be seen at watson.framework.config. Attributes: _config (dict): The configuration for the application. global_app (Base): A reference to the currently running application. """ _config = None global_app = None @property def config(self): """Returns the configuration of the application. """ return self._config @config.setter def config(self, config): """Sets the configuration for the application. Example: .. code-block:: python app = Base() app.config = {'some': 'settings'} Args: config (mixed): The configuration to use. """ if isinstance(config, ModuleType): conf = module_to_dict(config, '__') else: conf = config or {} self._config = dict_deep_update(module_to_dict(DefaultConfig, '__'), conf) self.container.add('application.config', self.config) @property def container(self): """Returns the applications IocContainer. If no container has been created, a new container will be created based on the dependencies within the application configuration. """ if not self._container: self.container = IocContainer(self.config['dependencies']) return self._container @container.setter def container(self, container): """Sets the application IocContainer. Adds the application to the container, which can then be accessed via the 'application' key. """ container.add('application', self) self._container = container def __init__(self, config=None): """Initializes the application. Registers any events that are within the application configuration. Example: .. code-block:: python app = Base() Events: Dispatches the INIT. Args: config (mixed): See the Base.config properties. """ Base.global_app = self self.config = config or {} if 'exceptions' not in self.config: self.exception_class = ApplicationError else: self.exception_class = imports.load_definition_from_string( self.config['exceptions']['class']) self.register_events() self.trigger_init_event() super(Base, self).__init__() def trigger_init_event(self): """Execute any event listeners for the INIT event. """ self.dispatcher.trigger(Event(events.INIT, target=self)) def register_events(self): """Collect all the events from the app config and register them against the event dispatcher. """ self.dispatcher = self.container.get('shared_event_dispatcher') for event, listeners in self.config['events'].items(): for callback_priority_pair in listeners: try: priority = callback_priority_pair.priority except: priority = 1 try: once_only = callback_priority_pair.once_only except: once_only = False self.dispatcher.add( event, self.container.get(callback_priority_pair[0]), priority, once_only) def __call__(self, *args, **kwargs): return self.run(*args, **kwargs) @abc.abstractmethod def run(self): raise NotImplementedError( 'You must implement __call__') # pragma: no cover
class Base(ContainerAware, EventDispatcherAware, metaclass=abc.ABCMeta): """The core application structure for a Watson application. It makes heavy use of the IocContainer and EventDispatcher classes to handle the wiring and executing of methods. The default configuration for Watson applications can be seen at watson.mvc.config. """ _config = None @property def config(self): """Returns the configuration of the application. """ return self._config @config.setter def config(self, config): """Sets the configuration for the application. Usage: app = Base() app.config = {'some': 'settings'} Args: mixed config: The configuration to use. """ if isinstance(config, ModuleType): conf = module_to_dict(config, '__') else: conf = config or {} self._config = dict_deep_update(module_to_dict(DefaultConfig, '__'), conf) self.container.add('application.config', self.config) @property def container(self): """Returns the applications IocContainer. If no container has been created, a new container will be created based on the dependencies within the application configuration. """ if not self._container: self.container = IocContainer(self.config['dependencies']) return self._container @container.setter def container(self, container): """Sets the application IocContainer. Adds the application to the container, which can then be accessed via the 'application' key. """ container.add('application', self) self._container = container def __init__(self, config=None): """Initializes the application. Registers any events that are within the application configuration. Usage: app = Base() Events: Dispatches the INIT. Args: mixed config: See the Base.config properties. """ self.config = config or {} self.dispatcher = self.container.get('shared_event_dispatcher') for event, listeners in self.config['events'].items(): for callback_priority_pair in listeners: try: priority = callback_priority_pair.priority except: priority = 1 try: once_only = callback_priority_pair.once_only except: once_only = False self.dispatcher.add(event, self.container.get(callback_priority_pair[0]), priority, once_only) self.dispatcher.trigger(Event(events.INIT, target=self)) super(Base, self).__init__() def __call__(self, *args, **kwargs): return self.run(*args, **kwargs) @abc.abstractmethod def run(self): raise NotImplementedError('You must implement __call__') # pragma: no cover
def test_not_added(self): container = IocContainer() assert container.get('tests.watson.di.support.not_added') == 'not added'
def test_definition_doesnt_exist(self): container = IocContainer() container.get('test')
def test_add_dict(self): container = IocContainer() dep = {'something': 'test'} container.add('dep', dep) assert container.get('dep') == dep
def test_module_not_exist(self): container = IocContainer() with raises(exceptions.NotFoundError): container.get('something.blah')
def test_get_failed_object(self): container = IocContainer() with raises(exceptions.NotFoundError): container.get('none') assert True
def test_add_instantiated(self): container = IocContainer() dep = SampleDependency() container.add('dep', dep) assert container.get('dep') == dep
class Base(ContainerAware, EventDispatcherAware, metaclass=abc.ABCMeta): """The core application structure for a Watson application. It makes heavy use of the IocContainer and EventDispatcher classes to handle the wiring and executing of methods. The default configuration for Watson applications can be seen at watson.framework.config. Attributes: _config (dict): The configuration for the application. global_app (Base): A reference to the currently running application. """ _config = None global_app = None @property def config(self): """Returns the configuration of the application. """ return self._config @config.setter def config(self, config): """Sets the configuration for the application. Example: .. code-block:: python app = Base() app.config = {'some': 'settings'} Args: config (mixed): The configuration to use. """ if isinstance(config, ModuleType): conf = module_to_dict(config, '__') else: conf = config or {} self._config = dict_deep_update( module_to_dict(DefaultConfig, '__'), conf) self.container.add('application.config', self.config) @property def container(self): """Returns the applications IocContainer. If no container has been created, a new container will be created based on the dependencies within the application configuration. """ if not self._container: self.container = IocContainer(self.config['dependencies']) return self._container @container.setter def container(self, container): """Sets the application IocContainer. Adds the application to the container, which can then be accessed via the 'application' key. """ container.add('application', self) self._container = container def __init__(self, config=None): """Initializes the application. Registers any events that are within the application configuration. Example: .. code-block:: python app = Base() Events: Dispatches the INIT. Args: config (mixed): See the Base.config properties. """ Base.global_app = self self.config = config or {} if not self.config.get('exceptions'): self.exception_class = ApplicationError else: self.exception_class = imports.load_definition_from_string( self.config['exceptions']['class']) self.register_events() self.trigger_init_event() super(Base, self).__init__() def trigger_init_event(self): """Execute any event listeners for the INIT event. """ self.dispatcher.trigger(Event(events.INIT, target=self)) def register_events(self): """Collect all the events from the app config and register them against the event dispatcher. """ self.dispatcher = self.container.get('shared_event_dispatcher') for event, listeners in self.config['events'].items(): for callback_priority_pair in listeners: try: priority = callback_priority_pair[1] except: priority = 1 try: once_only = callback_priority_pair[2] except: once_only = False self.dispatcher.add( event, self.container.get(callback_priority_pair[0]), priority, once_only) def __call__(self, *args, **kwargs): return self.run(*args, **kwargs) @abc.abstractmethod def run(self): raise NotImplementedError('You must implement __call__') # pragma: no cover
def test_module_not_exist(self): container = IocContainer() with raises(ImportError): container.get('something.blah')
def test_get_self_defined_object(self): container = IocContainer() obj = container.get('tests.watson.di.support.DependencyWithDefinition') assert obj.the_test() == 'test'
class Base(ContainerAware, EventDispatcherAware, metaclass=abc.ABCMeta): """The core application structure for a Watson application. It makes heavy use of the IocContainer and EventDispatcher classes to handle the wiring and executing of methods. The default configuration for Watson applications can be seen at watson.framework.config. Attributes: _config (dict): The configuration for the application. global_app (Base): A reference to the currently running application. """ _config = None global_app = None @property def config(self): """Returns the configuration of the application. """ return self._config @config.setter def config(self, config): """Sets the configuration for the application. Example: .. code-block:: python app = Base() app.config = {'some': 'settings'} Args: config (mixed): The configuration to use. """ if isinstance(config, ModuleType): conf = module_to_dict(config, '__') else: conf = config or {} self._config = dict_deep_update( module_to_dict(DefaultConfig, '__'), conf) self.container.add('application.config', self.config) @property def container(self): """Returns the applications IocContainer. If no container has been created, a new container will be created based on the dependencies within the application configuration. """ if not self._container: self.container = IocContainer(self.config['dependencies']) return self._container @container.setter def container(self, container): """Sets the application IocContainer. Adds the application to the container, which can then be accessed via the 'application' key. """ container.add('application', self) self._container = container def __init__(self, config=None): """Initializes the application. Registers any events that are within the application configuration. Example: .. code-block:: python app = Base() Events: Dispatches the INIT. Args: config (mixed): See the Base.config properties. """ Base.global_app = self self.config = config or {} if not self.config.get('exceptions'): self.exception_class = ApplicationError else: self.exception_class = imports.load_definition_from_string( self.config['exceptions']['class']) self.register_components() self.register_events() self.trigger_init_event() super(Base, self).__init__() def register_components(self): """Register any components specified with the application. Components can include the following modules: - dependencies - events - models - routes - views Registering a component will merge any configuration settings within the above modules prior to the application booting. An example component might look like: /component /views /index.html /routes.py /views.py """ types = ('dependencies', 'events', 'routes', 'models', 'views') for component in self.config['components']: for type_ in types: with contextmanagers.suppress(Exception): type_component = imports.load_definition_from_string( '{}.{}.{}'.format(component, type_, type_)) if type_ == 'dependencies': self.container.update(type_component) if not isinstance(type_component, ModuleType): self._config[type_] = dict_deep_update( self._config.get(type_, {}), type_component) self._config['views'][ 'renderers']['jinja2']['config']['packages'].append( (component, 'views')) def trigger_init_event(self): """Execute any event listeners for the INIT event. """ self.dispatcher.trigger(Event(events.INIT, target=self)) def register_events(self): """Collect all the events from the app config and register them against the event dispatcher. """ self.dispatcher = self.container.get('shared_event_dispatcher') for event, listeners in self.config['events'].items(): for callback_priority_pair in listeners: try: priority = callback_priority_pair[1] except: priority = 1 try: once_only = callback_priority_pair[2] except: once_only = False self.dispatcher.add( event, self.container.get(callback_priority_pair[0]), priority, once_only) def __call__(self, *args, **kwargs): return self.run(*args, **kwargs) @abc.abstractmethod def run(self): raise NotImplementedError('You must implement __call__') # pragma: no cover