summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/changelog.rst1
-rw-r--r--factory/base.py16
-rw-r--r--factory/containers.py2
-rw-r--r--tests/test_containers.py11
-rw-r--r--tests/test_using.py49
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):