Ticket #16497: mx_localflavors-1.3.diff
File mx_localflavors-1.3.diff, 23.4 KB (added by , 13 years ago) |
---|
-
AUTHORS
diff --git a/AUTHORS b/AUTHORS index a19e49b..6dfb6f2 100644
a b answer newbie questions, and generally made Django that much better: 528 528 Gasper Zejn <zejn@kiberpipa.org> 529 529 Jarek Zgoda <jarek.zgoda@gmail.com> 530 530 Cheng Zhang 531 Gerardo Orozco <gerardo.orozco.mosqueda@gmail.com> 532 Andrés Torres Marroquín <andres.torres.marroquin@gmail.com> 531 533 532 534 A big THANK YOU goes to: 533 535 -
django/contrib/localflavor/mx/forms.py
diff --git a/django/contrib/localflavor/mx/forms.py b/django/contrib/localflavor/mx/forms.py index 9581937..7a10f90 100644
a b 1 # -*- coding: utf-8 -*- 1 2 """ 2 3 Mexican-specific form helpers. 3 4 """ 4 5 5 from django.forms.fields import Select 6 from django.forms import ValidationError 7 from django.forms.fields import Select, RegexField, CharField 8 from django.utils.translation import ugettext_lazy as _ 9 from django.core.validators import EMPTY_VALUES 10 from django.contrib.localflavor.mx.mx_states import STATE_CHOICES 11 import re 12 13 DATE_RE = r'\d{2}((01|03|05|07|08|10|12)(0[1-9]|[12]\d|3[01])|02(0[1-9]|[12]\d)|(04|06|09|11)(0[1-9]|[12]\d|30))' 14 15 """ 16 This is the list of inconvenient words according to the `Anexo IV` of the 17 document described in the next link: 18 www.sisi.org.mx/jspsi/documentos/2005/seguimiento/06101/0610100162005_065.doc 19 """ 20 21 RFC_INCONVENIENT_WORDS = [ 22 u'BUEI', u'BUEY', u'CACA', u'CACO', u'CAGA', u'CAGO', u'CAKA', u'CAKO', 23 u'COGE', u'COJA', u'COJE', u'COJI', u'COJO', u'CULO', u'FETO', u'GUEY', 24 u'JOTO', u'KACA', u'KACO', u'KAGA', u'KAGO', u'KOGE', u'KOJO', u'KAKA', 25 u'KULO', u'MAME', u'MAMO', u'MEAR', u'MEAS', u'MEON', u'MION', u'MOCO', 26 u'MULA', u'PEDA', u'PEDO', u'PENE', u'PUTA', u'PUTO', u'QULO', u'RATA', 27 u'RUIN' 28 ] 29 30 """ 31 This is the list of inconvenient words according to the `Anexo 2` of the 32 document described in the next link: 33 http://portal.veracruz.gob.mx/pls/portal/url/ITEM/444112558A57C6E0E040A8C02E00695C 34 """ 35 CURP_INCONVENIENT_WORDS = [ 36 u'BACA', u'BAKA', u'BUEI', u'BUEY', u'CACA', u'CACO', u'CAGA', u'CAGO', 37 u'CAKA', u'CAKO', u'COGE', u'COGI', u'COJA', u'COJE', u'COJI', u'COJO', 38 u'COLA', u'CULO', u'FALO', u'FETO', u'GETA', u'GUEI', u'GUEY', u'JETA', 39 u'JOTO', u'KACA', u'KACO', u'KAGA', u'KAGO', u'KAKA', u'KAKO', u'KOGE', 40 u'KOGI', u'KOJA', u'KOJE', u'KOJI', u'KOJO', u'KOLA', u'KULO', u'LILO', 41 u'LOCA', u'LOCO', u'LOKA', u'LOKO', u'MAME', u'MAMO', u'MEAR', u'MEAS', 42 u'MEON', u'MIAR', u'MION', u'MOCO', u'MOKO', u'MULA', u'MULO', u'NACA', 43 u'NACO', u'PEDA', u'PEDO', u'PENE', u'PIPI', u'PITO', u'POPO', u'PUTA', 44 u'PUTO', u'QULO', u'RATA', u'ROBA', u'ROBE', u'ROBO', u'RUIN', u'SENO', 45 u'TETA', u'VACA', u'VAGA', u'VAGO', u'VAKA', u'VUEI', u'VUEY', u'WUEI', 46 u'WUEY' 47 ] 6 48 7 49 class MXStateSelect(Select): 8 50 """ 9 51 A Select widget that uses a list of Mexican states as its choices. 10 52 """ 11 53 def __init__(self, attrs=None): 12 from mx_states import STATE_CHOICES13 54 super(MXStateSelect, self).__init__(attrs, choices=STATE_CHOICES) 14 55 56 class MXZipCodeField(RegexField): 57 """ 58 A field that accepts a Mexican Zip Code. 59 60 More info about this: 61 http://en.wikipedia.org/wiki/List_of_postal_codes_in_Mexico 62 """ 63 default_error_messages = { 64 'invalid': _(u'Enter a valid zip code in the format XXXXX.'), 65 } 66 67 def __init__(self, *args, **kwargs): 68 zip_code_re = ur'^(0[1-9]|[1][0-6]|[2-9]\d)(\d{3})$' 69 super(MXZipCodeField, self).__init__(zip_code_re, *args, **kwargs) 70 71 class MXRFCField(RegexField): 72 """ 73 A field that validates a Mexican `Registro Federal de Contribuyentes` for 74 either `Persona física` or `Persona moral`. 75 76 The `Persona física` RFC string is integrated by a juxtaposition of characters 77 following the next pattern: 78 Index Format Accepted Characters 79 1 X Any letter 80 2 X Any vowel 81 3-4 XX Any letter 82 5-10 YYMMDD Any valid date 83 11-12 XX Any letter or number between 0 and 9 84 13 X Any digit between 0 and 9 or the letter `A` 85 86 The `Persona moral` RFC string is integrated by a juxtaposition of characters 87 following the next pattern: 88 Index Format Accepted Characters 89 1-3 XXX Any letter including `&` and `Ñ` chars 90 4-9 YYMMDD Any valid date 91 10-11 XX Any letter or number between 0 and 9 92 12 X Any number between 0 and 9 or the letter `A` 93 94 More info about this: 95 http://es.wikipedia.org/wiki/Registro_Federal_de_Contribuyentes_(M%C3%A9xico) 96 """ 97 default_error_messages = { 98 'invalid': _(u'Enter a valid RFC.'), 99 'invalid_checksum': _(u'Invalid checksum for RFC.'), 100 } 101 102 def __init__(self, min_length=9, max_length=13, *args, **kwargs): 103 rfc_re = re.compile(ur'^([A-Z&Ññ]{3}|[A-Z][AEIOU][A-Z]{2})%s([A-Z0-9]{2}[0-9A])?$' % DATE_RE, 104 re.IGNORECASE) 105 super(MXRFCField, self).__init__(rfc_re, min_length=min_length, 106 max_length=max_length, *args, **kwargs) 107 108 def clean(self, value): 109 value = super(MXRFCField, self).clean(value) 110 if value in EMPTY_VALUES: 111 return u'' 112 value = value.upper() 113 if self._has_homoclave(value): 114 if not value[-1] == self._checksum(value[:-1]): 115 raise ValidationError(self.default_error_messages['invalid_checksum']) 116 if self._has_inconvenient_word(value): 117 raise ValidationError(self.default_error_messages['invalid']) 118 return value 119 120 def _has_homoclave(self, rfc): 121 """ 122 This check is done due to the existance of RFCs without a `homoclave` 123 since the current algorithm to calculate it had not been created for 124 the first RFCs ever in Mexico. 125 """ 126 rfc_without_homoclave_re = re.compile(ur'^[A-Z&Ññ]{3,4}%s$' % DATE_RE, 127 re.IGNORECASE) 128 return not rfc_without_homoclave_re.match(rfc) 129 130 def _checksum(self, rfc): 131 """ 132 More info about this procedure: 133 www.sisi.org.mx/jspsi/documentos/2005/seguimiento/06101/0610100162005_065.doc 134 """ 135 chars = u'0123456789ABCDEFGHIJKLMN&OPQRSTUVWXYZ-Ñ' 136 if len(rfc) is 11: 137 rfc = '-' + rfc 138 139 sum_ = sum(i * chars.index(c) for i, c in zip(reversed(xrange(14)), rfc)) 140 checksum = 11 - sum_ % 11 141 142 if checksum == 10: 143 return u'A' 144 elif checksum == 11: 145 return u'0' 146 else: 147 return unicode(checksum) 148 149 def _has_inconvenient_word(self, rfc): 150 first_four = rfc[:4] 151 return first_four in RFC_INCONVENIENT_WORDS 152 153 class MXCURPField(RegexField): 154 """ 155 A field that validates a Mexican `Clave Única de Registro de Población`. 156 157 The CURP is integrated by a juxtaposition of characters following the next 158 pattern: 159 160 Index Format Accepted Characters 161 1 X Any letter 162 2 X Any vowel 163 3-4 XX Any letter 164 5-10 YYMMDD Any valid date 165 11 X Either `H` or `M`, depending on the person's gender 166 12-13 XX Any valid acronym for a state in Mexico 167 14-16 XXX Any consonant 168 17 X Any number between 0 and 9 or any letter 169 18 X Any number between 0 and 9 170 171 More info about this: 172 http://www.condusef.gob.mx/index.php/clave-unica-de-registro-de-poblacion-curp 173 """ 174 default_error_messages = { 175 'invalid': _('Enter a valid CURP.'), 176 'invalid_checksum': _(u'Invalid checksum for CURP.'), 177 } 178 179 def __init__(self, min_length=18, max_length=18, *args, **kwargs): 180 states_re = r'(AS|BC|BS|CC|CL|CM|CS|CH|DF|DG|GT|GR|HG|JC|MC|MN|MS|NT|NL|OC|PL|QT|QR|SP|SL|SR|TC|TS|TL|VZ|YN|ZS|NE)' 181 consonants_re = r'[B-DF-HJ-NP-TV-Z]' 182 curp_re = ur'^[A-Z][AEIOU][A-Z]{2}%s[HM]%s%s{3}[0-9A-Z]\d$' % (DATE_RE, states_re, 183 consonants_re) 184 curp_re = re.compile(curp_re, re.IGNORECASE) 185 super(MXCURPField, self).__init__(curp_re, min_length=min_length, 186 max_length=max_length, *args, **kwargs) 187 188 def clean(self, value): 189 value = super(MXCURPField, self).clean(value) 190 if value in EMPTY_VALUES: 191 return u'' 192 value = value.upper() 193 if value[-1] != self._checksum(value[:-1]): 194 raise ValidationError(self.default_error_messages['invalid_checksum']) 195 if self._has_inconvenient_word(value): 196 raise ValidationError(self.default_error_messages['invalid']) 197 return value 198 199 def _checksum(self, value): 200 chars = u'0123456789ABCDEFGHIJKLMN&OPQRSTUVWXYZ' 201 202 s = sum(i * chars.index(c) for i, c in zip(reversed(xrange(19)), value)) 203 checksum = 10 - s % 10 204 205 if checksum == 10: 206 return u'0' 207 return unicode(checksum) 208 209 def _has_inconvenient_word(self, curp): 210 first_four = curp[:4] 211 return first_four in CURP_INCONVENIENT_WORDS -
new file django/contrib/localflavor/mx/models.py
diff --git a/django/contrib/localflavor/mx/models.py b/django/contrib/localflavor/mx/models.py new file mode 100644 index 0000000..dbeaaa6
- + 1 from django.utils.translation import ugettext_lazy as _ 2 from django.db.models.fields import CharField 3 from django.contrib.localflavor.mx.mx_states import STATE_CHOICES 4 5 class MXStateField(CharField): 6 """ 7 A model field that uses a list of Mexican states as its choices. 8 """ 9 10 description = _("Mexico state (three uppercase letters)") 11 12 def __init__(self, *args, **kwargs): 13 kwargs['choices'] = STATE_CHOICES 14 kwargs['max_length'] = 3 15 super(MXStateField, self).__init__(*args, **kwargs) 16 17 class MXZipCodeField(CharField): 18 """ 19 A model field that forms represent as a forms.MXZipCodeField field and 20 stores the five-digit Mexican zip code. 21 """ 22 23 description = _("Mexico zip code") 24 25 def __init__(self, *args, **kwargs): 26 kwargs['max_length'] = 5 27 super(MXZipCodeField, self).__init__(*args, **kwargs) 28 29 def formfield(self, **kwargs): 30 from django.contrib.localflavor.mx.forms import MXZipCodeField as Field 31 defaults = {'form_class': Field} 32 defaults.update(kwargs) 33 return super(MXZipCodeField, self).formfield(**defaults) 34 35 class MXRFCField(CharField): 36 """ 37 A model field that forms represent as a forms.MXRFCField field and 38 stores the value of a valid Mexican RFC. 39 """ 40 41 description = _("Mexican RFC") 42 43 def __init__(self, *args, **kwargs): 44 kwargs['max_length'] = 13 45 super(MXRFCField, self).__init__(*args, **kwargs) 46 47 def formfield(self, **kwargs): 48 from django.contrib.localflavor.mx.forms import MXRFCField as Field 49 defaults = {'form_class': Field} 50 defaults.update(kwargs) 51 return super(MXRFCField, self).formfield(**defaults) 52 53 class MXCURPField(CharField): 54 """ 55 A model field that forms represent as a forms.MXCURPField field and 56 stores the value of a valid Mexican CURP. 57 """ 58 59 description = _("Mexican CURP") 60 61 def __init__(self, *args, **kwargs): 62 kwargs['max_length'] = 18 63 super(MXCURPField, self).__init__(*args, **kwargs) 64 65 def formfield(self, **kwargs): 66 from django.contrib.localflavor.mx.forms import MXCURPField as Field 67 defaults = {'form_class': Field} 68 defaults.update(kwargs) 69 return super(MXCURPField, self).formfield(**defaults) 70 No newline at end of file -
new file tests/regressiontests/forms/localflavor/mx.py
diff --git a/tests/regressiontests/forms/localflavor/mx.py b/tests/regressiontests/forms/localflavor/mx.py new file mode 100644 index 0000000..1ffc11c
- + 1 # -*- coding: utf-8 -*- 2 from django.contrib.localflavor.mx.forms import (MXZipCodeField, MXRFCField, 3 MXStateSelect, MXCURPField) 4 5 from utils import LocalFlavorTestCase 6 7 8 class MXLocalFlavorTests(LocalFlavorTestCase): 9 def test_MXStateSelect(self): 10 f = MXStateSelect() 11 out = u'''<select name="state"> 12 <option value="AGU">Aguascalientes</option> 13 <option value="BCN">Baja California</option> 14 <option value="BCS">Baja California Sur</option> 15 <option value="CAM">Campeche</option> 16 <option value="CHH">Chihuahua</option> 17 <option value="CHP">Chiapas</option> 18 <option value="COA">Coahuila</option> 19 <option value="COL">Colima</option> 20 <option value="DIF">Distrito Federal</option> 21 <option value="DUR">Durango</option> 22 <option value="GRO">Guerrero</option> 23 <option value="GUA">Guanajuato</option> 24 <option value="HID">Hidalgo</option> 25 <option value="JAL">Jalisco</option> 26 <option value="MEX">Estado de México</option> 27 <option value="MIC" selected="selected">Michoacán</option> 28 <option value="MOR">Morelos</option> 29 <option value="NAY">Nayarit</option> 30 <option value="NLE">Nuevo León</option> 31 <option value="OAX">Oaxaca</option> 32 <option value="PUE">Puebla</option> 33 <option value="QUE">Querétaro</option> 34 <option value="ROO">Quintana Roo</option> 35 <option value="SIN">Sinaloa</option> 36 <option value="SLP">San Luis Potosí</option> 37 <option value="SON">Sonora</option> 38 <option value="TAB">Tabasco</option> 39 <option value="TAM">Tamaulipas</option> 40 <option value="TLA">Tlaxcala</option> 41 <option value="VER">Veracruz</option> 42 <option value="YUC">Yucatán</option> 43 <option value="ZAC">Zacatecas</option> 44 </select>''' 45 self.assertEqual(f.render('state', 'MIC'), out) 46 47 def test_MXZipCodeField(self): 48 error_format = [u'Enter a valid zip code in the format XXXXX.'] 49 valid = { 50 '58120': u'58120', 51 '58502': u'58502', 52 '59310': u'59310', 53 '99999': u'99999', 54 } 55 invalid = { 56 '17000': error_format, 57 '18000': error_format, 58 '19000': error_format, 59 '00000': error_format, 60 } 61 self.assertFieldOutput(MXZipCodeField, valid, invalid) 62 63 def test_MXRFCField(self): 64 error_format = [u'Enter a valid RFC.'] 65 error_checksum = [u'Invalid checksum for RFC.'] 66 valid = { 67 'MoFN641205eX5': u'MOFN641205EX5', 68 'ICa060120873': u'ICA060120873', 69 'eUcG751104rT0': u'EUCG751104RT0', 70 'GME08100195A': u'GME08100195A', 71 'AA&060524KX5': u'AA&060524KX5', 72 'CAÑ0708045P7': u'CAÑ0708045P7', 73 'aaa000101aa9': u'AAA000101AA9', 74 } 75 invalid = { 76 'MED0000000XA': error_format, 77 '0000000000XA': error_format, 78 'AAA000000AA6': error_format, 79 # Dates 80 'XXX880002XXX': error_format, 81 'XXX880200XXX': error_format, 82 'XXX880132XXX': error_format, 83 'XXX880230XXX': error_format, 84 'XXX880431XXX': error_format, 85 # Incorrect checksum 86 'MOGR650524E73': error_checksum, 87 'HVA7810058F1': error_checksum, 88 'MoFN641205eX2': error_checksum, 89 'ICa060120871': error_checksum, 90 'eUcG751104rT7': error_checksum, 91 'GME081001955': error_checksum, 92 'AA&060524KX9': error_checksum, 93 'CAÑ0708045P2': error_checksum, 94 } 95 self.assertFieldOutput(MXRFCField, valid, invalid) 96 97 def test_MXCURPField(self): 98 error_format = [u'Enter a valid CURP.'] 99 error_checksum = [u'Invalid checksum for CURP.'] 100 valid = { 101 'AaMG890608HDFLJL00': u'AAMG890608HDFLJL00', 102 'BAAd890419HMNRRV07': u'BAAD890419HMNRRV07', 103 'VIAA900930MMNClL08': u'VIAA900930MMNCLL08', 104 'HEGR891009HMNRRD09': u'HEGR891009HMNRRD09', 105 'MARR890512HMNRMN09': u'MARR890512HMNRMN09', 106 'MESJ890928HMNZNS00': u'MESJ890928HMNZNS00', 107 'BAAA890317HDFRLL03': u'BAAA890317HDFRLL03', 108 'TOMA880125HMNRRNO2': u'TOMA880125HMNRRNO2', 109 'OOMG890727HMNRSR06': u'OOMG890727HMNRSR06', 110 'AAAA000101HDFCCC09': u'AAAA000101HDFCCC09', 111 } 112 invalid = { 113 'AAAA000000HDFCCC09': error_format, 114 'AAAA000000HDFAAA03': error_format, 115 'AAAA000000HXXCCC08': error_format, 116 'AAAA000000XMNCCC02': error_format, 117 'HEGR891009HMNRRD0A': error_format, 118 'MARR890512HMNRMN0A': error_format, 119 'AaMG890608HDFLJL01': error_checksum, 120 'BAAd890419HMNRRV08': error_checksum, 121 'VIAA900930MMNClL09': error_checksum, 122 'MESJ890928HMNZNS01': error_checksum, 123 'BAAA890317HDFRLL04': error_checksum, 124 'TOMA880125HMNRRNO3': error_checksum, 125 'OOMG890727HMNRSR07': error_checksum, 126 } 127 self.assertFieldOutput(MXCURPField, valid, invalid) -
tests/regressiontests/forms/localflavortests.py
diff --git a/tests/regressiontests/forms/localflavortests.py b/tests/regressiontests/forms/localflavortests.py index 5ee1c32..d8a57bd 100644
a b from localflavor.is_ import ISLocalFlavorTests 19 19 from localflavor.it import ITLocalFlavorTests 20 20 from localflavor.jp import JPLocalFlavorTests 21 21 from localflavor.kw import KWLocalFlavorTests 22 from localflavor.mx import MXLocalFlavorTests 22 23 from localflavor.nl import NLLocalFlavorTests 23 24 from localflavor.pl import PLLocalFlavorTests 24 25 from localflavor.pt import PTLocalFlavorTests -
tests/regressiontests/forms/tests/__init__.py
diff --git a/tests/regressiontests/forms/tests/__init__.py b/tests/regressiontests/forms/tests/__init__.py index 2d96b2f..561e4c9 100644
a b from regressiontests.forms.localflavortests import ( 19 19 FRLocalFlavorTests, GenericLocalFlavorTests, IDLocalFlavorTests, 20 20 IELocalFlavorTests, ILLocalFlavorTests, ISLocalFlavorTests, 21 21 ITLocalFlavorTests, JPLocalFlavorTests, KWLocalFlavorTests, 22 NLLocalFlavorTests, PLLocalFlavorTests, PTLocalFlavorTests,23 ROLocalFlavorTests, SELocalFlavorTests, SKLocalFlavorTests,24 TRLocalFlavorTests, UKLocalFlavorTests, USLocalFlavorTests,25 U YLocalFlavorTests, ZALocalFlavorTests22 MXLocalFlavorTests, NLLocalFlavorTests, PLLocalFlavorTests, 23 PTLocalFlavorTests, ROLocalFlavorTests, SELocalFlavorTests, 24 SKLocalFlavorTests, TRLocalFlavorTests, UKLocalFlavorTests, 25 USLocalFlavorTests, UYLocalFlavorTests, ZALocalFlavorTests 26 26 ) -
new file tests/regressiontests/localflavor/mx/forms.py
diff --git a/tests/regressiontests/localflavor/mx/__init__.py b/tests/regressiontests/localflavor/mx/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/regressiontests/localflavor/mx/forms.py b/tests/regressiontests/localflavor/mx/forms.py new file mode 100644 index 0000000..8a45781
- + 1 from django.forms import ModelForm 2 from models import MXPersonProfile 3 4 class MXPersonProfileForm(ModelForm): 5 """docstring for MXPersonProfileForm""" 6 class Meta: 7 model = MXPersonProfile -
new file tests/regressiontests/localflavor/mx/models.py
diff --git a/tests/regressiontests/localflavor/mx/models.py b/tests/regressiontests/localflavor/mx/models.py new file mode 100644 index 0000000..81a5018
- + 1 from django.db import models 2 from django.contrib.localflavor.mx.models import (MXStateField, 3 MXRFCField, MXCURPField, MXZipCodeField) 4 5 # When creating models you need to remember to add a app_label as 6 # 'localflavor', so your model can be found 7 8 class MXPersonProfile(models.Model): 9 state = MXStateField() 10 rfc = MXRFCField() 11 curp = MXCURPField() 12 zip_code = MXZipCodeField() 13 class Meta: 14 app_label = 'localflavor' -
new file tests/regressiontests/localflavor/mx/tests.py
diff --git a/tests/regressiontests/localflavor/mx/tests.py b/tests/regressiontests/localflavor/mx/tests.py new file mode 100644 index 0000000..40da38a
- + 1 # -*- coding: utf-8 -*- 2 from django.test import TestCase 3 from forms import MXPersonProfileForm 4 5 class MXLocalFlavorTests(TestCase): 6 def setUp(self): 7 self.form = MXPersonProfileForm({ 8 'state': 'MIC', 9 'rfc': 'toma880125kv3', 10 'curp': 'toma880125hmnrrn02', 11 'zip_code': '58120', 12 }) 13 14 def test_get_display_methods(self): 15 """Test that the get_*_display() methods are added to the model instances.""" 16 place = self.form.save() 17 self.assertEqual(place.get_state_display(), u'Michoacán') 18 19 def test_errors(self): 20 """Test that required MXFields throw appropriate errors.""" 21 form = MXPersonProfileForm({ 22 'state': 'Invalid state', 23 'rfc': 'invalid rfc', 24 'curp': 'invalid curp', 25 'zip_code': 'xxx', 26 }) 27 self.assertFalse(form.is_valid()) 28 self.assertEqual(form.errors['state'], [u'Select a valid choice. Invalid state is not one of the available choices.']) 29 self.assertEqual(form.errors['rfc'], [u'Enter a valid RFC.']) 30 self.assertEqual(form.errors['curp'], [u'Ensure this value has at least 18 characters (it has 12).', u'Enter a valid CURP.']) 31 self.assertEqual(form.errors['zip_code'], [u'Enter a valid zip code in the format XXXXX.']) 32 33 def test_field_blank_option(self): 34 """Test that the empty option is there.""" 35 state_select_html = """\ 36 <select name="state" id="id_state"> 37 <option value="">---------</option> 38 <option value="AGU">Aguascalientes</option> 39 <option value="BCN">Baja California</option> 40 <option value="BCS">Baja California Sur</option> 41 <option value="CAM">Campeche</option> 42 <option value="CHH">Chihuahua</option> 43 <option value="CHP">Chiapas</option> 44 <option value="COA">Coahuila</option> 45 <option value="COL">Colima</option> 46 <option value="DIF">Distrito Federal</option> 47 <option value="DUR">Durango</option> 48 <option value="GRO">Guerrero</option> 49 <option value="GUA">Guanajuato</option> 50 <option value="HID">Hidalgo</option> 51 <option value="JAL">Jalisco</option> 52 <option value="MEX">Estado de México</option> 53 <option value="MIC" selected="selected">Michoacán</option> 54 <option value="MOR">Morelos</option> 55 <option value="NAY">Nayarit</option> 56 <option value="NLE">Nuevo León</option> 57 <option value="OAX">Oaxaca</option> 58 <option value="PUE">Puebla</option> 59 <option value="QUE">Querétaro</option> 60 <option value="ROO">Quintana Roo</option> 61 <option value="SIN">Sinaloa</option> 62 <option value="SLP">San Luis Potosí</option> 63 <option value="SON">Sonora</option> 64 <option value="TAB">Tabasco</option> 65 <option value="TAM">Tamaulipas</option> 66 <option value="TLA">Tlaxcala</option> 67 <option value="VER">Veracruz</option> 68 <option value="YUC">Yucatán</option> 69 <option value="ZAC">Zacatecas</option> 70 </select>""" 71 self.assertEqual(str(self.form['state']), state_select_html) -
tests/regressiontests/localflavor/tests.py
diff --git a/tests/regressiontests/localflavor/tests.py b/tests/regressiontests/localflavor/tests.py index 85e91a0..25de89f 100644
a b from django.utils import unittest 3 3 4 4 # just import your tests here 5 5 from us.tests import * 6 from mx.tests import *