Esempio n. 1
0
def test_inheritance():
    foo = Resource("foo", __name__)
    bar = Resource("bar", __name__)

    parent = Container()

    class NoopImplementation(Implementation):
        @contextlib.contextmanager
        def reify(self, resource, provider):
            yield

    foo_impl1 = NoopImplementation()
    foo_impl2 = NoopImplementation()
    bar_impl = NoopImplementation()

    parent.provide(foo, foo_impl1)
    parent.provide(bar, bar_impl)

    child = Container(parent)

    child.provide(foo, foo_impl2)

    assert foo_impl1 == parent.find_implementation(foo)
    assert bar_impl == parent.find_implementation(bar)
    assert foo_impl2 == child.find_implementation(foo)
    assert bar_impl == child.find_implementation(bar)
Esempio n. 2
0
def test_pool():
    container = Container()

    count = 0

    counter = Resource("counter", __name__)
    squared_counter = Resource("squared_counter", __name__)

    @counter.plain()
    def next_count():
        nonlocal count
        count += 1
        return count

    @squared_counter.plain(counter)
    def next_squred_counter(counter: int):
        return counter**2

    with container.context() as context:
        assert 1 == context.resolve(counter)
        assert 1 == context.resolve(counter)
        assert 1 == context.resolve(counter)

        assert 1 == context.resolve(squared_counter)
        assert 1 == context.resolve(squared_counter)
        assert 1 == context.resolve(squared_counter)

    with container.context() as context:
        assert 2 == context.resolve(counter)
        assert 2 == context.resolve(counter)
        assert 2 == context.resolve(counter)

        assert 4 == context.resolve(squared_counter)
        assert 4 == context.resolve(squared_counter)
        assert 4 == context.resolve(squared_counter)
Esempio n. 3
0
def test_drain_exception():
    container = Container()

    foo = Resource("foo", __name__)
    bar = Resource("bar", __name__)

    # aliving flag for foo
    foo_alive = False

    @foo.contextual()
    @contextlib.contextmanager
    def get_foo():
        nonlocal foo_alive
        foo_alive = True
        try:
            with pytest.raises(ZeroDivisionError):
                yield "foo"
        finally:
            foo_alive = False

    @bar.contextual(foo)
    @contextlib.contextmanager
    def get_bar(foo: str):
        try:
            yield "bar"
        finally:
            1 / 0

    with pytest.raises(ZeroDivisionError):
        with container.context() as context:
            assert "foo" == context.resolve(foo)
            assert "bar" == context.resolve(bar)
            assert foo_alive is True
    assert foo_alive is False
Esempio n. 4
0
def test_contextual():
    container = Container()

    foo = Resource("foo", __name__)
    bar = Resource("bar", __name__)

    @container.contextual(bar)
    @contextlib.contextmanager
    def with_bar():
        yield "BAR"

    @container.contextual(foo, bar)
    @contextlib.contextmanager
    def with_foo(bar: str):
        yield f"FOO.{bar}"

    with container.context() as context:
        "BAR" == context.resolve(bar)
        "FOO" == context.resolve(foo)

    # and context managers should be left as context managers
    with with_foo("bar") as foo_value:
        assert "FOO.bar" == foo_value
    with with_bar() as bar_value:
        assert "BAR" == bar_value
Esempio n. 5
0
def test_provide():
    foo = Resource("foo", __name__)

    container = Container()

    class SimpleImplementation(Implementation):
        @contextlib.contextmanager
        def reify(self, resource, provider):
            pass

    impl = SimpleImplementation()

    with pytest.raises(ResourceNotProvidedError):
        container.find_implementation(foo)
    container.provide(foo, impl)
    assert impl == container.find_implementation(foo)
Esempio n. 6
0
def test_default_implemenation():
    container = Container()

    foo = Resource("foo", __name__)

    @foo.plain()
    def get_foo():
        return "FOO"

    class SimpleImplementation(Implementation):
        @contextlib.contextmanager
        def reify(self, resource, provider):
            yield "FOO-2"

    assert foo.default_implementation == container.find_implementation(foo)

    impl = SimpleImplementation()
    container.provide(foo, impl)
    assert impl == container.find_implementation(foo)
Esempio n. 7
0
def test_drain():
    container = Container()

    refcount = 0

    reference = Resource("reference", __name__)

    @reference.contextual()
    @contextlib.contextmanager
    def next_count():
        nonlocal refcount
        refcount += 1
        try:
            yield refcount
        finally:
            refcount -= 1

    with container.context() as context:
        assert 1 == context.resolve(reference)
        assert 1 == refcount
    assert 0 == refcount
Esempio n. 8
0
def test_child():
    foo = Resource("foo", __name__)
    bar = Resource("bar", __name__)

    container = Container()

    foo_refs = 0
    bar_refs = 0

    @container.plain(foo)
    def get_foo():
        nonlocal foo_refs
        foo_refs += 1
        return f"foo-{foo_refs}"

    @container.plain(bar)
    def get_bar():
        nonlocal bar_refs
        bar_refs += 1
        return f"bar-{bar_refs}"

    with container.context(preload=[foo]) as parent:
        assert 1 == foo_refs
        assert "foo-1" == parent.resolve(foo)

        with parent.child() as child1:
            assert "foo-1" == child1.resolve(foo)
            assert "bar-1" == child1.resolve(bar)

        with parent.child(preload=[bar]) as child2:
            assert 2 == bar_refs
            assert "foo-1" == child2.resolve(foo)
            assert "bar-2" == child2.resolve(bar)

    assert 1 == foo_refs
    assert 2 == bar_refs
Esempio n. 9
0
def test_plain():

    container = Container()

    foo = Resource("foo", __name__)
    bar = Resource("bar", __name__)
    baz: Resource[Baz] = Resource("baz", __name__)

    @container.plain(bar)
    def get_bar():
        return "BAR"

    @container.plain(foo, bar)
    def get_foo(bar: str):
        return f"FOO.{bar}"

    @container.plain(baz, foo, bar)
    class Baz(object):
        def __init__(self, foo, bar):
            super().__init__()
            self.foo = foo
            self.bar = bar

    with container.context() as context:  # type: Context
        "BAR" == context.resolve(bar)
        "FOO" == context.resolve(foo)
        "FOO" == context.resolve(baz).foo
        "BAR" == context.resolve(baz).bar

    # and functions should be left as plain functions
    assert "FOO.bar" == get_foo("bar")
    assert "BAR" == get_bar()
    baz_instance = Baz("foo", "bar")
    assert isinstance(baz_instance, Baz)
    assert "foo" == baz_instance.foo
    assert "bar" == baz_instance.bar