summaryrefslogtreecommitdiff
path: root/tests/regressiontests/forms
diff options
context:
space:
mode:
authorJoseph Kocherhans <joseph@jkocherhans.com>2007-09-15 22:25:52 +0000
committerJoseph Kocherhans <joseph@jkocherhans.com>2007-09-15 22:25:52 +0000
commit019e3c61e4390b0e5ad981256d6426e24083626a (patch)
tree5efefabcad63dbe68f0c2b53c4ff5100667fc24d /tests/regressiontests/forms
parentb2669113821eeb8b3cd654bbf5ab33053894b923 (diff)
newforms-admin: Merged to [6332].
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@6342 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests/regressiontests/forms')
-rw-r--r--tests/regressiontests/forms/localflavor.py748
-rw-r--r--tests/regressiontests/forms/models.py21
-rw-r--r--tests/regressiontests/forms/regressions.py6
-rw-r--r--tests/regressiontests/forms/tests.py101
-rw-r--r--tests/regressiontests/forms/util.py45
5 files changed, 905 insertions, 16 deletions
diff --git a/tests/regressiontests/forms/localflavor.py b/tests/regressiontests/forms/localflavor.py
index a896013b0d..2fe15847c7 100644
--- a/tests/regressiontests/forms/localflavor.py
+++ b/tests/regressiontests/forms/localflavor.py
@@ -980,6 +980,20 @@ u'41-3562-3464'
>>> w.render('states', 'PR')
u'<select name="states">\n<option value="AC">Acre</option>\n<option value="AL">Alagoas</option>\n<option value="AP">Amap\xe1</option>\n<option value="AM">Amazonas</option>\n<option value="BA">Bahia</option>\n<option value="CE">Cear\xe1</option>\n<option value="DF">Distrito Federal</option>\n<option value="ES">Esp\xedrito Santo</option>\n<option value="GO">Goi\xe1s</option>\n<option value="MA">Maranh\xe3o</option>\n<option value="MT">Mato Grosso</option>\n<option value="MS">Mato Grosso do Sul</option>\n<option value="MG">Minas Gerais</option>\n<option value="PA">Par\xe1</option>\n<option value="PB">Para\xedba</option>\n<option value="PR" selected="selected">Paran\xe1</option>\n<option value="PE">Pernambuco</option>\n<option value="PI">Piau\xed</option>\n<option value="RJ">Rio de Janeiro</option>\n<option value="RN">Rio Grande do Norte</option>\n<option value="RS">Rio Grande do Sul</option>\n<option value="RO">Rond\xf4nia</option>\n<option value="RR">Roraima</option>\n<option value="SC">Santa Catarina</option>\n<option value="SP">S\xe3o Paulo</option>\n<option value="SE">Sergipe</option>\n<option value="TO">Tocantins</option>\n</select>'
+# BRStateChoiceField #########################################################
+>>> from django.contrib.localflavor.br.forms import BRStateChoiceField
+>>> f = BRStateChoiceField()
+>>> ', '.join([f.clean(s) for s, _ in f.widget.choices])
+u'AC, AL, AP, AM, BA, CE, DF, ES, GO, MA, MT, MS, MG, PA, PB, PR, PE, PI, RJ, RN, RS, RO, RR, SC, SP, SE, TO'
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean('pr')
+Traceback (most recent call last):
+...
+ValidationError: [u'Select a valid brazilian state. That state is not one of the available states.']
+
# DEZipCodeField ##############################################################
>>> from django.contrib.localflavor.de.forms import DEZipCodeField
@@ -1446,4 +1460,738 @@ ValidationError: [u'National Identification Number consists of 11 digits.']
Traceback (most recent call last):
...
ValidationError: [u'National Identification Number consists of 11 digits.']
+
+# NLPhoneNumberField ########################################################
+
+>>> from django.contrib.localflavor.nl.forms import NLPhoneNumberField
+>>> f = NLPhoneNumberField(required=False)
+>>> f.clean('')
+u''
+>>> f.clean('012-3456789')
+'012-3456789'
+>>> f.clean('0123456789')
+'0123456789'
+>>> f.clean('+31-12-3456789')
+'+31-12-3456789'
+>>> f.clean('(0123) 456789')
+'(0123) 456789'
+>>> f.clean('foo')
+Traceback (most recent call last):
+ ...
+ValidationError: [u'Enter a valid phone number']
+
+# NLZipCodeField ############################################################
+
+>>> from django.contrib.localflavor.nl.forms import NLZipCodeField
+>>> f = NLZipCodeField(required=False)
+>>> f.clean('')
+u''
+>>> f.clean('1234ab')
+u'1234 AB'
+>>> f.clean('1234 ab')
+u'1234 AB'
+>>> f.clean('1234 AB')
+u'1234 AB'
+>>> f.clean('0123AB')
+Traceback (most recent call last):
+ ...
+ValidationError: [u'Enter a valid postal code']
+>>> f.clean('foo')
+Traceback (most recent call last):
+ ...
+ValidationError: [u'Enter a valid postal code']
+
+# NLSoFiNumberField #########################################################
+
+>>> from django.contrib.localflavor.nl.forms import NLSoFiNumberField
+>>> f = NLSoFiNumberField(required=False)
+>>> f.clean('')
+u''
+>>> f.clean('123456782')
+'123456782'
+>>> f.clean('000000000')
+Traceback (most recent call last):
+ ...
+ValidationError: [u'Enter a valid SoFi number']
+>>> f.clean('123456789')
+Traceback (most recent call last):
+ ...
+ValidationError: [u'Enter a valid SoFi number']
+>>> f.clean('foo')
+Traceback (most recent call last):
+ ...
+ValidationError: [u'Enter a valid SoFi number']
+
+# NLProvinceSelect ##########################################################
+
+>>> from django.contrib.localflavor.nl.forms import NLProvinceSelect
+>>> s = NLProvinceSelect()
+>>> s.render('provinces', 'OV')
+u'<select name="provinces">\n<option value="DR">Drente</option>\n<option value="FL">Flevoland</option>\n<option value="FR">Friesland</option>\n<option value="GL">Gelderland</option>\n<option value="GR">Groningen</option>\n<option value="LB">Limburg</option>\n<option value="NB">Noord-Brabant</option>\n<option value="NH">Noord-Holland</option>\n<option value="OV" selected="selected">Overijssel</option>\n<option value="UT">Utrecht</option>\n<option value="ZE">Zeeland</option>\n<option value="ZH">Zuid-Holland</option>\n</select>'
+
+# ARProvinceField #############################################################
+
+>>> from django.contrib.localflavor.ar.forms import ARProvinceSelect
+>>> f = ARProvinceSelect()
+>>> f.render('provincias', 'A')
+u'<select name="provincias">\n<option value="B">Buenos Aires</option>\n<option value="K">Catamarca</option>\n<option value="H">Chaco</option>\n<option value="U">Chubut</option>\n<option value="C">Ciudad Aut\xf3noma de Buenos Aires</option>\n<option value="X">C\xf3rdoba</option>\n<option value="W">Corrientes</option>\n<option value="E">Entre R\xedos</option>\n<option value="P">Formosa</option>\n<option value="Y">Jujuy</option>\n<option value="L">La Pampa</option>\n<option value="F">La Rioja</option>\n<option value="M">Mendoza</option>\n<option value="N">Misiones</option>\n<option value="Q">Neuqu\xe9n</option>\n<option value="R">R\xedo Negro</option>\n<option value="A" selected="selected">Salta</option>\n<option value="J">San Juan</option>\n<option value="D">San Luis</option>\n<option value="Z">Santa Cruz</option>\n<option value="S">Santa Fe</option>\n<option value="G">Santiago del Estero</option>\n<option value="V">Tierra del Fuego, Ant\xe1rtida e Islas del Atl\xe1ntico Sur</option>\n<option value="T">Tucum\xe1n</option>\n</select>'
+
+# ARPostalCodeField ###########################################################
+
+>>> from django.contrib.localflavor.ar.forms import ARPostalCodeField
+>>> f = ARPostalCodeField()
+>>> f.clean('5000')
+u'5000'
+>>> f.clean('C1064AAB')
+u'C1064AAB'
+>>> f.clean('c1064AAB')
+u'C1064AAB'
+>>> f.clean('C1064aab')
+u'C1064AAB'
+>>> f.clean(u'4400')
+u'4400'
+>>> f.clean(u'C1064AAB')
+u'C1064AAB'
+>>> f.clean('C1064AABB')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at most 8 characters (it has 9).']
+>>> f.clean('C1064AA')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format NNNN or ANNNNAAA.']
+>>> f.clean('C106AAB')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format NNNN or ANNNNAAA.']
+>>> f.clean('106AAB')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format NNNN or ANNNNAAA.']
+>>> f.clean('500')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at least 4 characters (it has 3).']
+>>> f.clean('5PPP')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format NNNN or ANNNNAAA.']
+>>> f.clean(None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean(u'')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+>>> f = ARPostalCodeField(required=False)
+>>> f.clean('5000')
+u'5000'
+>>> f.clean('C1064AAB')
+u'C1064AAB'
+>>> f.clean('c1064AAB')
+u'C1064AAB'
+>>> f.clean('C1064aab')
+u'C1064AAB'
+>>> f.clean(u'4400')
+u'4400'
+>>> f.clean(u'C1064AAB')
+u'C1064AAB'
+>>> f.clean('C1064AABB')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at most 8 characters (it has 9).']
+>>> f.clean('C1064AA')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format NNNN or ANNNNAAA.']
+>>> f.clean('C106AAB')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format NNNN or ANNNNAAA.']
+>>> f.clean('106AAB')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format NNNN or ANNNNAAA.']
+>>> f.clean('500')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at least 4 characters (it has 3).']
+>>> f.clean('5PPP')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format NNNN or ANNNNAAA.']
+>>> f.clean(None)
+u''
+>>> f.clean('')
+u''
+>>> f.clean(u'')
+u''
+
+# ARDNIField ##################################################################
+
+>>> from django.contrib.localflavor.ar.forms import ARDNIField
+>>> f = ARDNIField()
+>>> f.clean('20123456')
+u'20123456'
+>>> f.clean('20.123.456')
+u'20123456'
+>>> f.clean('9123456')
+u'9123456'
+>>> f.clean('9.123.456')
+u'9123456'
+>>> f.clean(u'20123456')
+u'20123456'
+>>> f.clean(u'20.123.456')
+u'20123456'
+>>> f.clean('20.123456')
+u'20123456'
+>>> f.clean('101234566')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field requires 7 or 8 digits.']
+>>> f.clean('W0123456')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field requires only numbers.']
+>>> f.clean('10,123,456')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field requires only numbers.']
+>>> f.clean(None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean(u'')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+>>> f = ARDNIField(required=False)
+>>> f.clean('20123456')
+u'20123456'
+>>> f.clean('20.123.456')
+u'20123456'
+>>> f.clean('9123456')
+u'9123456'
+>>> f.clean('9.123.456')
+u'9123456'
+>>> f.clean(u'20123456')
+u'20123456'
+>>> f.clean(u'20.123.456')
+u'20123456'
+>>> f.clean('20.123456')
+u'20123456'
+>>> f.clean('101234566')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field requires 7 or 8 digits.']
+>>> f.clean('W0123456')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field requires only numbers.']
+>>> f.clean('10,123,456')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field requires only numbers.']
+>>> f.clean(None)
+u''
+>>> f.clean('')
+u''
+>>> f.clean(u'')
+u''
+
+# ARCUITField #################################################################
+
+>>> from django.contrib.localflavor.ar.forms import ARCUITField
+>>> f = ARCUITField()
+>>> f.clean('20-10123456-9')
+u'20-10123456-9'
+>>> f.clean(u'20-10123456-9')
+u'20-10123456-9'
+>>> f.clean('27-10345678-4')
+u'27-10345678-4'
+>>> f.clean('20101234569')
+u'20-10123456-9'
+>>> f.clean('27103456784')
+u'27-10345678-4'
+>>> f.clean('2-10123456-9')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.']
+>>> f.clean('210123456-9')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.']
+>>> f.clean('20-10123456')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.']
+>>> f.clean('20-10123456-')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.']
+>>> f.clean('20-10123456-5')
+Traceback (most recent call last):
+...
+ValidationError: [u'Invalid CUIT.']
+>>> f.clean(u'2-10123456-9')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.']
+>>> f.clean('27-10345678-1')
+Traceback (most recent call last):
+...
+ValidationError: [u'Invalid CUIT.']
+>>> f.clean(u'27-10345678-1')
+Traceback (most recent call last):
+...
+ValidationError: [u'Invalid CUIT.']
+>>> f.clean(None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean(u'')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+>>> f = ARCUITField(required=False)
+>>> f.clean('20-10123456-9')
+u'20-10123456-9'
+>>> f.clean(u'20-10123456-9')
+u'20-10123456-9'
+>>> f.clean('27-10345678-4')
+u'27-10345678-4'
+>>> f.clean('20101234569')
+u'20-10123456-9'
+>>> f.clean('27103456784')
+u'27-10345678-4'
+>>> f.clean('2-10123456-9')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.']
+>>> f.clean('210123456-9')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.']
+>>> f.clean('20-10123456')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.']
+>>> f.clean('20-10123456-')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.']
+>>> f.clean('20-10123456-5')
+Traceback (most recent call last):
+...
+ValidationError: [u'Invalid CUIT.']
+>>> f.clean(u'2-10123456-9')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.']
+>>> f.clean('27-10345678-1')
+Traceback (most recent call last):
+...
+ValidationError: [u'Invalid CUIT.']
+>>> f.clean(u'27-10345678-1')
+Traceback (most recent call last):
+...
+ValidationError: [u'Invalid CUIT.']
+>>> f.clean(None)
+u''
+>>> f.clean('')
+u''
+>>> f.clean(u'')
+u''
+
+# CAPostalCodeField ##############################################################
+
+CAPostalCodeField validates that the data is a six-character Canadian postal code.
+>>> from django.contrib.localflavor.ca.forms import CAPostalCodeField
+>>> f = CAPostalCodeField()
+>>> f.clean('T2S 2H7')
+u'T2S 2H7'
+>>> f.clean('T2S 2H')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean('2T6 H8I')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean('T2S2H')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean(90210)
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean(None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f = CAPostalCodeField(required=False)
+>>> f.clean('T2S 2H7')
+u'T2S 2H7'
+>>> f.clean('T2S2H7')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean('T2S 2H')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean('2T6 H8I')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean('T2S2H')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean(90210)
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean(None)
+u''
+>>> f.clean('')
+u''
+
+# CAPhoneNumberField ##########################################################
+
+CAPhoneNumberField validates that the data is a valid Canadian phone number,
+including the area code. It's normalized to XXX-XXX-XXXX format.
+Note: This test is exactly the same as the USPhoneNumberField except using a real
+Candian area code
+
+>>> from django.contrib.localflavor.ca.forms import CAPhoneNumberField
+>>> f = CAPhoneNumberField()
+>>> f.clean('403-555-1212')
+u'403-555-1212'
+>>> f.clean('4035551212')
+u'403-555-1212'
+>>> f.clean('403 555-1212')
+u'403-555-1212'
+>>> f.clean('(403) 555-1212')
+u'403-555-1212'
+>>> f.clean('403 555 1212')
+u'403-555-1212'
+>>> f.clean('403.555.1212')
+u'403-555-1212'
+>>> f.clean('403.555-1212')
+u'403-555-1212'
+>>> f.clean(' (403) 555.1212 ')
+u'403-555-1212'
+>>> f.clean('555-1212')
+Traceback (most recent call last):
+...
+ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.']
+>>> f.clean('403-55-1212')
+Traceback (most recent call last):
+...
+ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.']
+>>> f.clean(None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+>>> f = CAPhoneNumberField(required=False)
+>>> f.clean('403-555-1212')
+u'403-555-1212'
+>>> f.clean('4035551212')
+u'403-555-1212'
+>>> f.clean('403 555-1212')
+u'403-555-1212'
+>>> f.clean('(403) 555-1212')
+u'403-555-1212'
+>>> f.clean('403 555 1212')
+u'403-555-1212'
+>>> f.clean('403.555.1212')
+u'403-555-1212'
+>>> f.clean('403.555-1212')
+u'403-555-1212'
+>>> f.clean(' (403) 555.1212 ')
+u'403-555-1212'
+>>> f.clean('555-1212')
+Traceback (most recent call last):
+...
+ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.']
+>>> f.clean('403-55-1212')
+Traceback (most recent call last):
+...
+ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.']
+>>> f.clean(None)
+u''
+>>> f.clean('')
+u''
+
+# CAProvinceField ################################################################
+
+CAProvinceField validates that the data is either an abbreviation or name of a
+Canadian province.
+>>> from django.contrib.localflavor.ca.forms import CAProvinceField
+>>> f = CAProvinceField()
+>>> f.clean('ab')
+u'AB'
+>>> f.clean('BC')
+u'BC'
+>>> f.clean('nova scotia')
+u'NS'
+>>> f.clean(' manitoba ')
+u'MB'
+>>> f.clean('T2S 2H7')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a Canadian province or territory.']
+>>> f.clean(None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+>>> f = CAProvinceField(required=False)
+>>> f.clean('ab')
+u'AB'
+>>> f.clean('BC')
+u'BC'
+>>> f.clean('nova scotia')
+u'NS'
+>>> f.clean(' manitoba ')
+u'MB'
+>>> f.clean('T2S 2H7')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a Canadian province or territory.']
+>>> f.clean(None)
+u''
+>>> f.clean('')
+u''
+
+# CAProvinceSelect ###############################################################
+
+CAProvinceSelect is a Select widget that uses a list of Canadian provinces/territories
+as its choices.
+>>> from django.contrib.localflavor.ca.forms import CAProvinceSelect
+>>> w = CAProvinceSelect()
+>>> print w.render('province', 'AB')
+<select name="province">
+<option value="AB" selected="selected">Alberta</option>
+<option value="BC">British Columbia</option>
+<option value="MB">Manitoba</option>
+<option value="NB">New Brunswick</option>
+<option value="NF">Newfoundland and Labrador</option>
+<option value="NT">Northwest Territories</option>
+<option value="NS">Nova Scotia</option>
+<option value="NU">Nunavut</option>
+<option value="ON">Ontario</option>
+<option value="PE">Prince Edward Island</option>
+<option value="QC">Quebec</option>
+<option value="SK">Saskatchewan</option>
+<option value="YK">Yukon</option>
+</select>
+
+# CASocialInsuranceNumberField #################################################
+>>> from django.contrib.localflavor.ca.forms import CASocialInsuranceNumberField
+>>> f = CASocialInsuranceNumberField()
+>>> f.clean('046-454-286')
+u'046-454-286'
+>>> f.clean('046-454-287')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXXX format.']
+>>> f.clean('046 454 286')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXXX format.']
+>>> f.clean('046-44-286')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXXX format.']
+
+## Generic DateField ##########################################################
+
+>>> from django.contrib.localflavor.generic.forms import *
+
+A DateField that uses generic dd/mm/yy dates instead of mm/dd/yy where
+appropriate.
+
+>>> import datetime
+>>> f = DateField()
+>>> f.clean(datetime.date(2006, 10, 25))
+datetime.date(2006, 10, 25)
+>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30))
+datetime.date(2006, 10, 25)
+>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59))
+datetime.date(2006, 10, 25)
+>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200))
+datetime.date(2006, 10, 25)
+>>> f.clean('2006-10-25')
+datetime.date(2006, 10, 25)
+>>> f.clean('25/10/2006')
+datetime.date(2006, 10, 25)
+>>> f.clean('25/10/06')
+datetime.date(2006, 10, 25)
+>>> f.clean('Oct 25 2006')
+datetime.date(2006, 10, 25)
+>>> f.clean('October 25 2006')
+datetime.date(2006, 10, 25)
+>>> f.clean('October 25, 2006')
+datetime.date(2006, 10, 25)
+>>> f.clean('25 October 2006')
+datetime.date(2006, 10, 25)
+>>> f.clean('25 October, 2006')
+datetime.date(2006, 10, 25)
+>>> f.clean('2006-4-31')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid date.']
+>>> f.clean('200a-10-25')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid date.']
+>>> f.clean('10/25/06')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid date.']
+>>> f.clean(None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+>>> f = DateField(required=False)
+>>> f.clean(None)
+>>> repr(f.clean(None))
+'None'
+>>> f.clean('')
+>>> repr(f.clean(''))
+'None'
+
+DateField accepts an optional input_formats parameter:
+>>> f = DateField(input_formats=['%Y %m %d'])
+>>> f.clean(datetime.date(2006, 10, 25))
+datetime.date(2006, 10, 25)
+>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30))
+datetime.date(2006, 10, 25)
+>>> f.clean('2006 10 25')
+datetime.date(2006, 10, 25)
+
+The input_formats parameter overrides all default input formats,
+so the default formats won't work unless you specify them:
+>>> f.clean('2006-10-25')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid date.']
+>>> f.clean('25/10/2006')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid date.']
+>>> f.clean('25/10/06')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid date.']
+
+## Generic DateTimeField ######################################################
+
+A DateField that uses generic dd/mm/yy dates instead of mm/dd/yy where
+appropriate.
+
+>>> import datetime
+>>> f = DateTimeField()
+>>> f.clean(datetime.date(2006, 10, 25))
+datetime.datetime(2006, 10, 25, 0, 0)
+>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30))
+datetime.datetime(2006, 10, 25, 14, 30)
+>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59))
+datetime.datetime(2006, 10, 25, 14, 30, 59)
+>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200))
+datetime.datetime(2006, 10, 25, 14, 30, 59, 200)
+>>> f.clean('2006-10-25 14:30:45')
+datetime.datetime(2006, 10, 25, 14, 30, 45)
+>>> f.clean('2006-10-25 14:30:00')
+datetime.datetime(2006, 10, 25, 14, 30)
+>>> f.clean('2006-10-25 14:30')
+datetime.datetime(2006, 10, 25, 14, 30)
+>>> f.clean('2006-10-25')
+datetime.datetime(2006, 10, 25, 0, 0)
+>>> f.clean('25/10/2006 14:30:45')
+datetime.datetime(2006, 10, 25, 14, 30, 45)
+>>> f.clean('25/10/2006 14:30:00')
+datetime.datetime(2006, 10, 25, 14, 30)
+>>> f.clean('25/10/2006 14:30')
+datetime.datetime(2006, 10, 25, 14, 30)
+>>> f.clean('25/10/2006')
+datetime.datetime(2006, 10, 25, 0, 0)
+>>> f.clean('25/10/06 14:30:45')
+datetime.datetime(2006, 10, 25, 14, 30, 45)
+>>> f.clean('25/10/06 14:30:00')
+datetime.datetime(2006, 10, 25, 14, 30)
+>>> f.clean('25/10/06 14:30')
+datetime.datetime(2006, 10, 25, 14, 30)
+>>> f.clean('25/10/06')
+datetime.datetime(2006, 10, 25, 0, 0)
+>>> f.clean('hello')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid date/time.']
+>>> f.clean('2006-10-25 4:30 p.m.')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid date/time.']
+
+DateField accepts an optional input_formats parameter:
+>>> f = DateTimeField(input_formats=['%Y %m %d %I:%M %p'])
+>>> f.clean(datetime.date(2006, 10, 25))
+datetime.datetime(2006, 10, 25, 0, 0)
+>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30))
+datetime.datetime(2006, 10, 25, 14, 30)
+>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59))
+datetime.datetime(2006, 10, 25, 14, 30, 59)
+>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200))
+datetime.datetime(2006, 10, 25, 14, 30, 59, 200)
+>>> f.clean('2006 10 25 2:30 PM')
+datetime.datetime(2006, 10, 25, 14, 30)
+
+The input_formats parameter overrides all default input formats,
+so the default formats won't work unless you specify them:
+>>> f.clean('2006-10-25 14:30:45')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid date/time.']
+
+>>> f = DateTimeField(required=False)
+>>> f.clean(None)
+>>> repr(f.clean(None))
+'None'
+>>> f.clean('')
+>>> repr(f.clean(''))
+'None'
+
"""
diff --git a/tests/regressiontests/forms/models.py b/tests/regressiontests/forms/models.py
index e69de29bb2..f4f8607193 100644
--- a/tests/regressiontests/forms/models.py
+++ b/tests/regressiontests/forms/models.py
@@ -0,0 +1,21 @@
+from django.db import models
+
+class BoundaryModel(models.Model):
+ positive_integer = models.PositiveIntegerField(null=True, blank=True)
+
+__test__ = {'API_TESTS': """
+>>> from django.newforms import form_for_model
+
+# Boundary conditions on a PostitiveIntegerField #########################
+>>> BoundaryForm = form_for_model(BoundaryModel)
+>>> f = BoundaryForm({'positive_integer':100})
+>>> f.is_valid()
+True
+>>> f = BoundaryForm({'positive_integer':0})
+>>> f.is_valid()
+True
+>>> f = BoundaryForm({'positive_integer':-100})
+>>> f.is_valid()
+False
+
+"""} \ No newline at end of file
diff --git a/tests/regressiontests/forms/regressions.py b/tests/regressiontests/forms/regressions.py
index df2ef578a1..3212e20170 100644
--- a/tests/regressiontests/forms/regressions.py
+++ b/tests/regressiontests/forms/regressions.py
@@ -60,6 +60,12 @@ Translated error messages used to be buggy.
u'<ul class="errorlist"><li>\u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043b\u0435.</li></ul>\n<p><label for="id_somechoice_0">\xc5\xf8\xdf:</label> <ul>\n<li><label><input type="radio" id="id_somechoice_0" value="\xc5" name="somechoice" /> En tied\xe4</label></li>\n<li><label><input type="radio" id="id_somechoice_1" value="\xf8" name="somechoice" /> Mies</label></li>\n<li><label><input type="radio" id="id_somechoice_2" value="\xdf" name="somechoice" /> Nainen</label></li>\n</ul></p>'
>>> deactivate()
+Deep copying translated text shouldn't raise an error
+>>> from django.utils.translation import gettext_lazy
+>>> class CopyForm(Form):
+... degree = IntegerField(widget=Select(choices=((1, gettext_lazy('test')),)))
+>>> f = CopyForm()
+
#######################
# Miscellaneous Tests #
#######################
diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py
index 0284449a59..104557be34 100644
--- a/tests/regressiontests/forms/tests.py
+++ b/tests/regressiontests/forms/tests.py
@@ -3,6 +3,7 @@ from localflavor import localflavor_tests
from regressions import regression_tests
from formsets import formset_tests
from media import media_tests
+from util import util_tests
form_tests = r"""
>>> from django.newforms import *
@@ -962,6 +963,12 @@ True
Traceback (most recent call last):
...
ValidationError: [u'Enter a whole number.']
+>>> f.clean(42)
+42
+>>> f.clean(3.14)
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a whole number.']
>>> f.clean('1 ')
1
>>> f.clean(' 1')
@@ -1085,6 +1092,10 @@ True
23.0
>>> f.clean('3.14')
3.1400000000000001
+>>> f.clean(3.14)
+3.1400000000000001
+>>> f.clean(42)
+42.0
>>> f.clean('a')
Traceback (most recent call last):
...
@@ -1143,6 +1154,10 @@ True
Decimal("23")
>>> f.clean('3.14')
Decimal("3.14")
+>>> f.clean(3.14)
+Decimal("3.14")
+>>> f.clean(Decimal('3.14'))
+Decimal("3.14")
>>> f.clean('a')
Traceback (most recent call last):
...
@@ -1608,18 +1623,22 @@ ValidationError: [u'This field is required.']
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
+>>> f.clean('http://localhost')
+u'http://localhost'
>>> f.clean('http://example.com')
u'http://example.com'
>>> f.clean('http://www.example.com')
u'http://www.example.com'
+>>> f.clean('http://www.example.com:8000/test')
+u'http://www.example.com:8000/test'
+>>> f.clean('http://200.8.9.10')
+u'http://200.8.9.10'
+>>> f.clean('http://200.8.9.10:8000/test')
+u'http://200.8.9.10:8000/test'
>>> f.clean('foo')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid URL.']
->>> f.clean('example.com')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid URL.']
>>> f.clean('http://')
Traceback (most recent call last):
...
@@ -1650,10 +1669,6 @@ u'http://www.example.com'
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid URL.']
->>> f.clean('example.com')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid URL.']
>>> f.clean('http://')
Traceback (most recent call last):
...
@@ -1707,6 +1722,15 @@ Traceback (most recent call last):
...
ValidationError: [u'Ensure this value has at most 20 characters (it has 37).']
+URLField should prepend 'http://' if no scheme was given
+>>> f = URLField(required=False)
+>>> f.clean('example.com')
+u'http://example.com'
+>>> f.clean('')
+u''
+>>> f.clean('https://example.com')
+u'https://example.com'
+
# BooleanField ################################################################
>>> f = BooleanField()
@@ -2683,16 +2707,24 @@ to the next.
... super(Person, self).__init__(*args, **kwargs)
... if names_required:
... self.fields['first_name'].required = True
+... self.fields['first_name'].widget.attrs['class'] = 'required'
... self.fields['last_name'].required = True
+... self.fields['last_name'].widget.attrs['class'] = 'required'
>>> f = Person(names_required=False)
>>> f['first_name'].field.required, f['last_name'].field.required
(False, False)
+>>> f['first_name'].field.widget.attrs, f['last_name'].field.widget.attrs
+({}, {})
>>> f = Person(names_required=True)
>>> f['first_name'].field.required, f['last_name'].field.required
(True, True)
+>>> f['first_name'].field.widget.attrs, f['last_name'].field.widget.attrs
+({'class': 'required'}, {'class': 'required'})
>>> f = Person(names_required=False)
>>> f['first_name'].field.required, f['last_name'].field.required
(False, False)
+>>> f['first_name'].field.widget.attrs, f['last_name'].field.widget.attrs
+({}, {})
>>> class Person(Form):
... first_name = CharField(max_length=30)
... last_name = CharField(max_length=30)
@@ -3796,14 +3828,6 @@ u'1'
>>> smart_unicode('foo')
u'foo'
-# flatatt tests
->>> from django.newforms.util import flatatt
->>> flatatt({'id': "header"})
-u' id="header"'
->>> flatatt({'class': "news", 'title': "Read this"})
-u' class="news" title="Read this"'
->>> flatatt({})
-u''
####################################
# Test accessing errors in clean() #
@@ -3823,6 +3847,50 @@ u''
True
>>> f.cleaned_data['username']
u'sirrobin'
+
+#######################################
+# Test overriding ErrorList in a form #
+#######################################
+
+>>> from django.newforms.util import ErrorList
+>>> class DivErrorList(ErrorList):
+... def __unicode__(self):
+... return self.as_divs()
+... def as_divs(self):
+... if not self: return u''
+... return u'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' % e for e in self])
+>>> class CommentForm(Form):
+... name = CharField(max_length=50, required=False)
+... email = EmailField()
+... comment = CharField()
+>>> data = dict(email='invalid')
+>>> f = CommentForm(data, auto_id=False, error_class=DivErrorList)
+>>> print f.as_p()
+<p>Name: <input type="text" name="name" maxlength="50" /></p>
+<div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div>
+<p>Email: <input type="text" name="email" value="invalid" /></p>
+<div class="errorlist"><div class="error">This field is required.</div></div>
+<p>Comment: <input type="text" name="comment" /></p>
+
+#################################
+# Test multipart-encoded form #
+#################################
+
+>>> class FormWithoutFile(Form):
+... username = CharField()
+>>> class FormWithFile(Form):
+... username = CharField()
+... file = FileField()
+>>> class FormWithImage(Form):
+... image = ImageField()
+
+>>> FormWithoutFile().is_multipart()
+False
+>>> FormWithFile().is_multipart()
+True
+>>> FormWithImage().is_multipart()
+True
+
"""
__test__ = {
@@ -3831,6 +3899,7 @@ __test__ = {
'regressions': regression_tests,
'formset_tests': formset_tests,
'media_tests': media_tests,
+ 'util_tests': util_tests,
}
if __name__ == "__main__":
diff --git a/tests/regressiontests/forms/util.py b/tests/regressiontests/forms/util.py
new file mode 100644
index 0000000000..1a02b7e55b
--- /dev/null
+++ b/tests/regressiontests/forms/util.py
@@ -0,0 +1,45 @@
+# coding: utf-8
+"""
+Tests for newforms/util.py module.
+"""
+
+util_tests = r"""
+>>> from django.newforms.util import *
+>>> from django.utils.translation import ugettext_lazy
+
+###########
+# flatatt #
+###########
+
+>>> from django.newforms.util import flatatt
+>>> flatatt({'id': "header"})
+u' id="header"'
+>>> flatatt({'class': "news", 'title': "Read this"})
+u' class="news" title="Read this"'
+>>> flatatt({})
+u''
+
+###################
+# ValidationError #
+###################
+
+# Can take a string.
+>>> print ValidationError("There was an error.").messages
+<ul class="errorlist"><li>There was an error.</li></ul>
+
+# Can take a unicode string.
+>>> print ValidationError(u"Not \u03C0.").messages
+<ul class="errorlist"><li>Not π.</li></ul>
+
+# Can take a lazy string.
+>>> print ValidationError(ugettext_lazy("Error.")).messages
+<ul class="errorlist"><li>Error.</li></ul>
+
+# Can take a list.
+>>> print ValidationError(["Error one.", "Error two."]).messages
+<ul class="errorlist"><li>Error one.</li><li>Error two.</li></ul>
+
+# Can take a mixture in a list.
+>>> print ValidationError(["First error.", u"Not \u03C0.", ugettext_lazy("Error.")]).messages
+<ul class="errorlist"><li>First error.</li><li>Not π.</li><li>Error.</li></ul>
+"""