Permalink
Browse files

changing declaration syntax

  • Loading branch information...
1 parent de6c8ec commit 12f973a12a087ab9bba30386134e404fb063fd49 Mikko Hellsing committed Oct 15, 2010
Showing with 59 additions and 35 deletions.
  1. +31 −10 autofixture/base.py
  2. +10 −13 autofixture/contrib/auth.py
  3. +12 −4 autofixture/generators.py
  4. +6 −8 autofixture_tests/autofixture_test/tests.py
View
41 autofixture/base.py
@@ -59,6 +59,24 @@ def get_deep_links(self, field):
return Link(fields, default=self.default)
+def get_declared_generators(bases, attrs):
+ field_generators = {}
+ for base in bases[::-1]:
+ if hasattr(base, 'field_generators'):
+ field_generators.update(base.field_generators)
+ for k, v in attrs.items():
+ if isinstance(v, generators.Generator):
+ field_generators[k] = attrs.pop(k)
+ return field_generators
+
+
+class DeclarativeGeneratorsMetaclass(type):
+ def __new__(cls, name, bases, attrs):
+ attrs['field_generators'] = get_declared_generators(bases, attrs)
+ uber = super(DeclarativeGeneratorsMetaclass, cls)
+ return uber.__new__(cls, name, bases, attrs)
+
+
class AutoFixture(object):
'''
.. We don't support the following fields yet:
@@ -69,6 +87,9 @@ class AutoFixture(object):
Patches are welcome.
'''
+
+ __metaclass__ = DeclarativeGeneratorsMetaclass
+
class IGNORE_FIELD(object):
pass
@@ -94,21 +115,21 @@ class IGNORE_FIELD(object):
(fields.TimeField, generators.TimeGenerator),
))
- field_values = {}
+ field_generators = {}
default_constraints = [
constraints.unique_constraint,
constraints.unique_together_constraint]
def __init__(self, model,
- field_values=None, overwrite_defaults=None,
+ field_generators=None, overwrite_defaults=None,
constraints=None, follow_fk=None, generate_fk=None,
follow_m2m=None, generate_m2m=None):
'''
Parameters:
``model``: A model class which is used to create the test data.
- ``field_values``: A dictionary with field names of ``model`` as
+ ``field_generators``: A dictionary with field names of ``model`` as
keys. Values may be static values that are assigned to the field,
a ``Generator`` instance that generates a value on the fly or a
callable which takes no arguments and returns the wanted value.
@@ -143,7 +164,7 @@ def __init__(self, model,
will be ignored if this parameter is set.
'''
self.model = model
- self.field_values.update(field_values or {})
+ self.field_generators.update(field_generators or {})
self.constraints = constraints or []
if overwrite_defaults is not None:
self.overwrite_defaults = overwrite_defaults
@@ -192,12 +213,12 @@ def prepare_class(self):
'''
pass
- def add_field_value(self, name, value):
+ def add_field_generator(self, name, value):
'''
Pass a static *value* that should be assigned to the field called
*name*. *value* may be a :ref:`Generator <Generator>` instance.
'''
- self.field_values[name] = value
+ self.field_generators[name] = value
def add_constraint(self, constraint):
'''
@@ -219,8 +240,8 @@ def get_generator(self, field):
return None
kwargs = {}
- if field.name in self.field_values:
- value = self.field_values[field.name]
+ if field.name in self.field_generators:
+ value = self.field_generators[field.name]
if isinstance(value, generators.Generator):
return value
elif isinstance(value, AutoFixture):
@@ -245,7 +266,7 @@ def get_generator(self, field):
field.rel.to,
limit_choices_to=field.rel.limit_choices_to)
if field.blank or field.null:
- return generators.NoneGenerator()
+ return generators.StaticGenerator(None)
raise CreateInstanceError(
u'Cannot resolve ForeignKey "%s" to "%s". Provide either '
u'"follow_fk" or "generate_fk" parameters.' % (
@@ -382,7 +403,7 @@ def process_m2m(self, instance, field):
intermediary_model = generators.MultipleInstanceGenerator(
get_autofixture(
through,
- field_values={
+ field_generators={
self_fk.name: instance,
related_fk.name: generators.InstanceGenerator(
get_autofixture(field.rel.to))
View
23 autofixture/contrib/auth.py
@@ -22,19 +22,16 @@ class UserFixture(AutoFixture):
* ``date_joined`` and ``last_login`` are always in the past and it is
assured that ``date_joined`` will be lower than ``last_login``.
'''
- field_values = {
- 'username': generators.StringGenerator(chars=
- string.ascii_letters + string.digits + '_'),
- 'first_name': generators.LoremWordGenerator(1),
- 'last_name': generators.LoremWordGenerator(1),
- 'password': UNUSABLE_PASSWORD,
- 'is_active': True,
+ username = generators.UUIDGenerator()
+ first_name = generators.LoremWordGenerator(1)
+ last_name = generators.LoremWordGenerator(1)
+ password = generators.StaticGenerator(UNUSABLE_PASSWORD)
+ is_active = generators.StaticGenerator(True)
# don't generate admin users
- 'is_staff': False,
- 'is_superuser': False,
- 'date_joined': generators.DateTimeGenerator(max_date=datetime.now()),
- 'last_login': generators.DateTimeGenerator(max_date=datetime.now()),
- }
+ is_staff = generators.StaticGenerator(False)
+ is_superuser = generators.StaticGenerator(False)
+ date_joined = generators.DateTimeGenerator(max_date=datetime.now())
+ last_login = generators.DateTimeGenerator(max_date=datetime.now())
# don't follow permissions and groups
follow_m2m = False
@@ -55,7 +52,7 @@ def __init__(self, *args, **kwargs):
self.password = kwargs.pop('password', None)
super(UserFixture, self).__init__(*args, **kwargs)
if self.username:
- self.field_values['username'] = generators.StaticGenerator(
+ self.field_generators['username'] = generators.StaticGenerator(
self.username)
def unique_email(self, model, instance):
View
16 autofixture/generators.py
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
from decimal import Decimal
import datetime
+import os
import random
import re
import string
-import os
+import uuid
# backporting os.path.relpath, only availabe in python >= 2.6
@@ -76,9 +77,15 @@ def generate(self):
return self.value(*self.args, **self.kwargs)
-class NoneGenerator(Generator):
+class UUIDGenerator(Generator):
+ def __init__(self, max_length=None):
+ self.max_length = max_length
+
def generate(self):
- return self.empty_value
+ value = unicode(uuid.uuid1())
+ if self.max_length is not None:
+ value = value[:self.max_length]
+ return max_length
class StringGenerator(Generator):
@@ -426,7 +433,8 @@ def __init__(self, autofixture, limit_choices_to=None, *args, **kwargs):
bits = lookup.split('__')
if len(bits) == 1 or \
len(bits) == 2 and bits[1] in ('exact', 'iexact'):
- self.autofixture.add_field_value(bits[0], StaticGenerator(value))
+ self.autofixture.add_field_generator(bits[0],
+ StaticGenerator(value))
super(InstanceGenerator, self).__init__(*args, **kwargs)
def generate(self):
View
14 autofixture_tests/autofixture_test/tests.py
@@ -9,13 +9,11 @@
from autofixture_tests.autofixture_test.models import (
SimpleModel, OtherSimpleModel, DeepLinkModel1, DeepLinkModel2,
NullableFKModel, BasicModel, UniqueTestModel, UniqueTogetherTestModel,
- RelatedModel, O2OModel, M2MModel, ThroughModel, M2MModelThrough)
+ RelatedModel, O2OModel, M2MModel, ThroughModel, M2MModelThrough)
class SimpleAutoFixture(AutoFixture):
- field_values = {
- 'name': generators.StaticGenerator('foo'),
- }
+ name = generators.StaticGenerator('foo')
class TestBasicModel(TestCase):
@@ -58,12 +56,12 @@ def test_constraints(self):
self.assertTrue(len(obj.ipaddressfield) >= 7)
self.assertEqual(BasicModel.objects.count(), 100)
- def test_field_values(self):
+ def test_field_generators(self):
int_value = 1
char_values = (u'a', u'b')
filler = AutoFixture(
BasicModel,
- field_values={
+ field_generators={
'intfield': 1,
'chars': generators.ChoicesGenerator(values=char_values),
'shortchars': lambda: u'ab',
@@ -358,10 +356,10 @@ def test_create(self):
def test_overwrite_attributes(self):
autofixture.register(SimpleModel, SimpleAutoFixture)
for obj in autofixture.create(
- SimpleModel, 10, field_values={'name': 'bar'}):
+ SimpleModel, 10, field_generators={'name': 'bar'}):
self.assertEqual(obj.name, 'bar')
obj = autofixture.create_one(
- SimpleModel, field_values={'name': 'bar'})
+ SimpleModel, field_generators={'name': 'bar'})
self.assertEqual(obj.name, 'bar')

0 comments on commit 12f973a

Please sign in to comment.