Permalink
Browse files

initial commit

  • Loading branch information...
0 parents commit fe528db5ac1d2af5454d8c0bc887a1f1a35bf1d4 Vanderson Mota committed Jan 9, 2011
@@ -0,0 +1,3 @@
+*.pyc
+*.swp
+*.swo
@@ -0,0 +1,40 @@
+# Creating objects for testing shouldn't hurt
+-----------------------------------------------------------
+
+model_mommy is a tool for creating objects for testing in Django, inspired in ruby's ObjectDaddy and FactoryGirl.
+It generate the values according with the field type, but it supports custom values as well.
+
+#Installing
+
+ pip install model_mommy
+
+## Basic Usage:
+
+If you have a model like this in your app:
+
+ class Kid(models.Model):
+ name = models.CharField(max_length=30)
+ age = models.IntegerField()
+ bio = models.TextField()
+ birthday = models.DateField()
+
+just call the mommy =):
+
+ from model_mommy import mommy
+ kid = mommy.make_one(Kid)
+
+and your object is created! No boring attributes passing like 'foobar' every damn time.
+
+mommy also handles relationships. Suppose the kid has a dog:
+
+ class Dog(models.Model):
+ owner = models.ForeignKey('Kid')
+
+when you do:
+
+ rex = mommy.make_one(Dog)
+
+it will also create the Kid, automatically.
+
+##Currently supports the fields:
+CharField, TextField, FloatField, ForeignKey, and all the integer-type Fields
No changes.
No changes.
@@ -0,0 +1,26 @@
+#coding: utf-8
+from django.db import models
+
+class Kid(models.Model):
+ name = models.CharField(max_length=30)
+ age = models.IntegerField()
+ bio = models.TextField()
+ wanted_games_qtd = models.BigIntegerField()
+ birthday = models.DateField()
+
+class Dog(models.Model):
+ owner = models.ForeignKey('Kid')
+
+class DummyIntModel(models.Model):
+ int_field = models.IntegerField()
+ big_int_field = models.BigIntegerField()
+ small_int_field = models.SmallIntegerField()
+ positive_small_int_field = models.PositiveSmallIntegerField()
+ positive_int_field = models.PositiveIntegerField()
+
+class DummyNumbersModel(models.Model):
+ float_field = models.FloatField(null=True)
+ decimal_field = models.DecimalField(max_digits=4, decimal_places=2, null=True)
+
+
+
@@ -0,0 +1,46 @@
+#coding: utf-8
+from django.db.models.fields import AutoField, CharField, TextField
+from django.db.models.fields import DateField
+from django.db.models.fields import IntegerField, BigIntegerField, SmallIntegerField
+from django.db.models.fields import PositiveSmallIntegerField, PositiveIntegerField
+from django.db.models.fields import FloatField, DecimalField
+
+from django.db.models import ForeignKey
+from string import letters
+from random import choice, randint
+from datetime import date
+from decimal import Decimal
+
+MAX_LENGTH = 100
+MAX_INT_VALUE = 1000
+
+INT_FIELDS = (
+ IntegerField, BigIntegerField, SmallIntegerField,
+ PositiveIntegerField, PositiveSmallIntegerField,
+)
+
+STR_FIELDS = (CharField, TextField)
+
+def make_one(model):
+ attrs = {}
+ for field in model._meta.fields:
+ if isinstance(model, AutoField):
+ continue
+ attrs[field.name] = _generate_value(field)
+ return model.objects.create(**attrs)
+
+
+def _generate_value(field):
+ if isinstance(field, STR_FIELDS):
+ random_str = ''
+ for i in range(field.max_length or MAX_LENGTH):
+ random_str += choice(letters)
+ return random_str
+ elif isinstance(field, INT_FIELDS):
+ return randint(1, MAX_INT_VALUE)
+ elif isinstance(field, FloatField):
+ return float(randint(1, MAX_INT_VALUE))
+ elif isinstance(field, ForeignKey):
+ return make_one(field.related.parent_model)
+ elif isinstance(field, DateField):
+ return date.today()
@@ -0,0 +1,2 @@
+#coding: utf-8
+from test_mommy import *
@@ -0,0 +1,6 @@
+#coding: utf-8
+from django.db import models
+
+class Kid(models.Model):
+ name = models.CharField(max_length=30)
+ age = models.IntegerField()
@@ -0,0 +1,100 @@
+from datetime import date, datetime
+from decimal import Decimal
+
+from django.db.models.fields import *
+from django.test import TestCase
+from model_mommy.models import Kid, Dog, DummyIntModel
+from model_mommy.models import DummyNumbersModel
+from model_mommy import mommy
+
+class FieldFillingTestCase(TestCase):
+
+ def setUp(self):
+ self.kid = mommy.make_one(Kid)
+
+class MommyCreatesSimpleModel(TestCase):
+
+ def test_make_one_should_create_one_object(self):
+ kid = mommy.make_one(Kid)
+ self.assertTrue(isinstance(kid, Kid))
+ self.assertEqual(Kid.objects.all().count(), 1)
+
+class MommyCreatesAssociatedModels(TestCase):
+ def test_dependent_models_with_ForeignKey(self):
+ dog = mommy.make_one(Dog)
+
+ self.assertTrue(isinstance(dog.owner, Kid))
+
+class StringFieldsFilling(FieldFillingTestCase):
+
+ def test_fill_CharField_with_a_random_str(self):
+ kid_name_field = Kid._meta.get_field('name')
+ self.assertTrue(isinstance(kid_name_field, CharField))
+
+ self.assertTrue(isinstance(self.kid.name, str))
+ self.assertEqual(len(self.kid.name), kid_name_field.max_length)
+
+ def test_fill_TextField_with_a_random_str(self):
+ kid_bio_field = Kid._meta.get_field('bio')
+ self.assertTrue(isinstance(kid_bio_field, TextField))
+
+ self.assertTrue(isinstance(self.kid.bio, str))
+
+class DateTimeFieldsFilling(FieldFillingTestCase):
+
+ def test_fill_DateField_with_a_date(self):
+ birthday_field = Kid._meta.get_field('birthday')
+ self.assertTrue(isinstance(birthday_field, DateField))
+
+ self.assertTrue(isinstance(self.kid.birthday, date))
+
+
+class FillingIntFields(TestCase):
+
+ def setUp(self):
+ self.dummy_int_model = mommy.make_one(DummyIntModel)
+
+ def test_fill_IntegerField_with_a_random_number(self):
+ int_field = DummyIntModel._meta.get_field('int_field')
+ self.assertTrue(isinstance(int_field, IntegerField))
+
+ self.assertTrue(isinstance(self.dummy_int_model.int_field, int))
+
+ def test_fill_BigIntegerField_with_a_random_number(self):
+ big_int_field = DummyIntModel._meta.get_field('big_int_field')
+ self.assertTrue(isinstance(big_int_field, BigIntegerField))
+
+ self.assertTrue(isinstance(self.dummy_int_model.big_int_field, int))
+
+ def test_fill_SmallIntegerField_with_a_random_number(self):
+ small_int_field = DummyIntModel._meta.get_field('small_int_field')
+ self.assertTrue(isinstance(small_int_field, SmallIntegerField))
+
+ self.assertTrue(isinstance(self.dummy_int_model.small_int_field, int))
+
+ def test_fill_PositiveSmallIntegerField_with_a_random_number(self):
+ positive_small_int_field = DummyIntModel._meta.get_field('positive_small_int_field')
+ self.assertTrue(isinstance(positive_small_int_field, PositiveSmallIntegerField))
+
+ self.assertTrue(isinstance(self.dummy_int_model.positive_small_int_field, int))
+ self.assertTrue(self.dummy_int_model.positive_small_int_field > 0)
+
+ def test_fill_PositiveIntegerField_with_a_random_number(self):
+ positive_int_field = DummyIntModel._meta.get_field('positive_int_field')
+ self.assertTrue(isinstance(positive_int_field, PositiveIntegerField))
+
+ self.assertTrue(isinstance(self.dummy_int_model.positive_int_field, int))
+ self.assertTrue(self.dummy_int_model.positive_int_field > 0)
+
+class FillingOthersNumericFields(TestCase):
+ def test_filling_FloatField_with_a_random_float(self):
+ self.dummy_numbers_model = mommy.make_one(DummyNumbersModel)
+ float_field = DummyNumbersModel._meta.get_field('float_field')
+ self.assertTrue(isinstance(float_field, FloatField))
+ self.assertTrue(isinstance(self.dummy_numbers_model.float_field, float))
+
+ def _test_filling_DecimalField_with_a_random_decimal(self):
+ self.dummy_numbers_model = mommy.make_one(DummyNumbersModel)
+ decimal_field = DummyNumbersModel._meta.get_field('decimal_field')
+ self.assertTrue(isinstance(decimal_field, DecimalField))
+ self.assertTrue(isinstance(self.dummy_numbers_model.decimal_field, Decimal))
@@ -0,0 +1,15 @@
+import sys
+import setuptools
+
+setuptools.setup(
+ name="model_mommy",
+ version="0.2",
+ packages=["model_mommy",],
+ install_requires=["django",],
+ author="vandersonmota",
+ author_email="vandersonmota@gmail.com",
+ url="http://github.com/vandersonmota/model_mommy",
+ license="http://www.apache.org/licenses/LICENSE-2.0",
+ description="automatic object creation facility for django",
+ keywords="django testing factory python",
+)

0 comments on commit fe528db

Please sign in to comment.