[PATCH V2] New factory class to create arbitrary model objects, to be used in tests

Guilherme Salgado guilherme.salgado at linaro.org
Fri Apr 15 05:42:31 EST 2011


Signed-off-by: Guilherme Salgado <guilherme.salgado at linaro.org>
---

I think there's value in having this factory because some tests will need
either more stuff than is provided by the basic fixture or just different
stuff, and changing the fixture to accomodate the needs of every possible test
is a well known cause of obscure tests: 
    <http://xunitpatterns.com/Obscure%20Test.html#General%20Fixture>

I already have some tests using this and I'm planning to write more for the
'my patches' page that I'm working on, which I hope to submit soon.

 apps/patchwork/tests/factory.py |  111 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 111 insertions(+), 0 deletions(-)
 create mode 100644 apps/patchwork/tests/factory.py

diff --git a/apps/patchwork/tests/factory.py b/apps/patchwork/tests/factory.py
new file mode 100644
index 0000000..a750e85
--- /dev/null
+++ b/apps/patchwork/tests/factory.py
@@ -0,0 +1,111 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2011 Jeremy Kerr <jk at ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+from datetime import datetime
+import email
+from itertools import count
+from random import randint
+
+from django.contrib.auth.models import User
+
+from patchwork.models import Bundle, Patch, Person, Project, State
+
+
+class ObjectFactory(object):
+    """Factory methods for creating basic Python objects."""
+
+    def __init__(self):
+        # Initialise the unique identifier.
+        self.integer = count(randint(0, 1000000))
+
+    def getUniqueEmailAddress(self):
+        return "%s at example.com" % self.getUniqueString('email')
+
+    def getUniqueString(self, prefix=None):
+        """Return a string unique to this factory instance.
+
+        :param prefix: Used as a prefix for the unique string. If unspecified,
+            defaults to 'generic-string'.
+        """
+        if prefix is None:
+            prefix = "generic-string"
+        string = "%s%s" % (prefix, self.getUniqueInteger())
+        return string.lower()
+
+    def getUniqueInteger(self):
+        """Return an integer unique to this factory instance."""
+        return self.integer.next()
+
+    def makeUser(self):
+        userid = password = self.getUniqueString()
+        user = User.objects.create_user(
+            userid, self.getUniqueEmailAddress(), password)
+        user.save()
+        return user
+
+    def makeProject(self):
+        name = self.getUniqueString()
+        project = Project(
+            linkname=name, name=name,
+            listid=self.getUniqueString(),
+            listemail=self.getUniqueEmailAddress())
+        project.save()
+        return project
+
+    def makePerson(self, is_user=True):
+        person = Person(
+            email=self.getUniqueEmailAddress(), name=self.getUniqueString())
+        person.save()
+        if is_user:
+            # Must create the user after the person is created or else
+            # create_user() will trigger the creation of a person.
+            user = User.objects.create_user(
+                person.name, person.email, password=None)
+            user.save()
+        # Re-fetch the person object so that our callsite sees the link to the
+        # newly created user.
+        person = Person.objects.get(email=person.email)
+        return person
+
+    def makeBundle(self, patches=None):
+        if patches is None:
+            patches = [self.makePatch()]
+        bundle = Bundle(
+            owner=self.makeUser(), project=self.makeProject(),
+            name=self.getUniqueString())
+        bundle.save()
+        for patch in patches:
+            bundle.append_patch(patch)
+        bundle.save()
+        return bundle
+
+    def makePatch(self, project=None, submitter=None, date=None):
+        if date is None:
+            date = datetime.now()
+        if project is None:
+            project = self.makeProject()
+        if submitter is None:
+            submitter = self.makePerson()
+        msgid = email.utils.make_msgid(idstring=self.getUniqueString())
+        patch = Patch(
+            project=project, msgid=msgid, name=self.getUniqueString(),
+            submitter=submitter, date=date,
+            state=State.objects.get(name='New'))
+        patch.save()
+        return patch



More information about the Patchwork mailing list