From 8bafde1229fdebb48383449de9bcadde06451816 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Tue, 16 Nov 2010 13:20:56 +0000 Subject: [PATCH] Migrated forms (minus localflavor) doctests. A huge thanks to Daniel Lindsley for the patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@14570 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- AUTHORS | 2 +- tests/regressiontests/forms/error_messages.py | 399 ---- tests/regressiontests/forms/forms.py | 1899 ----------------- tests/regressiontests/forms/formsets.py | 762 ------- tests/regressiontests/forms/localflavor/be.py | 8 +- .../forms/{tests.py => localflavortests.py} | 23 - tests/regressiontests/forms/media.py | 385 ---- tests/regressiontests/forms/models.py | 176 -- tests/regressiontests/forms/regressions.py | 135 -- tests/regressiontests/forms/tests/__init__.py | 15 + .../forms/tests/error_messages.py | 253 +++ .../forms/{ => tests}/extra.py | 544 +++-- .../forms/{ => tests}/fields.py | 146 +- tests/regressiontests/forms/tests/forms.py | 1709 +++++++++++++++ tests/regressiontests/forms/tests/formsets.py | 797 +++++++ .../forms/{ => tests}/input_formats.py | 0 tests/regressiontests/forms/tests/media.py | 460 ++++ tests/regressiontests/forms/tests/models.py | 161 ++ .../forms/tests/regressions.py | 122 ++ tests/regressiontests/forms/tests/util.py | 57 + .../forms/{ => tests}/validators.py | 0 tests/regressiontests/forms/tests/widgets.py | 1135 ++++++++++ tests/regressiontests/forms/util.py | 60 - tests/regressiontests/forms/widgets.py | 1398 ------------ 24 files changed, 5027 insertions(+), 5619 deletions(-) delete mode 100644 tests/regressiontests/forms/error_messages.py delete mode 100644 tests/regressiontests/forms/forms.py delete mode 100644 tests/regressiontests/forms/formsets.py rename tests/regressiontests/forms/{tests.py => localflavortests.py} (79%) delete mode 100644 tests/regressiontests/forms/media.py delete mode 100644 tests/regressiontests/forms/regressions.py create mode 100644 tests/regressiontests/forms/tests/__init__.py create mode 100644 tests/regressiontests/forms/tests/error_messages.py rename tests/regressiontests/forms/{ => tests}/extra.py (54%) rename tests/regressiontests/forms/{ => tests}/fields.py (95%) create mode 100644 tests/regressiontests/forms/tests/forms.py create mode 100644 tests/regressiontests/forms/tests/formsets.py rename tests/regressiontests/forms/{ => tests}/input_formats.py (100%) create mode 100644 tests/regressiontests/forms/tests/media.py create mode 100644 tests/regressiontests/forms/tests/models.py create mode 100644 tests/regressiontests/forms/tests/regressions.py create mode 100644 tests/regressiontests/forms/tests/util.py rename tests/regressiontests/forms/{ => tests}/validators.py (100%) create mode 100644 tests/regressiontests/forms/tests/widgets.py delete mode 100644 tests/regressiontests/forms/util.py delete mode 100644 tests/regressiontests/forms/widgets.py diff --git a/AUTHORS b/AUTHORS index bc45ce7809..ac87816465 100644 --- a/AUTHORS +++ b/AUTHORS @@ -309,7 +309,7 @@ answer newbie questions, and generally made Django that much better: limodou Philip Lindborg Simon Litchfield - Daniel Lindsley + Daniel Lindsley Trey Long Laurent Luce Martin Mahner diff --git a/tests/regressiontests/forms/error_messages.py b/tests/regressiontests/forms/error_messages.py deleted file mode 100644 index 038fa39f6b..0000000000 --- a/tests/regressiontests/forms/error_messages.py +++ /dev/null @@ -1,399 +0,0 @@ -# -*- coding: utf-8 -*- -tests = r""" ->>> from django.forms import * ->>> from django.core.files.uploadedfile import SimpleUploadedFile - -# CharField ################################################################### - ->>> e = {'required': 'REQUIRED'} ->>> e['min_length'] = 'LENGTH %(show_value)s, MIN LENGTH %(limit_value)s' ->>> e['max_length'] = 'LENGTH %(show_value)s, MAX LENGTH %(limit_value)s' ->>> f = CharField(min_length=5, max_length=10, error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean('1234') -Traceback (most recent call last): -... -ValidationError: [u'LENGTH 4, MIN LENGTH 5'] ->>> f.clean('12345678901') -Traceback (most recent call last): -... -ValidationError: [u'LENGTH 11, MAX LENGTH 10'] - -# IntegerField ################################################################ - ->>> e = {'required': 'REQUIRED'} ->>> e['invalid'] = 'INVALID' ->>> e['min_value'] = 'MIN VALUE IS %(limit_value)s' ->>> e['max_value'] = 'MAX VALUE IS %(limit_value)s' ->>> f = IntegerField(min_value=5, max_value=10, error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean('abc') -Traceback (most recent call last): -... -ValidationError: [u'INVALID'] ->>> f.clean('4') -Traceback (most recent call last): -... -ValidationError: [u'MIN VALUE IS 5'] ->>> f.clean('11') -Traceback (most recent call last): -... -ValidationError: [u'MAX VALUE IS 10'] - -# FloatField ################################################################## - ->>> e = {'required': 'REQUIRED'} ->>> e['invalid'] = 'INVALID' ->>> e['min_value'] = 'MIN VALUE IS %(limit_value)s' ->>> e['max_value'] = 'MAX VALUE IS %(limit_value)s' ->>> f = FloatField(min_value=5, max_value=10, error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean('abc') -Traceback (most recent call last): -... -ValidationError: [u'INVALID'] ->>> f.clean('4') -Traceback (most recent call last): -... -ValidationError: [u'MIN VALUE IS 5'] ->>> f.clean('11') -Traceback (most recent call last): -... -ValidationError: [u'MAX VALUE IS 10'] - -# DecimalField ################################################################ - ->>> e = {'required': 'REQUIRED'} ->>> e['invalid'] = 'INVALID' ->>> e['min_value'] = 'MIN VALUE IS %(limit_value)s' ->>> e['max_value'] = 'MAX VALUE IS %(limit_value)s' ->>> e['max_digits'] = 'MAX DIGITS IS %s' ->>> e['max_decimal_places'] = 'MAX DP IS %s' ->>> e['max_whole_digits'] = 'MAX DIGITS BEFORE DP IS %s' ->>> f = DecimalField(min_value=5, max_value=10, error_messages=e) ->>> f2 = DecimalField(max_digits=4, decimal_places=2, error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean('abc') -Traceback (most recent call last): -... -ValidationError: [u'INVALID'] ->>> f.clean('4') -Traceback (most recent call last): -... -ValidationError: [u'MIN VALUE IS 5'] ->>> f.clean('11') -Traceback (most recent call last): -... -ValidationError: [u'MAX VALUE IS 10'] ->>> f2.clean('123.45') -Traceback (most recent call last): -... -ValidationError: [u'MAX DIGITS IS 4'] ->>> f2.clean('1.234') -Traceback (most recent call last): -... -ValidationError: [u'MAX DP IS 2'] ->>> f2.clean('123.4') -Traceback (most recent call last): -... -ValidationError: [u'MAX DIGITS BEFORE DP IS 2'] - -# DateField ################################################################### - ->>> e = {'required': 'REQUIRED'} ->>> e['invalid'] = 'INVALID' ->>> f = DateField(error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean('abc') -Traceback (most recent call last): -... -ValidationError: [u'INVALID'] - -# TimeField ################################################################### - ->>> e = {'required': 'REQUIRED'} ->>> e['invalid'] = 'INVALID' ->>> f = TimeField(error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean('abc') -Traceback (most recent call last): -... -ValidationError: [u'INVALID'] - -# DateTimeField ############################################################### - ->>> e = {'required': 'REQUIRED'} ->>> e['invalid'] = 'INVALID' ->>> f = DateTimeField(error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean('abc') -Traceback (most recent call last): -... -ValidationError: [u'INVALID'] - -# RegexField ################################################################## - ->>> e = {'required': 'REQUIRED'} ->>> e['invalid'] = 'INVALID' ->>> e['min_length'] = 'LENGTH %(show_value)s, MIN LENGTH %(limit_value)s' ->>> e['max_length'] = 'LENGTH %(show_value)s, MAX LENGTH %(limit_value)s' ->>> f = RegexField(r'^\d+$', min_length=5, max_length=10, error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean('abcde') -Traceback (most recent call last): -... -ValidationError: [u'INVALID'] ->>> f.clean('1234') -Traceback (most recent call last): -... -ValidationError: [u'LENGTH 4, MIN LENGTH 5'] ->>> f.clean('12345678901') -Traceback (most recent call last): -... -ValidationError: [u'LENGTH 11, MAX LENGTH 10'] - -# EmailField ################################################################## - ->>> e = {'required': 'REQUIRED'} ->>> e['invalid'] = 'INVALID' ->>> e['min_length'] = 'LENGTH %(show_value)s, MIN LENGTH %(limit_value)s' ->>> e['max_length'] = 'LENGTH %(show_value)s, MAX LENGTH %(limit_value)s' ->>> f = EmailField(min_length=8, max_length=10, error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean('abcdefgh') -Traceback (most recent call last): -... -ValidationError: [u'INVALID'] ->>> f.clean('a@b.com') -Traceback (most recent call last): -... -ValidationError: [u'LENGTH 7, MIN LENGTH 8'] ->>> f.clean('aye@bee.com') -Traceback (most recent call last): -... -ValidationError: [u'LENGTH 11, MAX LENGTH 10'] - -# FileField ################################################################## - ->>> e = {'required': 'REQUIRED'} ->>> e['invalid'] = 'INVALID' ->>> e['missing'] = 'MISSING' ->>> e['empty'] = 'EMPTY FILE' ->>> f = FileField(error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean('abc') -Traceback (most recent call last): -... -ValidationError: [u'INVALID'] ->>> f.clean(SimpleUploadedFile('name', None)) -Traceback (most recent call last): -... -ValidationError: [u'EMPTY FILE'] ->>> f.clean(SimpleUploadedFile('name', '')) -Traceback (most recent call last): -... -ValidationError: [u'EMPTY FILE'] - -# URLField ################################################################## - ->>> e = {'required': 'REQUIRED'} ->>> e['invalid'] = 'INVALID' ->>> e['invalid_link'] = 'INVALID LINK' ->>> f = URLField(verify_exists=True, error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean('abc.c') -Traceback (most recent call last): -... -ValidationError: [u'INVALID'] ->>> f.clean('http://www.broken.djangoproject.com') -Traceback (most recent call last): -... -ValidationError: [u'INVALID LINK'] - -# BooleanField ################################################################ - ->>> e = {'required': 'REQUIRED'} ->>> f = BooleanField(error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] - -# ChoiceField ################################################################# - ->>> e = {'required': 'REQUIRED'} ->>> e['invalid_choice'] = '%(value)s IS INVALID CHOICE' ->>> f = ChoiceField(choices=[('a', 'aye')], error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean('b') -Traceback (most recent call last): -... -ValidationError: [u'b IS INVALID CHOICE'] - -# MultipleChoiceField ######################################################### - ->>> e = {'required': 'REQUIRED'} ->>> e['invalid_choice'] = '%(value)s IS INVALID CHOICE' ->>> e['invalid_list'] = 'NOT A LIST' ->>> f = MultipleChoiceField(choices=[('a', 'aye')], error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean('b') -Traceback (most recent call last): -... -ValidationError: [u'NOT A LIST'] ->>> f.clean(['b']) -Traceback (most recent call last): -... -ValidationError: [u'b IS INVALID CHOICE'] - -# SplitDateTimeField ########################################################## - ->>> e = {'required': 'REQUIRED'} ->>> e['invalid_date'] = 'INVALID DATE' ->>> e['invalid_time'] = 'INVALID TIME' ->>> f = SplitDateTimeField(error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean(['a', 'b']) -Traceback (most recent call last): -... -ValidationError: [u'INVALID DATE', u'INVALID TIME'] - -# IPAddressField ############################################################## - ->>> e = {'required': 'REQUIRED'} ->>> e['invalid'] = 'INVALID IP ADDRESS' ->>> f = IPAddressField(error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean('127.0.0') -Traceback (most recent call last): -... -ValidationError: [u'INVALID IP ADDRESS'] - -############################################################################### - -# Create choices for the model choice field tests below. - ->>> from regressiontests.forms.models import ChoiceModel ->>> ChoiceModel.objects.create(pk=1, name='a') - ->>> ChoiceModel.objects.create(pk=2, name='b') - ->>> ChoiceModel.objects.create(pk=3, name='c') - - -# ModelChoiceField ############################################################ - ->>> e = {'required': 'REQUIRED'} ->>> e['invalid_choice'] = 'INVALID CHOICE' ->>> f = ModelChoiceField(queryset=ChoiceModel.objects.all(), error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean('4') -Traceback (most recent call last): -... -ValidationError: [u'INVALID CHOICE'] - -# ModelMultipleChoiceField #################################################### - ->>> e = {'required': 'REQUIRED'} ->>> e['invalid_choice'] = '%s IS INVALID CHOICE' ->>> e['list'] = 'NOT A LIST OF VALUES' ->>> f = ModelMultipleChoiceField(queryset=ChoiceModel.objects.all(), error_messages=e) ->>> f.clean('') -Traceback (most recent call last): -... -ValidationError: [u'REQUIRED'] ->>> f.clean('3') -Traceback (most recent call last): -... -ValidationError: [u'NOT A LIST OF VALUES'] ->>> f.clean(['4']) -Traceback (most recent call last): -... -ValidationError: [u'4 IS INVALID CHOICE'] - -# Subclassing ErrorList ####################################################### - ->>> from django.utils.safestring import mark_safe ->>> ->>> class TestForm(Form): -... first_name = CharField() -... last_name = CharField() -... birthday = DateField() -... -... def clean(self): -... raise ValidationError("I like to be awkward.") -... ->>> class CustomErrorList(util.ErrorList): -... def __unicode__(self): -... return self.as_divs() -... def as_divs(self): -... if not self: return u'' -... return mark_safe(u'
%s
' -... % ''.join([u'

%s

' % e for e in self])) -... - -This form should print errors the default way. - ->>> form1 = TestForm({'first_name': 'John'}) ->>> print form1['last_name'].errors -
  • This field is required.
->>> print form1.errors['__all__'] -
  • I like to be awkward.
- -This one should wrap error groups in the customized way. - ->>> form2 = TestForm({'first_name': 'John'}, error_class=CustomErrorList) ->>> print form2['last_name'].errors -

This field is required.

->>> print form2.errors['__all__'] -

I like to be awkward.

- -""" diff --git a/tests/regressiontests/forms/forms.py b/tests/regressiontests/forms/forms.py deleted file mode 100644 index 91594139f2..0000000000 --- a/tests/regressiontests/forms/forms.py +++ /dev/null @@ -1,1899 +0,0 @@ -# -*- coding: utf-8 -*- -tests = r""" ->>> from django.forms import * ->>> from django.core.files.uploadedfile import SimpleUploadedFile ->>> import datetime ->>> import time ->>> import re ->>> from decimal import Decimal - -######### -# Forms # -######### - -A Form is a collection of Fields. It knows how to validate a set of data and it -knows how to render itself in a couple of default ways (e.g., an HTML table). -You can pass it data in __init__(), as a dictionary. - -# Form ######################################################################## - ->>> class Person(Form): -... first_name = CharField() -... last_name = CharField() -... birthday = DateField() - -Pass a dictionary to a Form's __init__(). ->>> p = Person({'first_name': u'John', 'last_name': u'Lennon', 'birthday': u'1940-10-9'}) ->>> p.is_bound -True ->>> p.errors -{} ->>> p.is_valid() -True ->>> p.errors.as_ul() -u'' ->>> p.errors.as_text() -u'' ->>> p.cleaned_data["first_name"], p.cleaned_data["last_name"], p.cleaned_data["birthday"] -(u'John', u'Lennon', datetime.date(1940, 10, 9)) ->>> print p['first_name'] - ->>> print p['last_name'] - ->>> print p['birthday'] - ->>> print p['nonexistentfield'] -Traceback (most recent call last): -... -KeyError: "Key 'nonexistentfield' not found in Form" - ->>> for boundfield in p: -... print boundfield - - - ->>> for boundfield in p: -... print boundfield.label, boundfield.data -First name John -Last name Lennon -Birthday 1940-10-9 ->>> print p - - - - -Empty dictionaries are valid, too. ->>> p = Person({}) ->>> p.is_bound -True ->>> p.errors['first_name'] -[u'This field is required.'] ->>> p.errors['last_name'] -[u'This field is required.'] ->>> p.errors['birthday'] -[u'This field is required.'] ->>> p.is_valid() -False ->>> p.cleaned_data -Traceback (most recent call last): -... -AttributeError: 'Person' object has no attribute 'cleaned_data' ->>> print p -
  • This field is required.
-
  • This field is required.
-
  • This field is required.
->>> print p.as_table() -
  • This field is required.
-
  • This field is required.
-
  • This field is required.
->>> print p.as_ul() -
    • This field is required.
  • -
    • This field is required.
  • -
    • This field is required.
  • ->>> print p.as_p() -
    • This field is required.
    -

    -
    • This field is required.
    -

    -
    • This field is required.
    -

    - -If you don't pass any values to the Form's __init__(), or if you pass None, -the Form will be considered unbound and won't do any validation. Form.errors -will be an empty dictionary *but* Form.is_valid() will return False. ->>> p = Person() ->>> p.is_bound -False ->>> p.errors -{} ->>> p.is_valid() -False ->>> p.cleaned_data -Traceback (most recent call last): -... -AttributeError: 'Person' object has no attribute 'cleaned_data' ->>> print p - - - ->>> print p.as_table() - - - ->>> print p.as_ul() -
  • -
  • -
  • ->>> print p.as_p() -

    -

    -

    - -Unicode values are handled properly. ->>> p = Person({'first_name': u'John', 'last_name': u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111', 'birthday': '1940-10-9'}) ->>> p.as_table() -u'\n\n' ->>> p.as_ul() -u'
  • \n
  • \n
  • ' ->>> p.as_p() -u'

    \n

    \n

    ' - ->>> p = Person({'last_name': u'Lennon'}) ->>> p.errors['first_name'] -[u'This field is required.'] ->>> p.errors['birthday'] -[u'This field is required.'] ->>> p.is_valid() -False ->>> p.errors.as_ul() -u'
    • first_name
      • This field is required.
    • birthday
      • This field is required.
    ' ->>> print p.errors.as_text() -* first_name - * This field is required. -* birthday - * This field is required. ->>> p.cleaned_data -Traceback (most recent call last): -... -AttributeError: 'Person' object has no attribute 'cleaned_data' ->>> p['first_name'].errors -[u'This field is required.'] ->>> p['first_name'].errors.as_ul() -u'
    • This field is required.
    ' ->>> p['first_name'].errors.as_text() -u'* This field is required.' - ->>> p = Person() ->>> print p['first_name'] - ->>> print p['last_name'] - ->>> print p['birthday'] - - -cleaned_data will always *only* contain a key for fields defined in the -Form, even if you pass extra data when you define the Form. In this -example, we pass a bunch of extra fields to the form constructor, -but cleaned_data contains only the form's fields. ->>> data = {'first_name': u'John', 'last_name': u'Lennon', 'birthday': u'1940-10-9', 'extra1': 'hello', 'extra2': 'hello'} ->>> p = Person(data) ->>> p.is_valid() -True ->>> p.cleaned_data['first_name'] -u'John' ->>> p.cleaned_data['last_name'] -u'Lennon' ->>> p.cleaned_data['birthday'] -datetime.date(1940, 10, 9) - - -cleaned_data will include a key and value for *all* fields defined in the Form, -even if the Form's data didn't include a value for fields that are not -required. In this example, the data dictionary doesn't include a value for the -"nick_name" field, but cleaned_data includes it. For CharFields, it's set to the -empty string. ->>> class OptionalPersonForm(Form): -... first_name = CharField() -... last_name = CharField() -... nick_name = CharField(required=False) ->>> data = {'first_name': u'John', 'last_name': u'Lennon'} ->>> f = OptionalPersonForm(data) ->>> f.is_valid() -True ->>> f.cleaned_data['nick_name'] -u'' ->>> f.cleaned_data['first_name'] -u'John' ->>> f.cleaned_data['last_name'] -u'Lennon' - -For DateFields, it's set to None. ->>> class OptionalPersonForm(Form): -... first_name = CharField() -... last_name = CharField() -... birth_date = DateField(required=False) ->>> data = {'first_name': u'John', 'last_name': u'Lennon'} ->>> f = OptionalPersonForm(data) ->>> f.is_valid() -True ->>> print f.cleaned_data['birth_date'] -None ->>> f.cleaned_data['first_name'] -u'John' ->>> f.cleaned_data['last_name'] -u'Lennon' - -"auto_id" tells the Form to add an "id" attribute to each form element. -If it's a string that contains '%s', Django will use that as a format string -into which the field's name will be inserted. It will also put a