diff options
| author | Joseph Kocherhans <joseph@jkocherhans.com> | 2007-09-15 22:25:52 +0000 |
|---|---|---|
| committer | Joseph Kocherhans <joseph@jkocherhans.com> | 2007-09-15 22:25:52 +0000 |
| commit | 019e3c61e4390b0e5ad981256d6426e24083626a (patch) | |
| tree | 5efefabcad63dbe68f0c2b53c4ff5100667fc24d /tests/regressiontests/forms | |
| parent | b2669113821eeb8b3cd654bbf5ab33053894b923 (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.py | 748 | ||||
| -rw-r--r-- | tests/regressiontests/forms/models.py | 21 | ||||
| -rw-r--r-- | tests/regressiontests/forms/regressions.py | 6 | ||||
| -rw-r--r-- | tests/regressiontests/forms/tests.py | 101 | ||||
| -rw-r--r-- | tests/regressiontests/forms/util.py | 45 |
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> +""" |
