Converted Swedish localflavor tests from doctests to unittests. Thanks, Idan Gazit!

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15057 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jannis Leidel 2010-12-26 11:44:37 +00:00
parent 2ea93f9327
commit 3e00cf1f09
5 changed files with 180 additions and 343 deletions

View File

@ -12,7 +12,7 @@ def id_number_checksum(gd):
if tmp > 9: if tmp > 9:
tmp = sum([int(i) for i in str(tmp)]) tmp = sum([int(i) for i in str(tmp)])
s += tmp s += tmp
n += 1 n += 1
@ -28,9 +28,9 @@ def validate_id_birthday(gd, fix_coordination_number_day=True):
If the date is an invalid birth day, a ValueError will be raised. If the date is an invalid birth day, a ValueError will be raised.
""" """
today = datetime.date.today() today = datetime.date.today()
day = int(gd['day']) day = int(gd['day'])
if fix_coordination_number_day and day > 60: if fix_coordination_number_day and day > 60:
day -= 60 day -= 60
@ -40,7 +40,7 @@ def validate_id_birthday(gd, fix_coordination_number_day=True):
# The century was not specified, and need to be calculated from todays date # The century was not specified, and need to be calculated from todays date
current_year = today.year current_year = today.year
year = int(today.strftime('%Y')) - int(today.strftime('%y')) + int(gd['year']) year = int(today.strftime('%Y')) - int(today.strftime('%y')) + int(gd['year'])
if ('%s%s%02d' % (gd['year'], gd['month'], day)) > today.strftime('%y%m%d'): if ('%s%s%02d' % (gd['year'], gd['month'], day)) > today.strftime('%y%m%d'):
year -= 100 year -= 100
@ -49,7 +49,7 @@ def validate_id_birthday(gd, fix_coordination_number_day=True):
year -= 100 year -= 100
else: else:
year = int(gd['century'] + gd['year']) year = int(gd['century'] + gd['year'])
# Make sure the year is valid # Make sure the year is valid
# There are no swedish personal identity numbers where year < 1800 # There are no swedish personal identity numbers where year < 1800
if year < 1800: if year < 1800:
@ -57,11 +57,11 @@ def validate_id_birthday(gd, fix_coordination_number_day=True):
# ValueError will be raise for invalid dates # ValueError will be raise for invalid dates
birth_day = datetime.date(year, int(gd['month']), day) birth_day = datetime.date(year, int(gd['month']), day)
# birth_day must not be in the future # birth_day must not be in the future
if birth_day > today: if birth_day > today:
raise ValueError raise ValueError
return birth_day return birth_day
def format_personal_id_number(birth_day, gd): def format_personal_id_number(birth_day, gd):

View File

@ -1,331 +1,165 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Tests for the contrib/localflavor/se form fields. from django.contrib.localflavor.se.forms import (SECountySelect,
SEOrganisationNumberField, SEPersonalIdentityNumberField,
SEPostalCodeField)
import datetime
from utils import LocalFlavorTestCase
class SELocalFlavorTests(LocalFlavorTestCase):
def setUp(self):
# Mocking datetime.date to make sure
# localflavor.se.utils.validate_id_birthday works
class MockDate(datetime.date):
def today(cls):
return datetime.date(2008, 5, 14)
today = classmethod(today)
self._olddate = datetime.date
datetime.date = MockDate
def tearDown(self):
datetime.date = self._olddate
def test_SECountySelect(self):
f = SECountySelect()
out = u'''<select name="swedish_county">
<option value="AB">Stockholm</option>
<option value="AC">V\xe4sterbotten</option>
<option value="BD">Norrbotten</option>
<option value="C">Uppsala</option>
<option value="D">S\xf6dermanland</option>
<option value="E" selected="selected">\xd6sterg\xf6tland</option>
<option value="F">J\xf6nk\xf6ping</option>
<option value="G">Kronoberg</option>
<option value="H">Kalmar</option>
<option value="I">Gotland</option>
<option value="K">Blekinge</option>
<option value="M">Sk\xe5ne</option>
<option value="N">Halland</option>
<option value="O">V\xe4stra G\xf6taland</option>
<option value="S">V\xe4rmland</option>
<option value="T">\xd6rebro</option>
<option value="U">V\xe4stmanland</option>
<option value="W">Dalarna</option>
<option value="X">G\xe4vleborg</option>
<option value="Y">V\xe4sternorrland</option>
<option value="Z">J\xe4mtland</option>
</select>'''
self.assertEqual(f.render('swedish_county', 'E'), out)
def test_SEOrganizationNumberField(self):
error_invalid = [u'Enter a valid Swedish organisation number.']
valid = {
'870512-1989': '198705121989',
'19870512-1989': '198705121989',
'870512-2128': '198705122128',
'081015-6315': '190810156315',
'081015+6315': '180810156315',
'0810156315': '190810156315',
# Test some different organisation numbers
# IKEA Linköping
'556074-7569': '5560747569',
# Volvo Personvagnar
'556074-3089': '5560743089',
# LJS (organisation)
'822001-5476': '8220015476',
# LJS (organisation)
'8220015476': '8220015476',
# Katedralskolan Linköping (school)
'2120000449': '2120000449',
# Faux organisation number, which tests that the checksum can be 0
'232518-5060': '2325185060',
}
invalid = {
# Ordinary personal identity numbers for sole proprietors
# The same rules as for SEPersonalIdentityField applies here
'081015 6315': error_invalid,
'950231-4496': error_invalid,
'6914104499': error_invalid,
'950d314496': error_invalid,
'invalid!!!': error_invalid,
'870514-1111': error_invalid,
# Co-ordination number checking
# Co-ordination numbers are not valid organisation numbers
'870574-1315': error_invalid,
'870573-1311': error_invalid,
# Volvo Personvagnar, bad format
'556074+3089': error_invalid,
# Invalid checksum
'2120000441': error_invalid,
# Valid checksum but invalid organisation type
'1120000441': error_invalid,
}
self.assertFieldOutput(SEOrganisationNumberField, valid, invalid)
def test_SEPersonalIdentityNumberField(self):
error_invalid = [u'Enter a valid Swedish personal identity number.']
error_coord = [u'Co-ordination numbers are not allowed.']
valid = {
'870512-1989': '198705121989',
'870512-2128': '198705122128',
'19870512-1989': '198705121989',
'198705121989': '198705121989',
'081015-6315': '190810156315',
'0810156315': '190810156315',
# This is a "special-case" in the checksum calculation,
# where the sum is divisible by 10 (the checksum digit == 0)
'8705141060': '198705141060',
# + means that the person is older than 100 years
'081015+6315': '180810156315',
# Co-ordination number checking
'870574-1315': '198705741315',
'870574+1315': '188705741315',
'198705741315': '198705741315',
}
invalid = {
'081015 6315': error_invalid,
'950d314496': error_invalid,
'invalid!!!': error_invalid,
# Invalid dates
# February 31st does not exist
'950231-4496': error_invalid,
# Month 14 does not exist
'6914104499': error_invalid,
# There are no Swedish personal id numbers where year < 1800
'17430309-7135': error_invalid,
# Invalid checksum
'870514-1111': error_invalid,
# Co-ordination number with bad checksum
'870573-1311': error_invalid,
}
self.assertFieldOutput(SEPersonalIdentityNumberField, valid, invalid)
valid = {}
invalid = {
# Check valid co-ordination numbers that should not be accepted
# because of coordination_number=False
'870574-1315': error_coord,
'870574+1315': error_coord,
'8705741315': error_coord,
# Invalid co-ordination numbers should be treated as invalid, and not
# as co-ordination numbers
'870573-1311': error_invalid,
}
kwargs = {'coordination_number': False,}
self.assertFieldOutput(SEPersonalIdentityNumberField, valid, invalid,
field_kwargs=kwargs)
def test_SEPostalCodeField(self):
error_format = [u'Enter a Swedish postal code in the format XXXXX.']
valid = {
'589 37': '58937',
'58937': '58937',
}
invalid = {
'abcasfassadf': error_format,
# Only one space is allowed for separation
'589 37': error_format,
# The postal code must not start with 0
'01234': error_format,
}
self.assertFieldOutput(SEPostalCodeField, valid, invalid)
tests = r"""
# Monkey-patch datetime.date
>>> import datetime
>>> class MockDate(datetime.date):
... def today(cls):
... return datetime.date(2008, 5, 14)
... today = classmethod(today)
...
>>> olddate = datetime.date
>>> datetime.date = MockDate
>>> datetime.date.today() == olddate(2008, 5, 14)
True
# SECountySelect #####################################################
>>> from django.contrib.localflavor.se.forms import SECountySelect
>>> w = SECountySelect()
>>> w.render('swedish_county', 'E')
u'<select name="swedish_county">\n<option value="AB">Stockholm</option>\n<option value="AC">V\xe4sterbotten</option>\n<option value="BD">Norrbotten</option>\n<option value="C">Uppsala</option>\n<option value="D">S\xf6dermanland</option>\n<option value="E" selected="selected">\xd6sterg\xf6tland</option>\n<option value="F">J\xf6nk\xf6ping</option>\n<option value="G">Kronoberg</option>\n<option value="H">Kalmar</option>\n<option value="I">Gotland</option>\n<option value="K">Blekinge</option>\n<option value="M">Sk\xe5ne</option>\n<option value="N">Halland</option>\n<option value="O">V\xe4stra G\xf6taland</option>\n<option value="S">V\xe4rmland</option>\n<option value="T">\xd6rebro</option>\n<option value="U">V\xe4stmanland</option>\n<option value="W">Dalarna</option>\n<option value="X">G\xe4vleborg</option>\n<option value="Y">V\xe4sternorrland</option>\n<option value="Z">J\xe4mtland</option>\n</select>'
# SEOrganisationNumberField #######################################
>>> from django.contrib.localflavor.se.forms import SEOrganisationNumberField
>>> f = SEOrganisationNumberField()
# Ordinary personal identity numbers for sole proprietors
# The same rules as for SEPersonalIdentityField applies here
>>> f.clean('870512-1989')
u'198705121989'
>>> f.clean('19870512-1989')
u'198705121989'
>>> f.clean('870512-2128')
u'198705122128'
>>> f.clean('081015-6315')
u'190810156315'
>>> f.clean('081015+6315')
u'180810156315'
>>> f.clean('0810156315')
u'190810156315'
>>> f.clean('081015 6315')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish organisation number.']
>>> f.clean('950231-4496')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish organisation number.']
>>> f.clean('6914104499')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish organisation number.']
>>> f.clean('950d314496')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish organisation number.']
>>> f.clean('invalid!!!')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish organisation number.']
>>> f.clean('870514-1111')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish organisation number.']
# Empty values
>>> f.clean('')
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
>>> f.clean(None)
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
# Co-ordination number checking
# Co-ordination numbers are not valid organisation numbers
>>> f.clean('870574-1315')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish organisation number.']
>>> f.clean('870573-1311')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish organisation number.']
# Test some different organisation numbers
>>> f.clean('556074-7569') # IKEA Linköping
u'5560747569'
>>> f.clean('556074-3089') # Volvo Personvagnar
u'5560743089'
>>> f.clean('822001-5476') # LJS (organisation)
u'8220015476'
>>> f.clean('8220015476') # LJS (organisation)
u'8220015476'
>>> f.clean('2120000449') # Katedralskolan Linköping (school)
u'2120000449'
# Faux organisation number, which tests that the checksum can be 0
>>> f.clean('232518-5060')
u'2325185060'
>>> f.clean('556074+3089') # Volvo Personvagnar, bad format
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish organisation number.']
# Invalid checksum
>>> f.clean('2120000441')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish organisation number.']
# Valid checksum but invalid organisation type
f.clean('1120000441')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish organisation number.']
# Empty values with required=False
>>> f = SEOrganisationNumberField(required=False)
>>> f.clean(None)
u''
>>> f.clean('')
u''
# SEPersonalIdentityNumberField #######################################
>>> from django.contrib.localflavor.se.forms import SEPersonalIdentityNumberField
>>> f = SEPersonalIdentityNumberField()
# Valid id numbers
>>> f.clean('870512-1989')
u'198705121989'
>>> f.clean('870512-2128')
u'198705122128'
>>> f.clean('19870512-1989')
u'198705121989'
>>> f.clean('198705121989')
u'198705121989'
>>> f.clean('081015-6315')
u'190810156315'
>>> f.clean('0810156315')
u'190810156315'
# This is a "special-case" in the checksum calculation,
# where the sum is divisible by 10 (the checksum digit == 0)
>>> f.clean('8705141060')
u'198705141060'
# + means that the person is older than 100 years
>>> f.clean('081015+6315')
u'180810156315'
# Bogus values
>>> f.clean('081015 6315')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish personal identity number.']
>>> f.clean('950d314496')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish personal identity number.']
>>> f.clean('invalid!!!')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish personal identity number.']
# Invalid dates
# February 31st does not exist
>>> f.clean('950231-4496')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish personal identity number.']
# Month 14 does not exist
>>> f.clean('6914104499')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish personal identity number.']
# There are no Swedish personal id numbers where year < 1800
>>> f.clean('17430309-7135')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish personal identity number.']
# Invalid checksum
>>> f.clean('870514-1111')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish personal identity number.']
# Empty values
>>> f.clean('')
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
>>> f.clean(None)
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
# Co-ordination number checking
>>> f.clean('870574-1315')
u'198705741315'
>>> f.clean('870574+1315')
u'188705741315'
>>> f.clean('198705741315')
u'198705741315'
# Co-ordination number with bad checksum
>>> f.clean('870573-1311')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish personal identity number.']
# Check valid co-ordination numbers, that should not be accepted
# because of coordination_number=False
>>> f = SEPersonalIdentityNumberField(coordination_number=False)
>>> f.clean('870574-1315')
Traceback (most recent call last):
...
ValidationError: [u'Co-ordination numbers are not allowed.']
>>> f.clean('870574+1315')
Traceback (most recent call last):
...
ValidationError: [u'Co-ordination numbers are not allowed.']
>>> f.clean('8705741315')
Traceback (most recent call last):
...
ValidationError: [u'Co-ordination numbers are not allowed.']
# Invalid co-ordination numbers should be treated as invalid, and not
# as co-ordination numbers
>>> f.clean('870573-1311')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Swedish personal identity number.']
# Empty values with required=False
>>> f = SEPersonalIdentityNumberField(required=False)
>>> f.clean(None)
u''
>>> f.clean('')
u''
# SEPostalCodeField ###############################################
>>> from django.contrib.localflavor.se.forms import SEPostalCodeField
>>> f = SEPostalCodeField()
>>>
Postal codes can have spaces
>>> f.clean('589 37')
u'58937'
... but the dont have to
>>> f.clean('58937')
u'58937'
>>> f.clean('abcasfassadf')
Traceback (most recent call last):
...
ValidationError: [u'Enter a Swedish postal code in the format XXXXX.']
# Only one space is allowed for separation
>>> f.clean('589 37')
Traceback (most recent call last):
...
ValidationError: [u'Enter a Swedish postal code in the format XXXXX.']
# The postal code must not start with 0
>>> f.clean('01234')
Traceback (most recent call last):
...
ValidationError: [u'Enter a Swedish postal code in the format XXXXX.']
# Empty values
>>> f.clean('')
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
>>> f.clean(None)
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
# Empty values, required=False
>>> f = SEPostalCodeField(required=False)
>>> f.clean('')
u''
>>> f.clean(None)
u''
# Revert the monkey patching
>>> datetime.date = olddate
"""

View File

@ -14,8 +14,9 @@ class LocalFlavorTestCase(TestCase):
restore_warnings_state(self._warnings_state) restore_warnings_state(self._warnings_state)
def assertFieldOutput(self, fieldclass, valid, invalid, field_args=[], def assertFieldOutput(self, fieldclass, valid, invalid, field_args=[],
field_kwargs={}, empty_value=u''): field_kwargs={}, empty_value=u''):
"""Asserts that a field behaves correctly with various inputs. """
Asserts that a field behaves correctly with various inputs.
Args: Args:
fieldclass: the class of the field to be tested. fieldclass: the class of the field to be tested.
@ -23,9 +24,10 @@ class LocalFlavorTestCase(TestCase):
cleaned values. cleaned values.
invalid: a dictionary mapping invalid inputs to one or more invalid: a dictionary mapping invalid inputs to one or more
raised error messages. raised error messages.
fieldargs: the args passed to instantiate the field field_args: the args passed to instantiate the field
fieldkwargs: the kwargs passed to instantiate the field field_kwargs: the kwargs passed to instantiate the field
emptyvalue: the expected clean output for inputs in EMPTY_VALUES empty_value: the expected clean output for inputs in EMPTY_VALUES
""" """
required = fieldclass(*field_args, **field_kwargs) required = fieldclass(*field_args, **field_kwargs)
optional = fieldclass(*field_args, **dict(field_kwargs, required=False)) optional = fieldclass(*field_args, **dict(field_kwargs, required=False))

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from localflavor.cz import tests as localflavor_cz_tests from localflavor.cz import tests as localflavor_cz_tests
from localflavor.se import tests as localflavor_se_tests
from localflavor.ar import ARLocalFlavorTests from localflavor.ar import ARLocalFlavorTests
from localflavor.at import ATLocalFlavorTests from localflavor.at import ATLocalFlavorTests
@ -25,6 +25,7 @@ from localflavor.nl import NLLocalFlavorTests
from localflavor.pl import PLLocalFlavorTests from localflavor.pl import PLLocalFlavorTests
from localflavor.pt import PTLocalFlavorTests from localflavor.pt import PTLocalFlavorTests
from localflavor.ro import ROLocalFlavorTests from localflavor.ro import ROLocalFlavorTests
from localflavor.se import SELocalFlavorTests
from localflavor.sk import SKLocalFlavorTests from localflavor.sk import SKLocalFlavorTests
from localflavor.tr import TRLocalFlavorTests from localflavor.tr import TRLocalFlavorTests
from localflavor.uk import UKLocalFlavorTests from localflavor.uk import UKLocalFlavorTests
@ -35,5 +36,4 @@ from localflavor.za import ZALocalFlavorTests
__test__ = { __test__ = {
'localflavor_cz_tests': localflavor_cz_tests, 'localflavor_cz_tests': localflavor_cz_tests,
'localflavor_se_tests': localflavor_se_tests,
} }

View File

@ -37,6 +37,7 @@ from regressiontests.forms.localflavortests import (
PLLocalFlavorTests, PLLocalFlavorTests,
PTLocalFlavorTests, PTLocalFlavorTests,
ROLocalFlavorTests, ROLocalFlavorTests,
SELocalFlavorTests,
SKLocalFlavorTests, SKLocalFlavorTests,
TRLocalFlavorTests, TRLocalFlavorTests,
UKLocalFlavorTests, UKLocalFlavorTests,