From 796e2bb3d133068b4e6c402efee4023d7f36b0e1 Mon Sep 17 00:00:00 2001 From: Roman Mogylatov Date: Sat, 30 Jan 2021 16:55:24 -0500 Subject: [PATCH] Add tests for callable provider --- src/dependency_injector/providers.c | 28 ++++++---- src/dependency_injector/providers.pyx | 2 +- tests/unit/providers/test_traversal_py3.py | 63 ++++++++++++++++++++++ 3 files changed, 81 insertions(+), 12 deletions(-) diff --git a/src/dependency_injector/providers.c b/src/dependency_injector/providers.c index c884851e..844ba1a8 100644 --- a/src/dependency_injector/providers.c +++ b/src/dependency_injector/providers.c @@ -4488,7 +4488,7 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_8Provider_28is_async_ static PyObject *__pyx_pf_19dependency_injector_9providers_8Provider_30is_async_mode_disabled(struct __pyx_obj_19dependency_injector_9providers_Provider *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_19dependency_injector_9providers_8Provider_32is_async_mode_undefined(struct __pyx_obj_19dependency_injector_9providers_Provider *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_19dependency_injector_9providers_8Provider_7related___get__(struct __pyx_obj_19dependency_injector_9providers_Provider *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_19dependency_injector_9providers_8Provider_34traverse(struct __pyx_obj_19dependency_injector_9providers_Provider *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v_types); /* proto */ +static PyObject *__pyx_pf_19dependency_injector_9providers_8Provider_34traverse(struct __pyx_obj_19dependency_injector_9providers_Provider *__pyx_v_self, PyObject *__pyx_v_types); /* proto */ static PyObject *__pyx_pf_19dependency_injector_9providers_8Provider_36_provide(struct __pyx_obj_19dependency_injector_9providers_Provider *__pyx_v_self, PyObject *__pyx_v_args, PyObject *__pyx_v_kwargs); /* proto */ static PyObject *__pyx_pf_19dependency_injector_9providers_8Provider_38_copy_overridings(struct __pyx_obj_19dependency_injector_9providers_Provider *__pyx_v_self, struct __pyx_obj_19dependency_injector_9providers_Provider *__pyx_v_copied, PyObject *__pyx_v_memo); /* proto */ static PyObject *__pyx_pf_19dependency_injector_9providers_8Provider_40__reduce_cython__(struct __pyx_obj_19dependency_injector_9providers_Provider *__pyx_v_self); /* proto */ @@ -9364,14 +9364,14 @@ static PyObject *__pyx_gb_19dependency_injector_9providers_8Provider_7related_2g * * def traverse(self, types=None): # <<<<<<<<<<<<<< * """Return providers traversal generator.""" - * return traverse(*self.related) + * return traverse(*self.related, types=types) */ /* Python wrapper */ static PyObject *__pyx_pw_19dependency_injector_9providers_8Provider_35traverse(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static char __pyx_doc_19dependency_injector_9providers_8Provider_34traverse[] = "Return providers traversal generator."; static PyObject *__pyx_pw_19dependency_injector_9providers_8Provider_35traverse(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - CYTHON_UNUSED PyObject *__pyx_v_types = 0; + PyObject *__pyx_v_types = 0; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; @@ -9427,12 +9427,13 @@ static PyObject *__pyx_pw_19dependency_injector_9providers_8Provider_35traverse( return __pyx_r; } -static PyObject *__pyx_pf_19dependency_injector_9providers_8Provider_34traverse(struct __pyx_obj_19dependency_injector_9providers_Provider *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v_types) { +static PyObject *__pyx_pf_19dependency_injector_9providers_8Provider_34traverse(struct __pyx_obj_19dependency_injector_9providers_Provider *__pyx_v_self, PyObject *__pyx_v_types) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; @@ -9441,7 +9442,7 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_8Provider_34traverse( /* "dependency_injector/providers.pyx":373 * def traverse(self, types=None): * """Return providers traversal generator.""" - * return traverse(*self.related) # <<<<<<<<<<<<<< + * return traverse(*self.related, types=types) # <<<<<<<<<<<<<< * * cpdef object _provide(self, tuple args, dict kwargs): */ @@ -9453,12 +9454,16 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_8Provider_34traverse( __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 373, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 373, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 373, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_types, __pyx_v_types) < 0) __PYX_ERR(1, 373, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 373, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; goto __pyx_L0; /* "dependency_injector/providers.pyx":371 @@ -9466,7 +9471,7 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_8Provider_34traverse( * * def traverse(self, types=None): # <<<<<<<<<<<<<< * """Return providers traversal generator.""" - * return traverse(*self.related) + * return traverse(*self.related, types=types) */ /* function exit code */ @@ -9474,6 +9479,7 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_8Provider_34traverse( __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("dependency_injector.providers.Provider.traverse", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; @@ -9483,7 +9489,7 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_8Provider_34traverse( } /* "dependency_injector/providers.pyx":375 - * return traverse(*self.related) + * return traverse(*self.related, types=types) * * cpdef object _provide(self, tuple args, dict kwargs): # <<<<<<<<<<<<<< * """Providing strategy implementation. @@ -9595,7 +9601,7 @@ static PyObject *__pyx_f_19dependency_injector_9providers_8Provider__provide(CYT __PYX_ERR(1, 382, __pyx_L1_error) /* "dependency_injector/providers.pyx":375 - * return traverse(*self.related) + * return traverse(*self.related, types=types) * * cpdef object _provide(self, tuple args, dict kwargs): # <<<<<<<<<<<<<< * """Providing strategy implementation. diff --git a/src/dependency_injector/providers.pyx b/src/dependency_injector/providers.pyx index d4c280cc..bac20a0e 100644 --- a/src/dependency_injector/providers.pyx +++ b/src/dependency_injector/providers.pyx @@ -370,7 +370,7 @@ cdef class Provider(object): def traverse(self, types=None): """Return providers traversal generator.""" - return traverse(*self.related) + return traverse(*self.related, types=types) cpdef object _provide(self, tuple args, dict kwargs): """Providing strategy implementation. diff --git a/tests/unit/providers/test_traversal_py3.py b/tests/unit/providers/test_traversal_py3.py index d41c78b1..209737bc 100644 --- a/tests/unit/providers/test_traversal_py3.py +++ b/tests/unit/providers/test_traversal_py3.py @@ -241,3 +241,66 @@ class DependenciesContainerTests(unittest.TestCase): self.assertIn(provider.provider1, all_providers) self.assertIn(provider.provider2, all_providers) + +class CallableTests(unittest.TestCase): + + def test_traverse(self): + provider = providers.Callable(dict) + all_providers = list(provider.traverse()) + self.assertEqual(len(all_providers), 0) + + def test_traverse_args(self): + provider1 = providers.Object('bar') + provider2 = providers.Object('baz') + provider = providers.Callable(list, 'foo', provider1, provider2) + + all_providers = list(provider.traverse()) + + self.assertEqual(len(all_providers), 2) + self.assertIn(provider1, all_providers) + self.assertIn(provider2, all_providers) + + def test_traverse_kwargs(self): + provider1 = providers.Object('bar') + provider2 = providers.Object('baz') + provider = providers.Callable(dict, foo='foo', bar=provider1, baz=provider2) + + all_providers = list(provider.traverse()) + + self.assertEqual(len(all_providers), 2) + self.assertIn(provider1, all_providers) + self.assertIn(provider2, all_providers) + + def test_traverse_overridden(self): + provider1 = providers.Object('bar') + provider2 = providers.Object('baz') + + provider = providers.Callable(dict, 'foo') + provider.override(provider1) + provider.override(provider2) + + all_providers = list(provider.traverse()) + + self.assertEqual(len(all_providers), 2) + self.assertIn(provider1, all_providers) + self.assertIn(provider2, all_providers) + + def test_traverse_provides(self): + provider1 = providers.Callable(list) + provider2 = providers.Object('bar') + provider3 = providers.Object('baz') + + provider = providers.Callable(provider1, provider2) + provider.override(provider3) + + all_providers = list(provider.traverse()) + + self.assertEqual(len(all_providers), 3) + self.assertIn(provider1, all_providers) + self.assertIn(provider2, all_providers) + self.assertIn(provider3, all_providers) + + +class ConfigurationOptionTests(unittest.TestCase): + # TODO: add tests + ...