Пример #1
0
    def test_make_will_inject_container(self):
        def returns_arg(c: Container):
            return c

        container = Container()
        arg = container.make(returns_arg)
        assert arg is container
Пример #2
0
    def test_make_string_argument_works(self):
        def make_n():
            return 5

        container = Container()
        container.bind('n', make_n)
        assert container.make('n') == 5
Пример #3
0
    def test_make_raises_if_no_annotation(self):
        class X:
            def __init__(self, foo): pass

        container = Container()
        with assert_raises(ResolutionError, 'foo'):
            container.make(X)
Пример #4
0
    def test_make_passes_kwargs(self):
        class X:
            def __init__(self, foo):
                self.foo = foo

        container = Container()
        x = container.make(X, {'foo': 'bar'})
        assert x.foo == 'bar'
Пример #5
0
    def test_make_is_not_caching_instances(self):
        class X:
            pass

        container = Container()
        x1 = container.make(X)
        x2 = container.make(X)
        assert x1 is not x2
Пример #6
0
    def test_make_handles_None_annotation(self):
        class X:
            def __init__(self, foo: None):
                self.foo = foo

        container = Container()
        x = container.make(X)
        assert x.foo is None
Пример #7
0
    def test_make_raises_if_given_invalid_explicit_kwargs(self):
        class X:
            def __init__(self, foo: str):
                self.foo = foo

        container = Container()
        with assert_raises(ResolutionError, 'bar'):
            container.make(X, {'foo': 'x', 'bar': 'y'})
Пример #8
0
    def test_make_raises_if_given_invalid_explicit_kwargs(self):
        class X:
            def __init__(self, foo: str):
                self.foo = foo

        container = Container()
        with assert_raises(ResolutionError, "bar"):
            container.make(X, {"foo": "x", "bar": "y"})
Пример #9
0
    def test_make_passes_kwargs(self):
        class X:
            def __init__(self, foo):
                self.foo = foo

        container = Container()
        x = container.make(X, {"foo": "bar"})
        assert x.foo == "bar"
Пример #10
0
    def test_make_does_not_auto_create_namedtuple(self):
        class X:
            pass

        Y = namedtuple('Y', ['x'])

        container = Container()
        with assert_raises(ResolutionError, 'x'):
            container.make(Y)
Пример #11
0
    def test_make_contextual_with_builtin_type(self):
        class X:
            def __init__(self, foo: str):
                self.foo = foo

        container = Container()
        container.bind_contextual(when=X, wants=str, called='foo', give=lambda: 'bar')
        x = container.make(X)
        assert x.foo == 'bar'
Пример #12
0
    def test_make_with_singletons(self):
        class X:
            pass

        container = Container()
        container.bind(X, X, lifetime_strategy=SINGLETON)
        x1 = container.make(X)
        x2 = container.make(X)
        assert x1 is x2
Пример #13
0
    def test_make_raises_if_not_concrete(self):
        class X(abc.ABC):
            @abc.abstractmethod
            def foo(self):
                pass

        container = Container()
        with assert_raises(ResolutionError, X):
            container.make(X)
Пример #14
0
    def test_make_contextual_with_builtin_type(self):
        class X:
            def __init__(self, foo: str):
                self.foo = foo

        container = Container()
        container.bind_contextual(when=X, wants=str, wants_name="foo", give=lambda: "bar")
        x = container.make(X)
        assert x.foo == "bar"
Пример #15
0
    def test_make_supports_namedtuple_contextual_binding(self):
        class X:
            pass

        Y = namedtuple("Y", ["x"])

        container = Container()
        container.bind_contextual(when=Y, wants_name="x", give=X)
        y = container.make(Y)
        assert isinstance(y.x, X)
Пример #16
0
    def test_make_injects_class_annotations(self):
        class X:
            pass

        class Y:
            foo: X

        container = Container()
        y = container.make(Y)
        assert isinstance(y.foo, X)
Пример #17
0
    def test_make_supports_namedtuple_contextual_binding(self):
        class X:
            pass

        Y = namedtuple('Y', ['x'])

        container = Container()
        container.bind_contextual(when=Y, called='x', give=X)
        y = container.make(Y)
        assert isinstance(y.x, X)
Пример #18
0
    def test_make_does_not_inject_class_annotations_if_hinted_as_classvar(self):
        class X:
            pass

        class Y:
            foo: ClassVar[X]

        container = Container()
        y = container.make(Y)
        assert not hasattr(Y, 'foo')
        assert not hasattr(y, 'foo')
Пример #19
0
    def test_make_string_argument_in_subrequirement(self):
        class X:
            def __init__(self, arg: 'n'):  # noqa: F821
                self.arg = arg

        def make_n():
            return 5

        container = Container()
        container.bind('n', make_n)
        assert container.make(X).arg == 5
Пример #20
0
    def test_make_init_kwargs_also_apply_to_attrs(self):
        class X:
            pass

        class Y:
            foo: X

        x1 = X()
        container = Container()
        y = container.make(Y, {'foo': x1})
        assert not hasattr(Y, 'foo')
        assert y.foo is x1
Пример #21
0
    def test_make_simple_autowiring_with_concrete_annotations(self):
        class X:
            pass

        class Y:
            def __init__(self, x: X):
                self.x = x

        container = Container()
        y = container.make(Y)
        assert isinstance(y, Y)
        assert isinstance(y.x, X)
Пример #22
0
    def test_make_caching_fibonacci(self):
        """A more complete quasi-real-life test"""

        class KeyValueDatabase(abc.ABC):
            @abc.abstractmethod
            def get(self, key):
                pass

            @abc.abstractmethod
            def has(self, key):
                pass

            @abc.abstractmethod
            def set(self, key, value):
                pass

        class MemoryStore(KeyValueDatabase):
            def __init__(self, initial_data: dict):
                self.data = initial_data

            def set(self, key, value):
                self.data[key] = value

            def has(self, key):
                return key in self.data

            def get(self, key):
                return self.data[key]

        class CachingFibonacci:
            def __init__(self, cache: KeyValueDatabase):
                self.cache = cache

            def calculate(self, n: int):
                if n in {0, 1}:
                    return n
                if self.cache.has(n):
                    return self.cache.get(n)
                return self.calculate(n - 1) + self.calculate(n - 2)

        container = Container()
        with assert_raises(ResolutionError, KeyValueDatabase):
            container.make(CachingFibonacci)

        container.bind(KeyValueDatabase, MemoryStore)
        with assert_raises(ResolutionError, "initial_data"):
            container.make(CachingFibonacci)

        container.bind_contextual(
            when=MemoryStore, wants=dict, wants_name="initial_data", give=lambda: {}
        )
        fib = container.make(CachingFibonacci)
        assert fib.calculate(6) == 8
Пример #23
0
    def test_make_optional_param_injection(self):
        class X:
            pass

        default_x = X()

        class Y:
            def __init__(self, foo: X = default_x):
                self.foo = foo

        container = Container()
        y = container.make(Y)
        assert y.foo is default_x
Пример #24
0
    def test_make_does_not_inject_class_annotations_if_set_on_class(self):
        class X:
            pass

        x1 = X()

        class Y:
            foo: X = x1

        container = Container()
        y = container.make(Y)
        assert y.foo is x1
        assert Y.foo is x1
Пример #25
0
    def test_make_init_kwargs_params_used_before_attr(self):
        class X:
            pass

        class Y:
            foo: X

            def __init__(self, foo: X):
                self.init_foo = foo

        container = Container()
        y = container.make(Y)
        assert isinstance(y.init_foo, X)
        assert not hasattr(y, 'foo')
Пример #26
0
    def test_make_does_not_save_singleton_if_explicit_init_kwargs_set(self):
        class X:
            def __init__(self, foo: str):
                self.foo = foo

        container = Container()
        container.bind(X, lambda: X('foo'), SINGLETON)
        x1 = container.make(X)
        x2 = container.make(X, {'foo': 'bar'})
        x3 = container.make(X)

        assert x1.foo == 'foo'
        assert x3 is x1
        assert x2.foo == 'bar'
        assert x2 is not x1
Пример #27
0
    def test_make_optional_attr_injection(self):
        class X:
            pass

        default_x = X()

        class Y:
            foo: X

            def __init__(self):
                self.foo = default_x

        container = Container()
        y = container.make(Y)
        assert y.foo is default_x
Пример #28
0
    def test_make_optional_param_contextual_binding_prioritized_over_default(self):
        class X:
            pass

        default_x = X()

        class Y:
            def __init__(self, foo: X = default_x):
                self.foo = foo

        container = Container()
        bound_x = X()
        container.bind_contextual(when=Y, wants=X, give=lambda: bound_x)
        y = container.make(Y)
        assert y.foo is not default_x
        assert y.foo is bound_x
Пример #29
0
    def test_make_optional_param_injection_default_prioritized_over_explicit_binding(self):
        class X:
            pass

        default_x = X()

        class Y:
            def __init__(self, foo: X = default_x):
                self.foo = foo

        container = Container()
        bound_x = X()
        container.bind_instance(X, bound_x)
        y = container.make(Y)
        assert y.foo is default_x
        assert y.foo is not bound_x
Пример #30
0
    def test_make_does_not_inject_class_annotations_if_hinted_in_init(self):
        class X1:
            pass

        class X2:
            pass

        class Y:
            foo: X1

            def __init__(self, foo: X2):
                self.foo = foo

        container = Container()
        y = container.make(Y)
        assert isinstance(y.foo, X2)