Пример #1
0
def test_injector_failure():
    # Dataclass wants a value, doesn't have a default, and it
    # isn't in props or injector
    @dataclass
    class AgeAthlete:
        age: int  # Note that this field is required

    props = dict()
    injectables = dict()
    with pytest.raises(TypeError):
        inject(props, injectables, AgeAthlete)
Пример #2
0
def test_injector_injectedattr_missing_class():
    """ Ask for a class not registered as injectable """
    class Jersey:
        pass

    @dataclass
    class InjectedAthlete:
        shoe_size: int = injected(Jersey, attr='size')

    shoe = Shoe(size=88)
    props = dict()
    injectables = {Shoe.__name__: shoe}
    with pytest.raises(InvalidInjectable) as exc:
        inject(props, injectables, InjectedAthlete)
    expected = 'Invalid injected type Jersey requested from type'
    assert expected == str(exc.value)
Пример #3
0
def test_injector_injected():
    """ Create instance from data based on injectables """

    shoe = Shoe(size=66)
    props = dict()
    injectables = {Shoe.__name__: shoe}
    athlete = inject(props, injectables, Athlete)
    assert 66 == athlete.shoe.size
Пример #4
0
def test_injector_props():
    """ Create instance based on data from passed-in props  """

    shoe = Shoe(size=55)
    props = dict(shoe=shoe)
    injectables = dict()
    athlete = inject(props, injectables, Athlete)
    assert 55 == athlete.shoe.size
Пример #5
0
def test_injector_precedence():
    # When both props and injectable, choose props

    shoe = Shoe(size=55)
    props = dict(shoe=shoe)

    shoe = Shoe(size=66)
    injectables = {Shoe.__name__: shoe}

    athlete = inject(props, injectables, Athlete)
    assert 55 == athlete.shoe.size
Пример #6
0
def test_injector_injected_double():
    """ Tell the injector to hand attribute of another injectable """
    @dataclass
    class InjectedAthlete:
        shoe_size: int = injected(Shoe, attr='size')

    shoe = Shoe(size=88)
    props = dict()
    injectables = {Shoe.__name__: shoe}
    athlete = inject(props, injectables, InjectedAthlete)
    assert 88 == athlete.shoe_size
Пример #7
0
    def initialize(self):
        """ Commit the actions and initialize the registry """
        dectate.commit(self.registry)

        # Get the injectables
        injectables = self.injectables

        # Stash ServiceManager stuff in injectables
        self.add_injectable(self.config)
        self.add_injectable(self)

        # Make the Registry injectable using a well-known name
        injectables['Registry'] = self.registry

        # Make each service config available as injectable
        for serviceconfig in self.config.serviceconfigs.values():
            self.add_injectable(serviceconfig)

        # Get a list of services
        q = dectate.Query('service')
        services = list(q(self.registry))

        # Go through each service, initialize it, then
        # put an instance in the service manager
        for action, target in services:
            # Use injector to make our target class
            props = dict()
            service = inject(props, injectables, target)

            # Store this in our dict of services
            name = action.name
            self.services[name] = service

            # Add this service, and its config, as injectable
            self.add_injectable(service)

        # TODO Should move more of this to a setup() function in each
        # service, to let them provide injectables
        if 'resource' in self.services:
            resources = self.services['resource'].resources
            self.add_injectable(resources)

        # Now the adapters in services['adapter']. Each adapter
        # can be dependency-injected...albeit carefully. Add the
        # (unique) for_ targets as injectable adapters.
        try:
            for action in AdapterAction.sorted_actions(self.registry):
                f = action[0].predicates['for_'].value
                self.adapters[f.__name__] = f
        except dectate.error.QueryError:
            # Likely a unit test that doesn't include adapters in
            # the registry
            pass
Пример #8
0
def test_injector_defaultfactory():
    # Field has a default value which should be used instead of
    # injection

    @dataclass
    class DefaultValueAthlete:
        shoe: Shoe = field(default_factory=Shoe)

    props = dict()
    injectables = dict()
    athlete = inject(props, injectables, DefaultValueAthlete)
    assert 77 == athlete.shoe.size
Пример #9
0
def test_injector_defaultvalue():
    # Field has a default value which should be used instead of
    # injection
    default_shoesize = Shoe(size=34523)

    @dataclass
    class DefaultValueAthlete:
        shoe: Shoe = default_shoesize

    props = dict()
    injectables = dict()
    athlete = inject(props, injectables, DefaultValueAthlete)
    assert 34523 == athlete.shoe.size
Пример #10
0
def test_injector_injected_callable():
    """ Tell the injector to hand call result of another injectable """
    @dataclass
    class CallableShoe:
        size: int

        def __call__(self):
            return self.size + 5

    @dataclass
    class InjectedAthlete:
        shoe_size: int = injected(CallableShoe)

    shoe = CallableShoe(size=70)
    props = dict()
    injectables = {CallableShoe.__name__: shoe}
    athlete = inject(props, injectables, InjectedAthlete)
    assert 75 == athlete.shoe_size
Пример #11
0
    def get_view(self, request) -> Optional[View]:
        """ Use the predicate registry to find the right view class """

        # Grab ViewAction and use sorted_actions to find first match
        sorted_actions = ViewAction.sorted_actions(self.registry)

        # Find the first action which matches the args
        for action, view_class in sorted_actions:
            if action.all_predicates_match(request):
                # Use dependency injection to make an instance of
                # that view class
                view_instance = inject(
                    dict(),  # props
                    self.get_injectables(request),
                    view_class,
                    request=request
                )
                return view_instance

        # No matches, return None
        return None
Пример #12
0
    def get_adapter(self, request, for_: Type[Any],
                    **kwargs) -> Optional[Adapter]:
        """ Use the predicate registry to find the right adapter class """

        # Grab AdapterAction and use sorted_actions to find first match
        sorted_actions = AdapterAction.sorted_actions(self.registry)

        # Find the first action which matches the args
        for action, adapter_class in sorted_actions:
            if action.all_predicates_match(request, for_=for_, **kwargs):
                # Use dependency injection to make an instance of
                # that adapter class
                adapter_instance = inject(
                    kwargs,  # props
                    self.get_injectables(request),
                    adapter_class,
                    request=request)
                return adapter_instance

        # No matches, return None
        return None
Пример #13
0
def test_injector_fielddefault():
    props = dict()
    injectables = dict()
    athlete = inject(props, injectables, Athlete)
    assert 77 == athlete.shoe.size