Example #1
0
    def _assert_providers_compatible_and_extract_template_func(
            providers, port_name):
        assert providers, 'why are you calling me if there are no providers for {}?'.format(
            port_name)

        func_map = {}
        spec_map = {}

        for provider in providers:
            func_map[provider] = func = get_template_funcs(provider)[port_name]
            spec_map[provider] = inspect.getargspec(func)

        non_generic_specs = {
            provider: spec
            for provider, spec in spec_map.iteritems()
            if spec != GENERIC_ARGSPEC
        }

        if not non_generic_specs:  # all needs of this port did not specific an interface
            return func_map.itervalues().next()  # just return the first one

        specs = non_generic_specs.values()
        if not all(spec == specs[0]
                   for spec in specs):  # we have a mixture of specs
            msg = 'The following components all need "{}" but expect different interfaces - {}'.format(
                port_name, ', '.join(
                    sorted(p.__name__ for p in non_generic_specs.iterkeys())))
            raise InconsistentInterface(msg)
        else:
            chosen_one = non_generic_specs.iterkeys().next()
            return func_map[chosen_one]
Example #2
0
def attach_mock_provider(consumer, ports):
    assert isinstance(consumer, INeed)
    assert isinstance(ports, (list, dict))

    invalid_ports = set(ports).difference(consumer.get_needs())
    if invalid_ports:
        raise UnknownPort('Invalid ports for {} - {}'.format(
            consumer, ', '.join(invalid_ports)))

    # create the underlying object that will hold all the mock functions for the specified ports
    template_funcs = get_template_funcs(service=consumer)
    template_func_subset = {port: template_funcs[port] for port in ports}
    template_class = type('Mock' + consumer.__class__.__name__, (),
                          template_func_subset)
    provider_impl = mock.create_autospec(spec=template_class,
                                         spec_set=True,
                                         instance=True)

    # supply return_value if provider
    if isinstance(ports, dict):
        for port, value in ports.iteritems():
            getattr(provider_impl, port).return_value = value

    provider = object_as_provider(provider=provider_impl, ports=ports)
    auto_wire(components=[consumer, provider])

    return provider_impl
Example #3
0
    def test_domain_inherits_needs_template_functions_from_the_services_they_encapsulate(self):
        D = self._get_domain_class()
        domain = D()
        template_funcs = get_template_funcs(service=domain)
        self.assertItemsEqual(['a', 'b'], template_funcs.keys())

        self.assert_has_same_argspec(lambda self, x, y=123: None, template_funcs['a'])
        self.assert_has_same_argspec(lambda self, *args, **kwargs: None, template_funcs['b'])
Example #4
0
    def test_template_function_propagation_works_for_nested_domains(self):
        D = self._get_domain_class()

        class SuperDomain(Domain):
            __services__ = [D]
            __provides__ = AutoProvide()

        domain = SuperDomain()
        template_funcs = get_template_funcs(service=domain)
        self.assertItemsEqual(['a', 'b'], template_funcs.keys())

        self.assert_has_same_argspec(lambda self, x, y=123: None, template_funcs['a'])
        self.assert_has_same_argspec(lambda self, *args, **kwargs: None, template_funcs['b'])
Example #5
0
    def test_default_template_func_is_consistent_and_has_wildcard_specs_but_not_callable(self):
        class MyService(Service):
            deps = Needs(ports=['a', 'b'])

            @provides
            def x(self):
                return self.deps.a() + self.deps.b()

        service = MyService()
        template_funcs = get_template_funcs(service=service)

        func = template_funcs['a']
        self.assertIs(func, template_funcs['b'])
        self.assert_has_same_argspec(lambda self, *args, **kwargs: None, func)
        self.assertRaises(NotImplementedError, func, None)  # template func meant as unbound methods so expects a 'self'
Example #6
0
    def test_needs_defined_using_Needs_class_has_template_funcs_with_correct_argspec(self):
        class MyService(Service):
            deps = Needs(ports=['a', 'b'])

            @provides
            def x(self):
                return self.deps.a() + self.deps.b()

        service = MyService()
        template_funcs = get_template_funcs(service=service)
        self.assertItemsEqual(['a', 'b'], template_funcs.keys())

        def expected_template(self, *args, **kwargs):
            pass

        self.assert_has_same_argspec(expected_template, template_funcs['a'])
        self.assert_has_same_argspec(expected_template, template_funcs['b'])
Example #7
0
    def tests_template_function_propagation_for_services_with_same_needs_and_same_interface(self):

        class NeedsA(NeedsInterface):
            def a(self, x, y=123):
                pass

        class A(Service):
            deps = NeedsA()

            @provides
            def aaa(self):
                return self.deps.a()

        class NeedsAB(NeedsInterface):
            def a(self, x, y=123):  # matching argspec
                pass

            def b(self, z):
                pass

        class AB(Service):
            deps = NeedsAB()

            @provides
            def abb(self):
                return self.deps.a() + self.deps.b()

        class B(Service):
            deps = Needs(['b'])  # no interface, should still match

            @provides
            def bbb(self):
                return self.deps.b()

        class D(Domain):
            __services__ = [A, B, AB]
            __provides__ = AutoProvide()

        domain = D()
        template_funcs = get_template_funcs(service=domain)
        self.assertItemsEqual(['a', 'b'], template_funcs.keys())

        self.assert_has_same_argspec(lambda self, x, y=123: None, template_funcs['a'])
        self.assert_has_same_argspec(lambda self, z: None, template_funcs['b'])
Example #8
0
    def test_needs_defined_using_NeedsInterface_class_has_templte_funcs_with_correct_argspec(self):

        class MyDeps(NeedsInterface):
            def a(self, x, y=123): pass
            def b(self, x, **kwargs): pass
            def c(self, *args, **kwargs): pass

        class MyService(Service):
            deps = MyDeps()

            @provides
            def x(self):
                return self.deps.a() + self.deps.b() + self.deps.c()

        service = MyService()
        template_funcs = get_template_funcs(service=service)
        self.assertItemsEqual(['a', 'b', 'c'], template_funcs.keys())

        self.assert_has_same_argspec(lambda self, x, y=123: None, template_funcs['a'])
        self.assert_has_same_argspec(lambda self, x, **kwargs: None, template_funcs['b'])
        self.assert_has_same_argspec(lambda self, *args, **kwargs: None, template_funcs['c'])