Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make set_seed a well_behaved decorator #31

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions django_any/contrib/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def any_user(password=None, permissions=[], groups=[], **kwargs):

if password:
user.set_password(password)
user._password = password

user.save()
return user
Expand Down
6 changes: 3 additions & 3 deletions django_any/contrib/default.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# -*- coding: utf-8 -*-
from django_any.models import any_model
from django.db.models.fields import NOT_PROVIDED
from inspect import isfunction, ismethod
from inspect import isroutine

def any_model_with_defaults(cls, **attrs):
"""Use model-provided defaults"""

for field in cls._meta.fields:
default = field.default
if default is not NOT_PROVIDED:
if isfunction(default) or ismethod(default):
if isroutine(default):
# for stuff like default=datetime.now
default = default()
attrs.setdefault(field.name, default)

return any_model(cls, **attrs)
return any_model(cls, **attrs)
16 changes: 13 additions & 3 deletions django_any/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ def get_some_file(path):
return result

if callable(field.upload_to):
generated_filepath = field.upload_to(None, xunit.any_string(ascii_letters, 10, 20))
generated_filepath = field.upload_to(field.model, xunit.any_string(ascii_letters, 10, 20))
upload_to = os.path.dirname(generated_filepath)
else:
upload_to = field.upload_to
Expand Down Expand Up @@ -436,8 +436,7 @@ def any_url_field(field, **kwargs):

if not url:
verified = [validator for validator in field.validators \
if isinstance(validator, validators.URLValidator) and \
validator.verify_exists == True]
if isinstance(validator, validators.URLValidator)]
if verified:
url = choice(['http://news.yandex.ru/society.html',
'http://video.google.com/?hl=en&tab=wv',
Expand Down Expand Up @@ -543,3 +542,14 @@ def any_model_default(model_cls, **kwargs):
if not attempts:
raise


try:
import django_extensions.db.fields
except ImportError:
pass
else:
import uuid

@any_field.register(django_extensions.db.fields.UUIDField)
def any_uuid_field(field, **kwargs):
return uuid.uuid4()
36 changes: 24 additions & 12 deletions django_any/test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
import time, random
from functools import wraps # requires python 2.5
import random
import time

try:
from unittest import _strclass
Expand Down Expand Up @@ -42,6 +44,8 @@ def login_as(self, **kwargs):
password = xunit.any_string()
if 'user' in kwargs:
user = kwargs['user']
if getattr(user, '_password', False) != False:
password = user._password
try:
user.set_password(password)
user.save()
Expand All @@ -54,7 +58,8 @@ def login_as(self, **kwargs):
return user
raise AssertionError('Can''t login with autogenerated user')

def post_any_data(self, url, extra=None, context_forms=_request_context_forms, **kwargs):
def post_any_data(self, url, extra=None,
context_forms=_request_context_forms, **kwargs):
response = self.get(url)

post_data = {}
Expand All @@ -63,28 +68,33 @@ def post_any_data(self, url, extra=None, context_forms=_request_context_forms, *
if callable(context_forms):
forms_list = context_forms(response.context)
elif isinstance(context_forms, (list, tuple)):
forms_list = [response.context[form_name] for form_name in context_forms]
forms_list = [response.context[form_name]
for form_name in context_forms]
else:
raise TypeError('context_forms should be callable or list or tuple, not %s' % type(context_forms).__name__)
raise TypeError('context_forms should be callable or list or tuple'
', not %s' % type(context_forms).__name__)

# generate data
for form in forms_list:
if isinstance(form, forms.formsets.BaseFormSet): # TODO any_form ExtensionMethod
# TODO any_form ExtensionMethod
if isinstance(form, forms.formsets.BaseFormSet):
#TODO support formset data
form_data = form.management_form.initial
form_data['MAX_NUM_FORMS'] = 0
else:
form_data, form_files = any_form(form.__class__, **kwargs) #TODO support form instance
#TODO support form instance
form_data, form_files = any_form(form.__class__)

if form.prefix:
form_data = dict([('%s-%s' % (form.prefix, key), value) for key, value in form_data.items()])
form_data = dict([('%s-%s' % (form.prefix, key), value)
for key, value in form_data.items()])

post_data.update(form_data)

if extra:
post_data.update(extra)

return self.post(url, post_data)
return self.post(url, post_data, **kwargs)


def without_random_seed(func):
Expand All @@ -106,12 +116,12 @@ def _wrapper(func):
return func
return _wrapper


def set_seed(func, seed=None):
"""
Set randon seed before executing function. If seed is
not provided current timestamp used
"""
@wraps(func)
def _wrapper(self, seed=seed, *args, **kwargs):
self.__django_any_seed = seed if seed else int(time.time()*1000)
random.seed(self.__django_any_seed)
Expand All @@ -127,7 +137,9 @@ def __new__(cls, cls_name, bases, attrs):
attrs['__django_any_seed'] = 0

def shortDescription(self):
return "%s (%s) With seed %s" % (self._testMethodName, _strclass(self.__class__), getattr(self, '__django_any_seed'))
return "%s (%s) With seed %s" % (
self._testMethodName, _strclass(self.__class__),
getattr(self, '__django_any_seed'))

for name, func in attrs.items():
if name.startswith('test') and hasattr(func, '__call__'):
Expand All @@ -139,7 +151,7 @@ def shortDescription(self):
for seed in getattr(func, '__django_any_with_seed', []):
attrs['%s_%d' % (name, seed)] = set_seed(func, seed)

testcase = super(WithTestDataSeed, cls).__new__(cls, cls_name, bases, attrs)
testcase = super(WithTestDataSeed, cls).__new__(
cls, cls_name, bases, attrs)
testcase.shortDescription = shortDescription
return testcase

2 changes: 2 additions & 0 deletions tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
ROOT_URLCONF = 'tests.test_runner'
MEDIA_ROOT = os.path.join(PROJECT_ROOT, 'media')

SECRET_KEY = 'keepitsecretkeepitsafe'

if __name__ == "__main__":
import sys, test_runner as settings
from django.core.management import execute_manager
Expand Down