def test_can_provide_class_without_own_init(self): class ExampleClassWithoutInit(object): pass obj_graph = object_graph.new_object_graph( modules=None, classes=[ExampleClassWithoutInit]) self.assertIsInstance(obj_graph.provide(ExampleClassWithoutInit), ExampleClassWithoutInit)
def test_can_provide_class_from_binding_name(self): class ExampleClass(object): pass obj_graph = object_graph.new_object_graph(modules=None, classes=[ExampleClass]) self.assertIsInstance(obj_graph.provide('example_class'), ExampleClass)
def test_all_parts_of_provide_decorator_are_used(self): class SomeClass(object): @decorators.annotate_arg('foo', 'specific-foo') @decorators.annotate_arg('bar', 'specific-bar') def __init__(self, foo, bar): self.foo = foo self.bar = bar class SomeBindingSpec(bindings.BindingSpec): @decorators.provides('foo', annotated_with='specific-foo', in_scope=scoping.SINGLETON) def provide_foo(self): return object() @decorators.provides('bar', annotated_with='specific-bar', in_scope=scoping.PROTOTYPE) def provide_bar(self): return object() obj_graph = object_graph.new_object_graph( modules=None, classes=[SomeClass], binding_specs=[SomeBindingSpec()]) class_one = obj_graph.provide(SomeClass) class_two = obj_graph.provide(SomeClass) self.assertIs(class_one, class_two)
def test_creates_object_graph_using_given_classes(self): class SomeClass(object): pass obj_graph = object_graph.new_object_graph(modules=None, classes=[SomeClass]) self.assertIsInstance(obj_graph.provide(SomeClass), SomeClass)
def test_allows_customizing_binding_spec_standard_method_names(self): class BindingSpecOne(bindings.BindingSpec): def Configure(self, bind): bind('foo', to_instance='a-foo') def Dependencies(self): return [] class BindingSpecTwo(bindings.BindingSpec): def Configure(self, bind): pass def Dependencies(self): return [BindingSpecOne()] class SomeClass(object): def __init__(self, foo): self.foo = foo obj_graph = object_graph.new_object_graph( modules=None, classes=[SomeClass], binding_specs=[BindingSpecTwo()], configure_method_name='Configure', dependencies_method_name='Dependencies') some_class = obj_graph.provide(SomeClass) self.assertEqual('a-foo', some_class.foo)
def test_allows_dag_binding_spec_dependencies(self): class CommonBindingSpec(bindings.BindingSpec): def configure(self, bind): bind('foo', to_instance='a-foo') class BindingSpecOne(bindings.BindingSpec): def dependencies(self): return [CommonBindingSpec()] class BindingSpecTwo(bindings.BindingSpec): def dependencies(self): return [CommonBindingSpec()] class RootBindingSpec(bindings.BindingSpec): def dependencies(self): return [BindingSpecOne(), BindingSpecTwo()] class SomeClass(object): def __init__(self, foo): self.foo = foo obj_graph = object_graph.new_object_graph( modules=None, classes=[SomeClass], binding_specs=[RootBindingSpec()]) some_class = obj_graph.provide(SomeClass) self.assertEqual('a-foo', some_class.foo)
def test_raises_exception_if_trying_to_provide_invalid_arg(self): class SomeClass(object): pass obj_graph = object_graph.new_object_graph(modules=None, classes=[SomeClass]) self.assertRaises(errors.WrongArgTypeError, obj_graph.provide, 42)
def test_raises_error_if_arg_refers_to_no_known_class(self): class UnknownParamClass(object): def __init__(self, unknown_class): pass obj_graph = object_graph.new_object_graph( modules=None, classes=[UnknownParamClass]) self.assertRaises(errors.NothingInjectableForArgError, obj_graph.provide, UnknownParamClass)
def test_can_provide_trivial_class(self): class ExampleClassWithInit(object): def __init__(self): pass obj_graph = object_graph.new_object_graph( modules=None, classes=[ExampleClassWithInit]) self.assertTrue(isinstance(obj_graph.provide(ExampleClassWithInit), ExampleClassWithInit))
def print_non_explicitly_bound_class_error(): class ImplicitlyBoundClass(object): pass obj_graph = object_graph.new_object_graph( modules=None, classes=[ImplicitlyBoundClass], only_use_explicit_bindings=True) _print_raised_exception( errors.NonExplicitlyBoundClassError, obj_graph.provide, ImplicitlyBoundClass)
def test_non_explicitly_injectable_class_cannot_be_directly_provided(self): class SomeClass(object): def __init__(self): self.foo = 'a-foo' obj_graph = object_graph.new_object_graph( modules=None, classes=[SomeClass], only_use_explicit_bindings=True) self.assertRaises( errors.NonExplicitlyBoundClassError, obj_graph.provide, SomeClass)
def print_nothing_injectable_for_arg_error(): class UnknownParamClass(object): def __init__(self, unknown_class): pass obj_graph = object_graph.new_object_graph( modules=None, classes=[UnknownParamClass]) _print_raised_exception(errors.NothingInjectableForArgError, obj_graph.provide, UnknownParamClass)
def test_non_inject_decorated_class_cannot_be_directly_provided(self): class SomeClass(object): def __init__(self): self.foo = 'a-foo' obj_graph = object_graph.new_object_graph( modules=None, classes=[SomeClass], only_use_explicit_bindings=True) self.assertRaises( errors.NonExplicitlyBoundClassError, obj_graph.provide, SomeClass)
def test_can_inject_something_into_first_positional_param(self): class Foo(object): def __init__(self): self.a = 2 def add(foo, b): return foo.a + b wrapped = object_graph.new_object_graph(modules=None, classes=[Foo]).wrap(add) self.assertEqual(5, wrapped(b=3))
def test_can_inject_something_into_non_first_positional_param(self): class Foo(object): def __init__(self): self.b = 3 def add(a, foo): return a + foo.b wrapped = object_graph.new_object_graph(modules=None, classes=[Foo]).wrap(add) self.assertEqual(5, wrapped(2))
def test_singleton_classes_are_singletons_when_provided_from_class(self): class SomeClass(object): pass obj_graph = object_graph.new_object_graph(modules=None, classes=[SomeClass]) self.assertIs(obj_graph.provide(SomeClass), obj_graph.provide(SomeClass))
def test_inject_decorated_class_can_be_directly_provided(self): class SomeClass(object): @decorators.inject() def __init__(self): self.foo = 'a-foo' obj_graph = object_graph.new_object_graph( modules=None, classes=[SomeClass], only_use_explicit_bindings=True) class_one = obj_graph.provide(SomeClass) self.assertEqual('a-foo', class_one.foo)
def test_can_provide_class_that_itself_requires_injection(self): class ClassOne(object): def __init__(self, class_two): pass class ClassTwo(object): pass obj_graph = object_graph.new_object_graph( modules=None, classes=[ClassOne, ClassTwo]) self.assertIsInstance(obj_graph.provide(ClassOne), ClassOne)
def test_inject_decorated_class_can_be_directly_provided(self): class SomeClass(object): @decorators.injectable def __init__(self): self.foo = 'a-foo' obj_graph = object_graph.new_object_graph( modules=None, classes=[SomeClass], only_use_explicit_bindings=True) class_one = obj_graph.provide(SomeClass) self.assertEqual('a-foo', class_one.foo)
def test_can_directly_provide_class_with_colliding_arg_name(self): class _CollidingExampleClass(object): pass class CollidingExampleClass(object): pass obj_graph = object_graph.new_object_graph( modules=None, classes=[_CollidingExampleClass, CollidingExampleClass]) self.assertIsInstance(obj_graph.provide(CollidingExampleClass), CollidingExampleClass)
def print_bad_dependency_scope_error(): class Foo(object): pass class Bar(object): def __init__(self, foo): pass obj_graph = object_graph.new_object_graph( classes=[Foo, Bar], is_scope_usable_from_scope=lambda _1, _2: False) _print_raised_exception(errors.BadDependencyScopeError, obj_graph.provide, Bar)
def test_can_provide_using_provider_fn(self): class ClassOne(object): def __init__(self, foo): self.foo = foo class SomeBindingSpec(bindings.BindingSpec): def provide_foo(self): return 'a-foo' obj_graph = object_graph.new_object_graph( modules=None, classes=[ClassOne], binding_specs=[SomeBindingSpec()]) class_one = obj_graph.provide(ClassOne) self.assertEqual('a-foo', class_one.foo)
def print_bad_dependency_scope_error(): class Foo(object): pass class Bar(object): def __init__(self, foo): pass obj_graph = object_graph.new_object_graph( modules=None, classes=[Foo, Bar], is_scope_usable_from_scope=lambda _1, _2: False) _print_raised_exception(errors.BadDependencyScopeError, obj_graph.provide, Bar)
def test_raises_error_if_injection_cycle(self): class ClassOne(object): def __init__(self, class_two): pass class ClassTwo(object): def __init__(self, class_one): pass obj_graph = object_graph.new_object_graph( modules=None, classes=[ClassOne, ClassTwo]) self.assertRaises(errors.CyclicInjectionError, obj_graph.provide, ClassOne)
def test_injects_provider_fn_if_so_named(self): class ClassOne(object): def __init__(self): self.forty_two = 42 class ClassTwo(object): def __init__(self, provide_class_one): self.provide_class_one = provide_class_one obj_graph = object_graph.new_object_graph( modules=None, classes=[ClassOne, ClassTwo]) class_two = obj_graph.provide(ClassTwo) self.assertEqual(42, class_two.provide_class_one().forty_two)
def test_cannot_pass_non_existent_args_to_provider_fn_for_instance(self): class SomeBindingSpec(bindings.BindingSpec): def configure(self, bind): bind('foo', to_instance='a-foo') class SomeClass(object): def __init__(self, provide_foo): self.foo = provide_foo(non_existent=42) obj_graph = object_graph.new_object_graph( modules=None, classes=[SomeClass], binding_specs=[SomeBindingSpec()]) self.assertRaises(TypeError, obj_graph.provide, SomeClass)
def print_ambiguous_arg_name_error(): class SomeClass(): def __init__(self, foo): pass class Foo(): pass class _Foo(): pass obj_graph = object_graph.new_object_graph(classes=[SomeClass, Foo, _Foo]) _print_raised_exception(errors.AmbiguousArgNameError, obj_graph.provide, SomeClass)
def test_cannot_inject_none_when_disallowing_injecting_none(self): class SomeClass(object): def __init__(self, foo): self.foo = foo class SomeBindingSpec(bindings.BindingSpec): def provide_foo(self): return None obj_graph = object_graph.new_object_graph( modules=None, classes=[SomeClass], binding_specs=[SomeBindingSpec()], allow_injecting_none=False) self.assertRaises(errors.InjectingNoneDisallowedError, obj_graph.provide, SomeClass)
def test_raises_error_if_only_binding_has_no_annotation(self): class ClassOne(object): @decorators.annotate_arg('foo', 'an-annotation') def __init__(self, foo): self.foo = foo class SomeBindingSpec(bindings.BindingSpec): def configure(self, bind): bind('foo', to_instance='a-foo') obj_graph = object_graph.new_object_graph( modules=None, classes=[ClassOne], binding_specs=[SomeBindingSpec()]) self.assertRaises(errors.NothingInjectableForArgError, obj_graph.provide, ClassOne)
def test_can_provide_arg_with_annotation(self): class ClassOne(object): @decorators.annotate_arg('foo', 'an-annotation') def __init__(self, foo): self.foo = foo class SomeBindingSpec(bindings.BindingSpec): def configure(self, bind): bind('foo', annotated_with='an-annotation', to_instance='a-foo') obj_graph = object_graph.new_object_graph( modules=None, classes=[ClassOne], binding_specs=[SomeBindingSpec()]) class_one = obj_graph.provide(ClassOne) self.assertEqual('a-foo', class_one.foo)
def print_injecting_none_disallowed_error(): class SomeClass(object): def __init__(self, foo): self.foo = foo class SomeBindingSpec(bindings.BindingSpec): def provide_foo(self): return None obj_graph = object_graph.new_object_graph( modules=None, classes=[SomeClass], binding_specs=[SomeBindingSpec()], allow_injecting_none=False) _print_raised_exception(errors.InjectingNoneDisallowedError, obj_graph.provide, SomeClass)
def test_can_not_directly_provide_class_with_colliding_arg_name(self): class _CollidingExampleClass(object): pass class CollidingExampleClass(object): pass obj_graph = object_graph.new_object_graph( modules=None, classes=[_CollidingExampleClass, CollidingExampleClass]) self.assertRaises(errors.AmbiguousArgNameError, obj_graph.provide, CollidingExampleClass)
def print_ambiguous_arg_name_error(): class SomeClass(object): def __init__(self, foo): pass class Foo(object): pass class _Foo(object): pass obj_graph = object_graph.new_object_graph( modules=None, classes=[SomeClass, Foo, _Foo]) _print_raised_exception(errors.AmbiguousArgNameError, obj_graph.provide, SomeClass)
def test_raises_error_if_provide_from_class_cannot_be_resolved(self): class SomeClass(object): pass class SomeBindingSpec(bindings.BindingSpec): def configure(self, bind): bind('foo', to_class=SomeClass) obj_graph = object_graph.new_object_graph( modules=None, classes=None, binding_specs=[SomeBindingSpec()]) self.assertRaises(errors.NothingInjectableForArgError, obj_graph.provide, SomeClass)
def test_can_inject_none_when_allowing_injecting_none(self): class SomeClass(object): def __init__(self, foo): self.foo = foo class SomeBindingSpec(bindings.BindingSpec): def provide_foo(self): return None obj_graph = object_graph.new_object_graph( modules=None, classes=[SomeClass], binding_specs=[SomeBindingSpec()], allow_injecting_none=True) some_class = obj_graph.provide(SomeClass) self.assertIsNone(some_class.foo)
def test_autoinjects_args_of_provider_fn(self): class ClassOne(object): def __init__(self, foo): self.foo = foo class SomeBindingSpec(bindings.BindingSpec): def provide_foo(self, bar): return 'a-foo with {0}'.format(bar) def provide_bar(self): return 'a-bar' obj_graph = object_graph.new_object_graph( modules=None, classes=[ClassOne], binding_specs=[SomeBindingSpec()]) class_one = obj_graph.provide(ClassOne) self.assertEqual('a-foo with a-bar', class_one.foo)
def test_non_bound_non_decorated_class_is_not_explicitly_bound(self): class ClassOne(object): @decorators.injectable def __init__(self, class_two): self.class_two = class_two class ClassTwo(object): def __init__(self): self.foo = 'a-foo' obj_graph = object_graph.new_object_graph( modules=None, classes=[ClassOne, ClassTwo], only_use_explicit_bindings=True) self.assertRaises(errors.NothingInjectableForArgError, obj_graph.provide, ClassOne)
def test_explicit_binding_is_explicitly_bound(self): class ClassOne(object): @decorators.injectable def __init__(self, class_two): self.class_two = class_two class SomeBindingSpec(bindings.BindingSpec): def configure(self, bind): bind('class_two', to_instance='a-class-two') obj_graph = object_graph.new_object_graph( modules=None, classes=[ClassOne], binding_specs=[SomeBindingSpec()], only_use_explicit_bindings=True) class_one = obj_graph.provide(ClassOne) self.assertEqual('a-class-two', class_one.class_two)
def test_provider_fn_is_explicitly_bound(self): class ClassOne(object): @decorators.injectable def __init__(self, class_two): self.class_two = class_two class SomeBindingSpec(bindings.BindingSpec): def provide_class_two(self): return 'a-class-two' obj_graph = object_graph.new_object_graph( modules=None, classes=[ClassOne], binding_specs=[SomeBindingSpec()], only_use_explicit_bindings=True) class_one = obj_graph.provide(ClassOne) self.assertEqual('a-class-two', class_one.class_two)
def test_allows_binding_spec_with_only_provider_methods(self): class ClassWithFooInjected(object): def __init__(self, foo): self.foo = foo class SomeBindingSpec(bindings.BindingSpec): def provide_foo(self): return 'a-foo' obj_graph = object_graph.new_object_graph( modules=None, classes=[ClassWithFooInjected], binding_specs=[SomeBindingSpec()], configure_method_name='Configure', dependencies_method_name='Dependencies') self.assertEqual('a-foo', obj_graph.provide(ClassWithFooInjected).foo)
def test_creates_object_graph_using_given_binding_specs(self): class ClassWithFooInjected(object): def __init__(self, foo): pass class SomeClass(object): pass class SomeBindingSpec(bindings.BindingSpec): def configure(self, bind): bind('foo', to_class=SomeClass) obj_graph = object_graph.new_object_graph( modules=None, classes=[ClassWithFooInjected], binding_specs=[SomeBindingSpec()]) self.assertIsInstance(obj_graph.provide(ClassWithFooInjected), ClassWithFooInjected)
def print_cyclic_injection_error(): class ClassOne(object): def __init__(self, class_two): pass class ClassTwo(object): def __init__(self, class_three): pass class ClassThree(object): def __init__(self, class_one): pass obj_graph = object_graph.new_object_graph( modules=None, classes=[ClassOne, ClassTwo, ClassThree]) _print_raised_exception(errors.CyclicInjectionError, obj_graph.provide, ClassOne)
def print_directly_passing_injected_args_error(): class SomeBindingSpec(bindings.BindingSpec): def provide_foo(self, injected): return 'unused' def configure(self, bind): bind('injected', to_instance=2) class SomeClass(object): def __init__(self, provide_foo): provide_foo(injected=40) obj_graph = object_graph.new_object_graph( modules=None, classes=[SomeClass], binding_specs=[SomeBindingSpec()]) _print_raised_exception(errors.DirectlyPassingInjectedArgsError, obj_graph.provide, SomeClass)