예제 #1
0
def test_injector_clone():
    class A:
        pass

    def fn(i: Injector, kwarg: A):
        assert isinstance(kwarg, A)
        assert kwarg is ainst
        assert i[A] is kwarg
        assert i is not injector
        i[A] = "another"
        return injector.exec(fn2)

    def fn2(i: Injector):
        assert i[A] is ainst
        return "OK"

    injector = Injector()
    injector.provide(A)

    ainst = injector[A] = injector[A]

    def get_kw(a: A, *, name: str, type: type):
        if name == "kwarg":
            return a
        else:
            raise NoKwOnly()

    injectable = injector.provide(fn, provide=[KwOnly(get_kw)])
    assert injectable(injector) == "OK"
    assert injector[fn] == "OK"
예제 #2
0
def test_injector_kwonly_def_error():
    injector = Injector()

    def get_kwargs1():
        pass

    def get_kwargs2(*, xyz):
        pass

    def get_kwargs3(*, type):
        pass

    with pytest.raises(ProvideError) as exc:
        injector.provide(KwOnly(get_kwargs1))
    exc.match("Callable must have kwonly arguments")

    with pytest.raises(ProvideError) as exc:
        injector.provide(KwOnly(get_kwargs2))
    exc.match(
        "Keyword argument resolver function muts have 'name' keyword only argument"
    )

    with pytest.raises(ProvideError) as exc:
        injector.provide(KwOnly(get_kwargs3))
    exc.match(
        "Keyword argument resolver function muts have 'name' keyword only argument"
    )

    class X:
        pass

    with pytest.raises(ProvideError) as exc:
        injector.provide(KwOnly(X))
    exc.match("Argument must be callable.")
예제 #3
0
def test_injector_descend2():
    class A:
        pass

    def fn(i: Injector, a: A):
        assert isinstance(a, A)
        assert a is ainst
        assert injector[A] is not a
        return i.exec(fn2)

    def fn2(i: Injector, a: A):
        assert isinstance(a, A)
        assert a is ainst
        assert i[A] is a
        return "OK"

    injector = Injector()
    injector.provide(A)

    iclone = injector.descend()
    ainst = iclone[A] = iclone[A]

    assert iclone.exec(fn) == "OK"

    iclone2 = iclone.descend()
    assert iclone2.exec(fn) == "OK"
예제 #4
0
def test_injector_attribute_inheritance():
    injector = Injector()

    class A:
        pass

    class B:
        a: Inject[A]

        def __init__(self):
            assert isinstance(self.a, A)

    class X:
        pass

    class C(B):
        x: Inject[X]

        def __init__(self):
            super().__init__()
            assert isinstance(self.x, X)

    injector.provide(A)
    injector.provide(X)

    c = injector.exec(C)
    assert isinstance(c, C)
    assert isinstance(c.a, A)
    assert isinstance(c.x, X)
예제 #5
0
def test_strategy_value():
    injector = Injector()
    provided = "VALUE"
    injector.provide("V", provided, VALUE)

    assert injector["V"] == "VALUE"
    assert injector["V"] is provided
    assert injector.provide("V", provided, VALUE)(injector) == "VALUE"
예제 #6
0
def test_injectable_call():
    injector = Injector()

    class A:
        pass

    injectable = injector.provide(A)
    assert isinstance(injectable(injector), A)
예제 #7
0
def test_forwardref_fn():
    def fn(a: "A"):
        assert isinstance(a, A)
        return "OK"

    injector = Injector()
    injector.provide(A)
    assert injector.exec(fn) == "OK"
예제 #8
0
def test_descend():
    injector = Injector()
    injector.provide(SelfInject)

    child = injector.descend()
    child.provide(injectable_func2)

    x = child[injectable_func2]
    assert isinstance(x, SelfInject)
예제 #9
0
def test_strategy_singleton():
    class A:
        pass

    injector = Injector()
    injector.provide(A, A, SINGLETON)

    assert isinstance(injector[A], A)
    assert injector[A] is injector[A]
    assert injector[A] is injector[A]
예제 #10
0
파일: benchmark.py 프로젝트: zozzz/yapic.di
def test_injector_injectable(benchmark):
    i = Injector()
    injectable = i.provide("PROVIDED", "PROVIDED", VALUE)

    benchmark.pedantic(lambda i: injectable(i),
                       args=(i, ),
                       iterations=10000,
                       rounds=100)

    assert injectable(i) == "PROVIDED"
예제 #11
0
def test_injectable_bind():
    injector = Injector()

    class A:
        pass

    injectable = injector.provide(A)
    bound = injectable.bind(injector)
    assert isinstance(bound, BoundInjectable)
    assert isinstance(bound(), A)
예제 #12
0
파일: benchmark.py 프로젝트: zozzz/yapic.di
def test_injector_getitem(benchmark):
    i = Injector()
    i.provide("PROVIDED", "PROVIDED", VALUE)

    benchmark.pedantic(lambda i: i["PROVIDED"],
                       args=(i, ),
                       iterations=10000,
                       rounds=100)

    assert i["PROVIDED"] == "PROVIDED"
예제 #13
0
def test_injector_exec_fn():
    injector = Injector()

    class A:
        pass

    def x(a: A):
        assert isinstance(a, A)
        return "OK"

    injector.provide(A)
    assert injector.exec(x) == "OK"
예제 #14
0
def test_injector_exec_cls():
    injector = Injector()

    class A:
        pass

    class B:
        def __init__(self, a: A):
            assert isinstance(a, A)

    injector.provide(A)
    assert isinstance(injector.exec(B), B)
예제 #15
0
def test_injectable_resolve_err():
    injector = Injector()

    class A:
        pass

    injectable = injector.provide(A)
    with pytest.raises(TypeError) as exc:
        injectable.resolve()
    exc.match("resolve\\(\\) takes exactly one argument \\(0 given\\)")

    with pytest.raises(TypeError) as exc:
        injectable.resolve(None)
    exc.match("Bad argument, must call with 'Injector' instance")
예제 #16
0
def test_own_provide(benchmark):
    class A:
        pass

    def fn(a: A):
        return a

    injector = Injector()
    injector.provide(fn, provide=[A])

    benchmark.pedantic(lambda i: injector.get(i),
                       args=(fn, ),
                       iterations=ITERS,
                       rounds=100)
예제 #17
0
def test_injector_own_kwonly():
    injector = Injector()

    class Config(dict):
        def __init__(self):
            super().__init__(some_key="OK")

    def get_kwarg(config: Config, *, name, type):
        assert name == "some_key"
        assert type is str
        return config[name]

    def fn(*, some_key: str):
        assert some_key == "OK"
        return "NICE"

    injector.provide(Config)
    injector.provide(fn, provide=[KwOnly(get_kwarg)])

    assert injector.get(fn) == "NICE"

    with pytest.raises(InjectError) as exc:
        assert injector.exec(fn) == "NICE"
    exc.match(
        "Not found suitable value for: <ValueResolver name=some_key id=<class 'str'>>"
    )
예제 #18
0
def test_value(benchmark):
    class A:
        pass

    injector = Injector()
    injector.provide("A", A, VALUE)

    def fn(id):
        return injector[id]

    benchmark.pedantic(lambda i: fn(i),
                       args=("A", ),
                       iterations=ITERS,
                       rounds=100)
예제 #19
0
def test_injectable_bind_err():
    injector = Injector()

    class A:
        pass

    injectable = injector.provide(A)
    with pytest.raises(TypeError) as exc:
        injectable.bind(None)
    exc.match("Bad argument, must call with 'Injector' instance")

    bound = injectable.bind(injector)
    with pytest.raises(TypeError) as exc:
        bound(None)
    exc.match("__call__ expected 0 arguments, got 1")
예제 #20
0
def test_cached_provide(benchmark):
    class A:
        pass

    def fn(a: A):
        return a

    injector = Injector()
    injector.provide(A)
    factory = injector.provide(fn).resolve

    benchmark.pedantic(lambda i: factory(i),
                       args=(injector, ),
                       iterations=ITERS,
                       rounds=100)
예제 #21
0
def test_class_with_type_annot():
    class B:
        pass

    class A:
        something: "Something"
        b: Inject[B]

    injector = Injector()
    injector.provide(A)
    injector.provide(B)

    a = injector[A]
    assert isinstance(a, A)
    assert isinstance(a.b, B)
    assert not hasattr(a, "something")
예제 #22
0
def test_params_wo_type():
    injector = Injector()
    r = Router()

    @r.on("/test/{any}")
    def action_any():
        return "any"

    @r.on("/test/{number:int}")
    def action_number():
        return "number"

    @r.on("/test/exact")
    def action_exact():
        return "exact"

    handler, params = r.find("/test/42", b"GET")
    assert handler(injector) == "number"
    assert params["number"] == 42

    handler, params = r.find("/test/something", b"GET")
    assert handler(injector) == "any"
    assert params["any"] == "something"

    handler, params = r.find("/test/exact", b"GET")
    assert handler(injector) == "exact"
    assert len(params) == 0
예제 #23
0
def test_injector_attribute():
    injector = Injector()

    class A:
        pass

    class B:
        a: Inject[A]

        def __init__(self):
            assert isinstance(self.a, A)

    injector.provide(A)

    b = injector.exec(B)
    assert isinstance(b, B)
    assert isinstance(b.a, A)
예제 #24
0
def test_injector_exec_object():
    BINST = "BInstance"

    injector = Injector()

    class A:
        pass

    class B:
        def __call__(self, a: A):
            assert isinstance(a, A)
            return "BBBB"

    def fn1(arg: B):
        assert isinstance(arg, B)
        return "fn1"

    def fn2(arg: BINST):
        assert arg == "BBBB"
        return "fn2"

    injector.provide(A)
    injector.provide(B)
    injector.provide(BINST, B())

    assert injector.exec(fn1) == "fn1"
    assert injector.exec(fn2) == "fn2"
예제 #25
0
def test_injectable_cached():
    injector = Injector()

    def test_fn():
        return "NICE"

    injectable = Injectable(test_fn)
    assert isinstance(injectable, Injectable)
    assert injectable(injector) == "NICE"
예제 #26
0
def test_injector_inject_self():
    injector = Injector()

    class A:
        inj: Inject[Injector]

        def __init__(self):
            assert isinstance(self.inj, Injector)
            assert isinstance(self.inj.get(B), B)

    class B:
        pass

    injector.provide(A)
    injector.provide(B)

    assert isinstance(injector.get(A), A)
    assert isinstance(injector[A], A)
예제 #27
0
def test_strategy_custom():
    cscope = dict()

    def custom_strategy(injectable, injector):
        try:
            return cscope[injectable]
        except KeyError:
            value = cscope[injectable] = injectable(injector)
            return value

    class A:
        pass

    injector = Injector()
    injector.provide(A, A, custom_strategy)

    assert isinstance(injector[A], A)
    assert injector[A] is injector[A]
예제 #28
0
def test_injector_setitem():
    class A:
        pass

    injector = Injector()
    injector[A] = A()

    def fn(a: A):
        assert isinstance(a, A)
        return "OK"

    assert injector.exec(fn) == "OK"

    del injector[A]

    with pytest.raises(InjectError) as exc:
        injector.exec(fn) == "OK"

    exc.match("Not found suitable value for")
예제 #29
0
def test_generic_param():
    T = TypeVar("T")

    class A(Generic[T]):
        b: Inject[T]

    class B:
        pass

    def fn(a: A[B]):
        assert isinstance(a, A)
        assert isinstance(a.b, B)
        return "OK"

    injector = Injector()
    injector.provide(A)
    injector.provide(B)

    assert injector.exec(fn) == "OK"
예제 #30
0
def test_injector_kwonly2():
    injector = Injector()

    class Config(dict):
        def __init__(self):
            super().__init__(some_key="OK")

        def __call__(self, *, name, type):
            assert name == "some_key"
            assert type is str
            return self[name]

    def fn(*, some_key: str):
        assert some_key == "OK"
        return "NICE"

    injector.provide(KwOnly(Config()))

    assert injector.exec(fn) == "NICE"