aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorChristopher Baines <mail@cbaines.net>2016-05-11 09:49:51 +0100
committerChristopher Baines <mail@cbaines.net>2016-05-11 09:49:51 +0100
commitd54b452452a04f8109ef8dc48c9b46d1cb99f476 (patch)
treea31e97328932c485d80e3be808c9e3572d955c39 /tests
parent36ef8928c06a4bba5249442cd832a73ece1570c3 (diff)
parentf1ed74e06dfb6851bc691ebfd8135c875154ad50 (diff)
downloadfactory-boy-d54b452452a04f8109ef8dc48c9b46d1cb99f476.tar
factory-boy-d54b452452a04f8109ef8dc48c9b46d1cb99f476.tar.gz
Merge tag 'v2.7.0' into debian/unstable
Release of factory_boy 2.7.0
Diffstat (limited to 'tests')
-rw-r--r--tests/test_base.py22
-rw-r--r--tests/test_containers.py163
-rw-r--r--tests/test_django.py16
-rw-r--r--tests/test_using.py156
4 files changed, 251 insertions, 106 deletions
diff --git a/tests/test_base.py b/tests/test_base.py
index 24f64e5..a3b3704 100644
--- a/tests/test_base.py
+++ b/tests/test_base.py
@@ -24,6 +24,7 @@ import warnings
from factory import base
from factory import declarations
+from factory import errors
from .compat import unittest
@@ -63,7 +64,7 @@ class TestModel(FakeDjangoModel):
class SafetyTestCase(unittest.TestCase):
def test_base_factory(self):
- self.assertRaises(base.FactoryError, base.BaseFactory)
+ self.assertRaises(errors.FactoryError, base.BaseFactory)
class AbstractFactoryTestCase(unittest.TestCase):
@@ -88,8 +89,8 @@ class AbstractFactoryTestCase(unittest.TestCase):
class TestObjectFactory(base.Factory):
pass
- self.assertRaises(base.FactoryError, TestObjectFactory.build)
- self.assertRaises(base.FactoryError, TestObjectFactory.create)
+ self.assertRaises(errors.FactoryError, TestObjectFactory.build)
+ self.assertRaises(errors.FactoryError, TestObjectFactory.create)
def test_abstract_factory_not_inherited(self):
"""abstract=True isn't propagated to child classes."""
@@ -110,8 +111,8 @@ class AbstractFactoryTestCase(unittest.TestCase):
abstract = False
model = None
- self.assertRaises(base.FactoryError, TestObjectFactory.build)
- self.assertRaises(base.FactoryError, TestObjectFactory.create)
+ self.assertRaises(errors.FactoryError, TestObjectFactory.build)
+ self.assertRaises(errors.FactoryError, TestObjectFactory.create)
class OptionsTests(unittest.TestCase):
@@ -134,25 +135,28 @@ class OptionsTests(unittest.TestCase):
self.assertEqual(AbstractFactory, AbstractFactory._meta.counter_reference)
def test_declaration_collecting(self):
- lazy = declarations.LazyAttribute(lambda _o: 1)
+ lazy = declarations.LazyFunction(int)
+ lazy2 = declarations.LazyAttribute(lambda _o: 1)
postgen = declarations.PostGenerationDeclaration()
class AbstractFactory(base.Factory):
x = 1
y = lazy
+ y2 = lazy2
z = postgen
# Declarations aren't removed
self.assertEqual(1, AbstractFactory.x)
self.assertEqual(lazy, AbstractFactory.y)
+ self.assertEqual(lazy2, AbstractFactory.y2)
self.assertEqual(postgen, AbstractFactory.z)
# And are available in class Meta
- self.assertEqual({'x': 1, 'y': lazy}, AbstractFactory._meta.declarations)
+ self.assertEqual({'x': 1, 'y': lazy, 'y2': lazy2}, AbstractFactory._meta.declarations)
self.assertEqual({'z': postgen}, AbstractFactory._meta.postgen_declarations)
def test_inherited_declaration_collecting(self):
- lazy = declarations.LazyAttribute(lambda _o: 1)
+ lazy = declarations.LazyFunction(int)
lazy2 = declarations.LazyAttribute(lambda _o: 2)
postgen = declarations.PostGenerationDeclaration()
postgen2 = declarations.PostGenerationDeclaration()
@@ -178,7 +182,7 @@ class OptionsTests(unittest.TestCase):
self.assertEqual({'z': postgen, 'b': postgen2}, OtherFactory._meta.postgen_declarations)
def test_inherited_declaration_shadowing(self):
- lazy = declarations.LazyAttribute(lambda _o: 1)
+ lazy = declarations.LazyFunction(int)
lazy2 = declarations.LazyAttribute(lambda _o: 2)
postgen = declarations.PostGenerationDeclaration()
postgen2 = declarations.PostGenerationDeclaration()
diff --git a/tests/test_containers.py b/tests/test_containers.py
index 083b306..1b87b2e 100644
--- a/tests/test_containers.py
+++ b/tests/test_containers.py
@@ -23,6 +23,7 @@
from factory import base
from factory import containers
from factory import declarations
+from factory import errors
from .compat import unittest
@@ -78,17 +79,39 @@ class LazyStubTestCase(unittest.TestCase):
self.assertEqual(2, stub.factory_parent.rank)
self.assertEqual(1, stub.factory_parent.factory_parent.rank)
- def test_cyclic_definition(self):
- class LazyAttr(containers.LazyValue):
- def __init__(self, attrname):
- self.attrname = attrname
+ class LazyAttr(containers.LazyValue):
+ def __init__(self, attrname):
+ self.attrname = attrname
+
+ def evaluate(self, obj, container=None):
+ return 1 + getattr(obj, self.attrname)
+ def test_cyclic_definition(self):
+ stub = containers.LazyStub({
+ 'one': self.LazyAttr('two'),
+ 'two': self.LazyAttr('one'),
+ })
+
+ self.assertRaises(errors.CyclicDefinitionError, getattr, stub, 'one')
+
+ def test_cyclic_definition_rescue(self):
+ class LazyAttrDefault(self.LazyAttr):
+ def __init__(self, attname, defvalue):
+ super(LazyAttrDefault, self).__init__(attname)
+ self.defvalue = defvalue
def evaluate(self, obj, container=None):
- return 1 + getattr(obj, self.attrname)
+ try:
+ return super(LazyAttrDefault, self).evaluate(obj, container)
+ except errors.CyclicDefinitionError:
+ return self.defvalue
- stub = containers.LazyStub({'one': LazyAttr('two'), 'two': LazyAttr('one')})
+ stub = containers.LazyStub({
+ 'one': LazyAttrDefault('two', 10),
+ 'two': self.LazyAttr('one'),
+ })
- self.assertRaises(containers.CyclicDefinitionError, getattr, stub, 'one')
+ self.assertEqual(10, stub.one)
+ self.assertEqual(11, stub.two)
def test_representation(self):
class RandomObj(object):
@@ -102,97 +125,56 @@ class LazyStubTestCase(unittest.TestCase):
class AttributeBuilderTestCase(unittest.TestCase):
- def test_empty(self):
- """Tests building attributes from an empty definition."""
+
+ def make_fake_factory(self, decls):
+ class Meta:
+ declarations = decls
+ parameters = {}
+ parameters_dependencies = {}
class FakeFactory(object):
- @classmethod
- def declarations(cls, extra):
- return extra
+ _meta = Meta
@classmethod
def _generate_next_sequence(cls):
return 1
+ return FakeFactory
+
+ def test_empty(self):
+ """Tests building attributes from an empty definition."""
+
+ FakeFactory = self.make_fake_factory({})
ab = containers.AttributeBuilder(FakeFactory)
self.assertEqual({}, ab.build(create=False))
def test_factory_defined(self):
- class FakeFactory(object):
- @classmethod
- def declarations(cls, extra):
- d = {'one': 1}
- d.update(extra)
- return d
-
- @classmethod
- def _generate_next_sequence(cls):
- return 1
-
+ FakeFactory = self.make_fake_factory({'one': 1})
ab = containers.AttributeBuilder(FakeFactory)
+
self.assertEqual({'one': 1}, ab.build(create=False))
def test_extended(self):
- class FakeFactory(object):
- @classmethod
- def declarations(cls, extra):
- d = {'one': 1}
- d.update(extra)
- return d
-
- @classmethod
- def _generate_next_sequence(cls):
- return 1
-
+ FakeFactory = self.make_fake_factory({'one': 1})
ab = containers.AttributeBuilder(FakeFactory, {'two': 2})
self.assertEqual({'one': 1, 'two': 2}, ab.build(create=False))
def test_overridden(self):
- class FakeFactory(object):
- @classmethod
- def declarations(cls, extra):
- d = {'one': 1}
- d.update(extra)
- return d
-
- @classmethod
- def _generate_next_sequence(cls):
- return 1
-
+ FakeFactory = self.make_fake_factory({'one': 1})
ab = containers.AttributeBuilder(FakeFactory, {'one': 2})
self.assertEqual({'one': 2}, ab.build(create=False))
def test_factory_defined_sequence(self):
seq = declarations.Sequence(lambda n: 'xx%d' % n)
-
- class FakeFactory(object):
- @classmethod
- def declarations(cls, extra):
- d = {'one': seq}
- d.update(extra)
- return d
-
- @classmethod
- def _generate_next_sequence(cls):
- return 1
+ FakeFactory = self.make_fake_factory({'one': seq})
ab = containers.AttributeBuilder(FakeFactory)
self.assertEqual({'one': 'xx1'}, ab.build(create=False))
def test_additionnal_sequence(self):
seq = declarations.Sequence(lambda n: 'xx%d' % n)
-
- class FakeFactory(object):
- @classmethod
- def declarations(cls, extra):
- d = {'one': 1}
- d.update(extra)
- return d
-
- @classmethod
- def _generate_next_sequence(cls):
- return 1
+ FakeFactory = self.make_fake_factory({'one': 1})
ab = containers.AttributeBuilder(FakeFactory, extra={'two': seq})
self.assertEqual({'one': 1, 'two': 'xx1'}, ab.build(create=False))
@@ -200,34 +182,27 @@ class AttributeBuilderTestCase(unittest.TestCase):
def test_replaced_sequence(self):
seq = declarations.Sequence(lambda n: 'xx%d' % n)
seq2 = declarations.Sequence(lambda n: 'yy%d' % n)
-
- class FakeFactory(object):
- @classmethod
- def declarations(cls, extra):
- d = {'one': seq}
- d.update(extra)
- return d
-
- @classmethod
- def _generate_next_sequence(cls):
- return 1
+ FakeFactory = self.make_fake_factory({'one': seq})
ab = containers.AttributeBuilder(FakeFactory, extra={'one': seq2})
self.assertEqual({'one': 'yy1'}, ab.build(create=False))
- def test_lazy_attribute(self):
- la = declarations.LazyAttribute(lambda a: a.one * 2)
+ def test_lazy_function(self):
+ lf = declarations.LazyFunction(int)
+ FakeFactory = self.make_fake_factory({'one': 1, 'two': lf})
- class FakeFactory(object):
- @classmethod
- def declarations(cls, extra):
- d = {'one': 1, 'two': la}
- d.update(extra)
- return d
+ ab = containers.AttributeBuilder(FakeFactory)
+ self.assertEqual({'one': 1, 'two': 0}, ab.build(create=False))
- @classmethod
- def _generate_next_sequence(cls):
- return 1
+ ab = containers.AttributeBuilder(FakeFactory, {'one': 4})
+ self.assertEqual({'one': 4, 'two': 0}, ab.build(create=False))
+
+ ab = containers.AttributeBuilder(FakeFactory, {'one': 4, 'three': lf})
+ self.assertEqual({'one': 4, 'two': 0, 'three': 0}, ab.build(create=False))
+
+ def test_lazy_attribute(self):
+ la = declarations.LazyAttribute(lambda a: a.one * 2)
+ FakeFactory = self.make_fake_factory({'one': 1, 'two': la})
ab = containers.AttributeBuilder(FakeFactory)
self.assertEqual({'one': 1, 'two': 2}, ab.build(create=False))
@@ -243,18 +218,12 @@ class AttributeBuilderTestCase(unittest.TestCase):
pass
sf = declarations.SubFactory(FakeInnerFactory)
-
- class FakeFactory(object):
- @classmethod
- def declarations(cls, extra):
- d = {'one': sf, 'two': 2}
- d.update(extra)
- return d
+ FakeFactory = self.make_fake_factory({'one': sf, 'two': 2})
ab = containers.AttributeBuilder(FakeFactory, {'one__blah': 1, 'two__bar': 2})
self.assertTrue(ab.has_subfields(sf))
self.assertEqual(['one'], list(ab._subfields.keys()))
- self.assertEqual(2, ab._attrs['two__bar'])
+ self.assertEqual(2, ab._declarations['two__bar'])
def test_sub_factory(self):
pass
diff --git a/tests/test_django.py b/tests/test_django.py
index 103df91..08349b9 100644
--- a/tests/test_django.py
+++ b/tests/test_django.py
@@ -362,6 +362,22 @@ class DjangoAbstractBaseSequenceTestCase(django_test.TestCase):
obj = ConcreteGrandSonFactory()
self.assertEqual(1, obj.pk)
+ def test_optional_abstract(self):
+ """Users need not describe the factory for an abstract model as abstract."""
+ class AbstractBaseFactory(factory.django.DjangoModelFactory):
+ class Meta:
+ model = models.AbstractBase
+
+ foo = factory.Sequence(lambda n: "foo%d" % n)
+
+ class ConcreteSonFactory(AbstractBaseFactory):
+ class Meta:
+ model = models.ConcreteSon
+
+ obj = ConcreteSonFactory()
+ self.assertEqual(1, obj.pk)
+ self.assertEqual("foo0", obj.foo)
+
@unittest.skipIf(django is None, "Django not installed.")
class DjangoRelatedFieldTestCase(django_test.TestCase):
diff --git a/tests/test_using.py b/tests/test_using.py
index 0a893c1..0ce29e9 100644
--- a/tests/test_using.py
+++ b/tests/test_using.py
@@ -27,6 +27,7 @@ import sys
import warnings
import factory
+from factory import errors
from .compat import is_python2, unittest
from . import tools
@@ -40,6 +41,15 @@ class TestObject(object):
self.four = four
self.five = five
+ def as_dict(self):
+ return dict(
+ one=self.one,
+ two=self.two,
+ three=self.three,
+ four=self.four,
+ five=self.five,
+ )
+
class FakeModel(object):
@classmethod
@@ -292,6 +302,19 @@ class SimpleBuildTestCase(unittest.TestCase):
self.assertEqual(obj.three, 5)
self.assertEqual(obj.four, None)
+ def test_build_to_dict(self):
+ # We have a generic factory
+ class TestObjectFactory(factory.Factory):
+ class Meta:
+ model = TestObject
+
+ one = 'one'
+ two = factory.LazyAttribute(lambda o: o.one * 2)
+
+ # Now, get a dict out of it
+ obj = factory.build(dict, FACTORY_CLASS=TestObjectFactory)
+ self.assertEqual({'one': 'one', 'two': 'oneone'}, obj)
+
class UsingFactoryTestCase(unittest.TestCase):
def test_attribute(self):
@@ -1092,6 +1115,119 @@ class KwargAdjustTestCase(unittest.TestCase):
self.assertEqual(42, obj.attributes)
+class TraitTestCase(unittest.TestCase):
+ def test_traits(self):
+ class TestObjectFactory(factory.Factory):
+ class Meta:
+ model = TestObject
+
+ class Params:
+ even = factory.Trait(two=True, four=True)
+ odd = factory.Trait(one=True, three=True, five=True)
+
+ obj1 = TestObjectFactory()
+ self.assertEqual(obj1.as_dict(),
+ dict(one=None, two=None, three=None, four=None, five=None))
+
+ obj2 = TestObjectFactory(even=True)
+ self.assertEqual(obj2.as_dict(),
+ dict(one=None, two=True, three=None, four=True, five=None))
+
+ obj3 = TestObjectFactory(odd=True)
+ self.assertEqual(obj3.as_dict(),
+ dict(one=True, two=None, three=True, four=None, five=True))
+
+ obj4 = TestObjectFactory(even=True, odd=True)
+ self.assertEqual(obj4.as_dict(),
+ dict(one=True, two=True, three=True, four=True, five=True))
+
+ obj5 = TestObjectFactory(odd=True, two=True)
+ self.assertEqual(obj5.as_dict(),
+ dict(one=True, two=True, three=True, four=None, five=True))
+
+ def test_traits_inheritance(self):
+ """A trait can be set in an inherited class."""
+ class TestObjectFactory(factory.Factory):
+ class Meta:
+ model = TestObject
+
+ class Params:
+ even = factory.Trait(two=True, four=True)
+ odd = factory.Trait(one=True, three=True, five=True)
+
+ class EvenObjectFactory(TestObjectFactory):
+ even = True
+
+ # Simple call
+ obj1 = EvenObjectFactory()
+ self.assertEqual(obj1.as_dict(),
+ dict(one=None, two=True, three=None, four=True, five=None))
+
+ # Force-disable it
+ obj2 = EvenObjectFactory(even=False)
+ self.assertEqual(obj2.as_dict(),
+ dict(one=None, two=None, three=None, four=None, five=None))
+
+ def test_traits_override(self):
+ """Override a trait in a subclass."""
+ class TestObjectFactory(factory.Factory):
+ class Meta:
+ model = TestObject
+
+ class Params:
+ even = factory.Trait(two=True, four=True)
+ odd = factory.Trait(one=True, three=True, five=True)
+
+ class WeirdMathFactory(TestObjectFactory):
+ class Params:
+ # Here, one is even.
+ even = factory.Trait(two=True, four=True, one=True)
+
+ obj = WeirdMathFactory(even=True)
+ self.assertEqual(obj.as_dict(),
+ dict(one=True, two=True, three=None, four=True, five=None))
+
+ def test_traits_chaining(self):
+ """Use a trait to enable other traits."""
+ class TestObjectFactory(factory.Factory):
+ class Meta:
+ model = TestObject
+
+ class Params:
+ even = factory.Trait(two=True, four=True)
+ odd = factory.Trait(one=True, three=True, five=True)
+ full = factory.Trait(even=True, odd=True)
+
+ # Setting "full" should enable all fields.
+ obj = TestObjectFactory(full=True)
+ self.assertEqual(obj.as_dict(),
+ dict(one=True, two=True, three=True, four=True, five=True))
+
+ # Does it break usual patterns?
+ obj1 = TestObjectFactory()
+ self.assertEqual(obj1.as_dict(),
+ dict(one=None, two=None, three=None, four=None, five=None))
+
+ obj2 = TestObjectFactory(even=True)
+ self.assertEqual(obj2.as_dict(),
+ dict(one=None, two=True, three=None, four=True, five=None))
+
+ obj3 = TestObjectFactory(odd=True)
+ self.assertEqual(obj3.as_dict(),
+ dict(one=True, two=None, three=True, four=None, five=True))
+
+ def test_prevent_cyclic_traits(self):
+
+ with self.assertRaises(errors.CyclicDefinitionError):
+ class TestObjectFactory(factory.Factory):
+ class Meta:
+ model = TestObject
+
+ class Params:
+ a = factory.Trait(b=True, one=True)
+ b = factory.Trait(a=True, two=True)
+
+
class SubFactoryTestCase(unittest.TestCase):
def test_sub_factory(self):
class TestModel2(FakeModel):
@@ -1132,6 +1268,26 @@ class SubFactoryTestCase(unittest.TestCase):
self.assertEqual('x0x', test_model.two.one)
self.assertEqual('x0xx0x', test_model.two.two)
+ def test_sub_factory_with_lazy_fields_access_factory_parent(self):
+ class TestModel2(FakeModel):
+ pass
+
+ class TestModelFactory(FakeModelFactory):
+ class Meta:
+ model = TestModel
+ one = 3
+
+ class TestModel2Factory(FakeModelFactory):
+ class Meta:
+ model = TestModel2
+ one = 'parent'
+ child = factory.SubFactory(TestModelFactory,
+ one=factory.LazyAttribute(lambda o: '%s child' % o.factory_parent.one),
+ )
+
+ test_model = TestModel2Factory()
+ self.assertEqual('parent child', test_model.child.one)
+
def test_sub_factory_and_sequence(self):
class TestObject(object):
def __init__(self, **kwargs):