diff options
-rw-r--r-- | docs/changelog.rst | 1 | ||||
-rw-r--r-- | factory/base.py | 16 | ||||
-rw-r--r-- | factory/containers.py | 2 | ||||
-rw-r--r-- | tests/test_containers.py | 11 | ||||
-rw-r--r-- | tests/test_using.py | 49 |
5 files changed, 73 insertions, 6 deletions
diff --git a/docs/changelog.rst b/docs/changelog.rst index 5f25818..ffca40e 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -7,6 +7,7 @@ ChangeLog *New:* - Add :class:`~factory.CircularSubFactory` to solve circular dependencies between factories - Better creation/building customization hooks at :meth:`factory.Factory._build` and :meth:`factory.Factory.create`. + - Add support for passing non-kwarg parameters to a :class:`~factory.Factory` wrapped class. 1.1.5 (09/07/2012) ------------------ diff --git a/factory/base.py b/factory/base.py index 93aacde..a3d91b0 100644 --- a/factory/base.py +++ b/factory/base.py @@ -266,6 +266,9 @@ class BaseFactory(object): # class. _base_factory = None + # List of arguments that should be passed as *args instead of **kwargs + FACTORY_ARG_PARAMETERS = () + @classmethod def _setup_next_sequence(cls): """Set up an initial sequence value for Sequence attributes. @@ -334,7 +337,6 @@ class BaseFactory(object): args (tuple): arguments to use when building the class kwargs (dict): keyword arguments to use when building the class """ - return target_class(*args, **kwargs) @classmethod @@ -578,18 +580,22 @@ class Factory(BaseFactory): **kwargs: arguments to pass to the creation function """ target_class = getattr(cls, CLASS_ATTRIBUTE_ASSOCIATED_CLASS) + + # Extract *args from **kwargs + args = tuple(kwargs.pop(key) for key in cls.FACTORY_ARG_PARAMETERS) + if create: # Backwards compatibility creation_function = cls.get_creation_function() if creation_function: - return creation_function(target_class, **kwargs) - return cls._create(target_class, **kwargs) + return creation_function(target_class, *args, **kwargs) + return cls._create(target_class, *args, **kwargs) else: # Backwards compatibility building_function = cls.get_building_function() if building_function: - return building_function(target_class, **kwargs) - return cls._build(target_class, **kwargs) + return building_function(target_class, *args, **kwargs) + return cls._build(target_class, *args, **kwargs) @classmethod def _generate(cls, create, attrs): diff --git a/factory/containers.py b/factory/containers.py index 6834f60..d50cb71 100644 --- a/factory/containers.py +++ b/factory/containers.py @@ -124,7 +124,7 @@ class DeclarationDict(dict): return False elif isinstance(value, declarations.OrderedDeclaration): return True - return (not name.startswith("_")) + return (not name.startswith("_") and not name.startswith("FACTORY_")) def update_with_public(self, d): """Updates the DeclarationDict from a class definition dict. diff --git a/tests/test_containers.py b/tests/test_containers.py index 797c480..b1ed6ed 100644 --- a/tests/test_containers.py +++ b/tests/test_containers.py @@ -178,6 +178,17 @@ class DeclarationDictTestCase(unittest.TestCase): self.assertEqual(set(['one', 'three']), set(d)) self.assertEqual(set([1, 3]), set(d.values())) + def test_update_with_public_ignores_factory_attributes(self): + """Ensure that a DeclarationDict ignores FACTORY_ keys.""" + d = containers.DeclarationDict() + d.update_with_public({ + 'one': 1, + 'FACTORY_FOR': 2, + 'FACTORY_ARG_PARAMETERS': 3, + }) + self.assertEqual(['one'], list(d)) + self.assertEqual([1], list(d.values())) + class AttributeBuilderTestCase(unittest.TestCase): def test_empty(self): diff --git a/tests/test_using.py b/tests/test_using.py index 8620127..7e141eb 100644 --- a/tests/test_using.py +++ b/tests/test_using.py @@ -675,6 +675,55 @@ class UsingFactoryTestCase(unittest.TestCase): self.assertEqual(TestObjectFactory.alt_create(foo=1), {"foo": 1}) +class NonKwargParametersTestCase(unittest.TestCase): + def test_build(self): + class TestObject(object): + def __init__(self, *args, **kwargs): + self.args = args + self.kwargs = kwargs + + class TestObjectFactory(factory.Factory): + FACTORY_FOR = TestObject + FACTORY_ARG_PARAMETERS = ('one', 'two',) + + one = 1 + two = 2 + three = 3 + + obj = TestObjectFactory.build() + self.assertEqual((1, 2), obj.args) + self.assertEqual({'three': 3}, obj.kwargs) + + def test_create(self): + class TestObject(object): + def __init__(self, *args, **kwargs): + self.args = None + self.kwargs = None + + @classmethod + def create(cls, *args, **kwargs): + inst = cls() + inst.args = args + inst.kwargs = kwargs + return inst + + class TestObjectFactory(factory.Factory): + FACTORY_FOR = TestObject + FACTORY_ARG_PARAMETERS = ('one', 'two') + + one = 1 + two = 2 + three = 3 + + @classmethod + def _create(cls, target_class, *args, **kwargs): + return target_class.create(*args, **kwargs) + + obj = TestObjectFactory.create() + self.assertEqual((1, 2), obj.args) + self.assertEqual({'three': 3}, obj.kwargs) + + class SubFactoryTestCase(unittest.TestCase): def testSubFactory(self): class TestModel2(FakeModel): |