summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaphaël Barrois <raphael.barrois@polytechnique.org>2012-01-12 13:30:41 -0800
committerRaphaël Barrois <raphael.barrois@polytechnique.org>2012-01-12 13:30:41 -0800
commit74225f59761ed3e09b625d9886552bdafb0fc30d (patch)
tree03c9204a5425f5ec3413f69ea09d1ad835b12ac1
parent363fa7b470286f2b38ab33a7e986bfd000f25d86 (diff)
parent5bdc19ccbde3934a05b11a0d0edf50d3b31e930d (diff)
downloadfactory-boy-74225f59761ed3e09b625d9886552bdafb0fc30d.tar
factory-boy-74225f59761ed3e09b625d9886552bdafb0fc30d.tar.gz
Merge pull request #4 from carljm/allow-public-classmethods
Allow public classmethods/staticmethods on factories.
-rw-r--r--factory/containers.py23
-rw-r--r--tests/test_containers.py8
-rw-r--r--tests/test_using.py16
3 files changed, 42 insertions, 5 deletions
diff --git a/factory/containers.py b/factory/containers.py
index 4127851..497e98c 100644
--- a/factory/containers.py
+++ b/factory/containers.py
@@ -104,20 +104,35 @@ class LazyStub(object):
class DeclarationDict(dict):
"""Slightly extended dict to work with OrderedDeclaration."""
+ def is_declaration(self, name, value):
+ """Determines if a class attribute is a field value declaration.
+
+ Based on the name and value of the class attribute, return ``True`` if
+ it looks like a declaration of a default field value, ``False`` if it
+ is private (name starts with '_') or a classmethod or staticmethod.
+
+ """
+ if isinstance(value, (classmethod, staticmethod)):
+ return False
+ elif isinstance(value, declarations.OrderedDeclaration):
+ return True
+ return (not name.startswith("_"))
+
def update_with_public(self, d):
"""Updates the DeclarationDict from a class definition dict.
Takes into account all public attributes and OrderedDeclaration
- instances; ignores all attributes starting with '_'.
+ instances; ignores all class/staticmethods and private attributes
+ (starting with '_').
Returns a dict containing all remaining elements.
"""
remaining = {}
for k, v in d.iteritems():
- if k.startswith('_') and not isinstance(v, declarations.OrderedDeclaration):
- remaining[k] = v
- else:
+ if self.is_declaration(k, v):
self[k] = v
+ else:
+ remaining[k] = v
return remaining
def copy(self, extra=None):
diff --git a/tests/test_containers.py b/tests/test_containers.py
index 57c06cf..effb060 100644
--- a/tests/test_containers.py
+++ b/tests/test_containers.py
@@ -159,7 +159,13 @@ class DeclarationDictTestCase(unittest.TestCase):
def test_update_with_public(self):
d = containers.DeclarationDict()
- d.update_with_public({'one': 1, '_two': 2, 'three': 3})
+ d.update_with_public({
+ 'one': 1,
+ '_two': 2,
+ 'three': 3,
+ 'classmethod': classmethod(lambda c: 1),
+ 'staticmethod': staticmethod(lambda: 1),
+ })
self.assertEqual(set(['one', 'three']), set(d))
self.assertEqual(set([1, 3]), set(d.values()))
diff --git a/tests/test_using.py b/tests/test_using.py
index e0e59cd..d1e4262 100644
--- a/tests/test_using.py
+++ b/tests/test_using.py
@@ -280,6 +280,22 @@ class FactoryTestCase(unittest.TestCase):
test_object = TestModelFactory.create()
self.assertEqual(test_object, "This doesn't even return an instance of TestModel")
+ def testClassMethodAccessible(self):
+ class TestObjectFactory(factory.Factory):
+ @classmethod
+ def alt_create(cls, **kwargs):
+ return kwargs
+
+ self.assertEqual(TestObjectFactory.alt_create(foo=1), {"foo": 1})
+
+ def testStaticMethodAccessible(self):
+ class TestObjectFactory(factory.Factory):
+ @staticmethod
+ def alt_create(**kwargs):
+ return kwargs
+
+ self.assertEqual(TestObjectFactory.alt_create(foo=1), {"foo": 1})
+
class SubFactoryTestCase(unittest.TestCase):
def testSubFactory(self):