PageRenderTime 93ms CodeModel.GetById 8ms app.highlight 75ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/regressiontests/forms/tests/fields.py

https://code.google.com/p/mango-py/
Python | 972 lines | 965 code | 0 blank | 7 comment | 0 complexity | 31cf0537ddb2e1d31ba8e6627361d322 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1# -*- coding: utf-8 -*-
  2"""
  3##########
  4# Fields #
  5##########
  6
  7Each Field class does some sort of validation. Each Field has a clean() method,
  8which either raises django.forms.ValidationError or returns the "clean"
  9data -- usually a Unicode object, but, in some rare cases, a list.
 10
 11Each Field's __init__() takes at least these parameters:
 12    required -- Boolean that specifies whether the field is required.
 13                True by default.
 14    widget -- A Widget class, or instance of a Widget class, that should be
 15              used for this Field when displaying it. Each Field has a default
 16              Widget that it'll use if you don't specify this. In most cases,
 17              the default widget is TextInput.
 18    label -- A verbose name for this field, for use in displaying this field in
 19             a form. By default, Django will use a "pretty" version of the form
 20             field name, if the Field is part of a Form.
 21    initial -- A value to use in this Field's initial display. This value is
 22               *not* used as a fallback if data isn't given.
 23
 24Other than that, the Field subclasses have class-specific options for
 25__init__(). For example, CharField has a max_length option.
 26"""
 27import datetime
 28import time
 29import re
 30import os
 31import urllib2
 32from decimal import Decimal
 33
 34from django.core.files.uploadedfile import SimpleUploadedFile
 35from django.forms import *
 36from django.forms.widgets import RadioFieldRenderer
 37from django.utils.unittest import TestCase
 38
 39
 40def fix_os_paths(x):
 41    if isinstance(x, basestring):
 42        return x.replace('\\', '/')
 43    elif isinstance(x, tuple):
 44        return tuple(fix_os_paths(list(x)))
 45    elif isinstance(x, list):
 46        return [fix_os_paths(y) for y in x]
 47    else:
 48        return x
 49
 50
 51class FieldsTests(TestCase):
 52
 53    def assertRaisesErrorWithMessage(self, error, message, callable, *args, **kwargs):
 54        self.assertRaises(error, callable, *args, **kwargs)
 55        try:
 56            callable(*args, **kwargs)
 57        except error, e:
 58            self.assertEqual(message, str(e))
 59
 60    def test_field_sets_widget_is_required(self):
 61        self.assertTrue(Field(required=True).widget.is_required)
 62        self.assertFalse(Field(required=False).widget.is_required)
 63
 64    # CharField ###################################################################
 65
 66    def test_charfield_1(self):
 67        f = CharField()
 68        self.assertEqual(u'1', f.clean(1))
 69        self.assertEqual(u'hello', f.clean('hello'))
 70        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
 71        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
 72        self.assertEqual(u'[1, 2, 3]', f.clean([1, 2, 3]))
 73        self.assertEqual(f.max_length, None)
 74        self.assertEqual(f.min_length, None)
 75
 76    def test_charfield_2(self):
 77        f = CharField(required=False)
 78        self.assertEqual(u'1', f.clean(1))
 79        self.assertEqual(u'hello', f.clean('hello'))
 80        self.assertEqual(u'', f.clean(None))
 81        self.assertEqual(u'', f.clean(''))
 82        self.assertEqual(u'[1, 2, 3]', f.clean([1, 2, 3]))
 83        self.assertEqual(f.max_length, None)
 84        self.assertEqual(f.min_length, None)
 85
 86    def test_charfield_3(self):
 87        f = CharField(max_length=10, required=False)
 88        self.assertEqual(u'12345', f.clean('12345'))
 89        self.assertEqual(u'1234567890', f.clean('1234567890'))
 90        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at most 10 characters (it has 11).']", f.clean, '1234567890a')
 91        self.assertEqual(f.max_length, 10)
 92        self.assertEqual(f.min_length, None)
 93
 94    def test_charfield_4(self):
 95        f = CharField(min_length=10, required=False)
 96        self.assertEqual(u'', f.clean(''))
 97        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 10 characters (it has 5).']", f.clean, '12345')
 98        self.assertEqual(u'1234567890', f.clean('1234567890'))
 99        self.assertEqual(u'1234567890a', f.clean('1234567890a'))
100        self.assertEqual(f.max_length, None)
101        self.assertEqual(f.min_length, 10)
102
103    def test_charfield_5(self):
104        f = CharField(min_length=10, required=True)
105        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
106        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 10 characters (it has 5).']", f.clean, '12345')
107        self.assertEqual(u'1234567890', f.clean('1234567890'))
108        self.assertEqual(u'1234567890a', f.clean('1234567890a'))
109        self.assertEqual(f.max_length, None)
110        self.assertEqual(f.min_length, 10)
111
112    # IntegerField ################################################################
113
114    def test_integerfield_1(self):
115        f = IntegerField()
116        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
117        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
118        self.assertEqual(1, f.clean('1'))
119        self.assertEqual(True, isinstance(f.clean('1'), int))
120        self.assertEqual(23, f.clean('23'))
121        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a whole number.']", f.clean, 'a')
122        self.assertEqual(42, f.clean(42))
123        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a whole number.']", f.clean, 3.14)
124        self.assertEqual(1, f.clean('1 '))
125        self.assertEqual(1, f.clean(' 1'))
126        self.assertEqual(1, f.clean(' 1 '))
127        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a whole number.']", f.clean, '1a')
128        self.assertEqual(f.max_value, None)
129        self.assertEqual(f.min_value, None)
130
131    def test_integerfield_2(self):
132        f = IntegerField(required=False)
133        self.assertEqual(None, f.clean(''))
134        self.assertEqual('None', repr(f.clean('')))
135        self.assertEqual(None, f.clean(None))
136        self.assertEqual('None', repr(f.clean(None)))
137        self.assertEqual(1, f.clean('1'))
138        self.assertEqual(True, isinstance(f.clean('1'), int))
139        self.assertEqual(23, f.clean('23'))
140        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a whole number.']", f.clean, 'a')
141        self.assertEqual(1, f.clean('1 '))
142        self.assertEqual(1, f.clean(' 1'))
143        self.assertEqual(1, f.clean(' 1 '))
144        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a whole number.']", f.clean, '1a')
145        self.assertEqual(f.max_value, None)
146        self.assertEqual(f.min_value, None)
147
148    def test_integerfield_3(self):
149        f = IntegerField(max_value=10)
150        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
151        self.assertEqual(1, f.clean(1))
152        self.assertEqual(10, f.clean(10))
153        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is less than or equal to 10.']", f.clean, 11)
154        self.assertEqual(10, f.clean('10'))
155        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is less than or equal to 10.']", f.clean, '11')
156        self.assertEqual(f.max_value, 10)
157        self.assertEqual(f.min_value, None)
158
159    def test_integerfield_4(self):
160        f = IntegerField(min_value=10)
161        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
162        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is greater than or equal to 10.']", f.clean, 1)
163        self.assertEqual(10, f.clean(10))
164        self.assertEqual(11, f.clean(11))
165        self.assertEqual(10, f.clean('10'))
166        self.assertEqual(11, f.clean('11'))
167        self.assertEqual(f.max_value, None)
168        self.assertEqual(f.min_value, 10)
169
170    def test_integerfield_5(self):
171        f = IntegerField(min_value=10, max_value=20)
172        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
173        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is greater than or equal to 10.']", f.clean, 1)
174        self.assertEqual(10, f.clean(10))
175        self.assertEqual(11, f.clean(11))
176        self.assertEqual(10, f.clean('10'))
177        self.assertEqual(11, f.clean('11'))
178        self.assertEqual(20, f.clean(20))
179        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is less than or equal to 20.']", f.clean, 21)
180        self.assertEqual(f.max_value, 20)
181        self.assertEqual(f.min_value, 10)
182
183    # FloatField ##################################################################
184
185    def test_floatfield_1(self):
186        f = FloatField()
187        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
188        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
189        self.assertEqual(1.0, f.clean('1'))
190        self.assertEqual(True, isinstance(f.clean('1'), float))
191        self.assertEqual(23.0, f.clean('23'))
192        self.assertEqual(3.1400000000000001, f.clean('3.14'))
193        self.assertEqual(3.1400000000000001, f.clean(3.14))
194        self.assertEqual(42.0, f.clean(42))
195        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, 'a')
196        self.assertEqual(1.0, f.clean('1.0 '))
197        self.assertEqual(1.0, f.clean(' 1.0'))
198        self.assertEqual(1.0, f.clean(' 1.0 '))
199        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, '1.0a')
200        self.assertEqual(f.max_value, None)
201        self.assertEqual(f.min_value, None)
202
203    def test_floatfield_2(self):
204        f = FloatField(required=False)
205        self.assertEqual(None, f.clean(''))
206        self.assertEqual(None, f.clean(None))
207        self.assertEqual(1.0, f.clean('1'))
208        self.assertEqual(f.max_value, None)
209        self.assertEqual(f.min_value, None)
210
211    def test_floatfield_3(self):
212        f = FloatField(max_value=1.5, min_value=0.5)
213        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is less than or equal to 1.5.']", f.clean, '1.6')
214        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is greater than or equal to 0.5.']", f.clean, '0.4')
215        self.assertEqual(1.5, f.clean('1.5'))
216        self.assertEqual(0.5, f.clean('0.5'))
217        self.assertEqual(f.max_value, 1.5)
218        self.assertEqual(f.min_value, 0.5)
219
220    # DecimalField ################################################################
221
222    def test_decimalfield_1(self):
223        f = DecimalField(max_digits=4, decimal_places=2)
224        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
225        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
226        self.assertEqual(f.clean('1'), Decimal("1"))
227        self.assertEqual(True, isinstance(f.clean('1'), Decimal))
228        self.assertEqual(f.clean('23'), Decimal("23"))
229        self.assertEqual(f.clean('3.14'), Decimal("3.14"))
230        self.assertEqual(f.clean(3.14), Decimal("3.14"))
231        self.assertEqual(f.clean(Decimal('3.14')), Decimal("3.14"))
232        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, 'NaN')
233        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, 'Inf')
234        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, '-Inf')
235        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, 'a')
236        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, u'????')
237        self.assertEqual(f.clean('1.0 '), Decimal("1.0"))
238        self.assertEqual(f.clean(' 1.0'), Decimal("1.0"))
239        self.assertEqual(f.clean(' 1.0 '), Decimal("1.0"))
240        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, '1.0a')
241        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 4 digits in total.']", f.clean, '123.45')
242        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 2 decimal places.']", f.clean, '1.234')
243        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 2 digits before the decimal point.']", f.clean, '123.4')
244        self.assertEqual(f.clean('-12.34'), Decimal("-12.34"))
245        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 4 digits in total.']", f.clean, '-123.45')
246        self.assertEqual(f.clean('-.12'), Decimal("-0.12"))
247        self.assertEqual(f.clean('-00.12'), Decimal("-0.12"))
248        self.assertEqual(f.clean('-000.12'), Decimal("-0.12"))
249        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 2 decimal places.']", f.clean, '-000.123')
250        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 4 digits in total.']", f.clean, '-000.12345')
251        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, '--0.12')
252        self.assertEqual(f.max_digits, 4)
253        self.assertEqual(f.decimal_places, 2)
254        self.assertEqual(f.max_value, None)
255        self.assertEqual(f.min_value, None)
256
257    def test_decimalfield_2(self):
258        f = DecimalField(max_digits=4, decimal_places=2, required=False)
259        self.assertEqual(None, f.clean(''))
260        self.assertEqual(None, f.clean(None))
261        self.assertEqual(f.clean('1'), Decimal("1"))
262        self.assertEqual(f.max_digits, 4)
263        self.assertEqual(f.decimal_places, 2)
264        self.assertEqual(f.max_value, None)
265        self.assertEqual(f.min_value, None)
266
267    def test_decimalfield_3(self):
268        f = DecimalField(max_digits=4, decimal_places=2, max_value=Decimal('1.5'), min_value=Decimal('0.5'))
269        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is less than or equal to 1.5.']", f.clean, '1.6')
270        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is greater than or equal to 0.5.']", f.clean, '0.4')
271        self.assertEqual(f.clean('1.5'), Decimal("1.5"))
272        self.assertEqual(f.clean('0.5'), Decimal("0.5"))
273        self.assertEqual(f.clean('.5'), Decimal("0.5"))
274        self.assertEqual(f.clean('00.50'), Decimal("0.50"))
275        self.assertEqual(f.max_digits, 4)
276        self.assertEqual(f.decimal_places, 2)
277        self.assertEqual(f.max_value, Decimal('1.5'))
278        self.assertEqual(f.min_value, Decimal('0.5'))
279
280    def test_decimalfield_4(self):
281        f = DecimalField(decimal_places=2)
282        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 2 decimal places.']", f.clean, '0.00000001')
283
284    def test_decimalfield_5(self):
285        f = DecimalField(max_digits=3)
286        # Leading whole zeros "collapse" to one digit.
287        self.assertEqual(f.clean('0000000.10'), Decimal("0.1"))
288        # But a leading 0 before the . doesn't count towards max_digits
289        self.assertEqual(f.clean('0000000.100'), Decimal("0.100"))
290        # Only leading whole zeros "collapse" to one digit.
291        self.assertEqual(f.clean('000000.02'), Decimal('0.02'))
292        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 3 digits in total.']", f.clean, '000000.0002')
293        self.assertEqual(f.clean('.002'), Decimal("0.002"))
294
295    def test_decimalfield_6(self):
296        f = DecimalField(max_digits=2, decimal_places=2)
297        self.assertEqual(f.clean('.01'), Decimal(".01"))
298        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 0 digits before the decimal point.']", f.clean, '1.1')
299
300    # DateField ###################################################################
301
302    def test_datefield_1(self):
303        f = DateField()
304        self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.date(2006, 10, 25)))
305        self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.datetime(2006, 10, 25, 14, 30)))
306        self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59)))
307        self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200)))
308        self.assertEqual(datetime.date(2006, 10, 25), f.clean('2006-10-25'))
309        self.assertEqual(datetime.date(2006, 10, 25), f.clean('10/25/2006'))
310        self.assertEqual(datetime.date(2006, 10, 25), f.clean('10/25/06'))
311        self.assertEqual(datetime.date(2006, 10, 25), f.clean('Oct 25 2006'))
312        self.assertEqual(datetime.date(2006, 10, 25), f.clean('October 25 2006'))
313        self.assertEqual(datetime.date(2006, 10, 25), f.clean('October 25, 2006'))
314        self.assertEqual(datetime.date(2006, 10, 25), f.clean('25 October 2006'))
315        self.assertEqual(datetime.date(2006, 10, 25), f.clean('25 October, 2006'))
316        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '2006-4-31')
317        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '200a-10-25')
318        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '25/10/06')
319        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
320
321    def test_datefield_2(self):
322        f = DateField(required=False)
323        self.assertEqual(None, f.clean(None))
324        self.assertEqual('None', repr(f.clean(None)))
325        self.assertEqual(None, f.clean(''))
326        self.assertEqual('None', repr(f.clean('')))
327
328    def test_datefield_3(self):
329        f = DateField(input_formats=['%Y %m %d'])
330        self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.date(2006, 10, 25)))
331        self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.datetime(2006, 10, 25, 14, 30)))
332        self.assertEqual(datetime.date(2006, 10, 25), f.clean('2006 10 25'))
333        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '2006-10-25')
334        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '10/25/2006')
335        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '10/25/06')
336
337    # TimeField ###################################################################
338
339    def test_timefield_1(self):
340        f = TimeField()
341        self.assertEqual(datetime.time(14, 25), f.clean(datetime.time(14, 25)))
342        self.assertEqual(datetime.time(14, 25, 59), f.clean(datetime.time(14, 25, 59)))
343        self.assertEqual(datetime.time(14, 25), f.clean('14:25'))
344        self.assertEqual(datetime.time(14, 25, 59), f.clean('14:25:59'))
345        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, 'hello')
346        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, '1:24 p.m.')
347
348    def test_timefield_2(self):
349        f = TimeField(input_formats=['%I:%M %p'])
350        self.assertEqual(datetime.time(14, 25), f.clean(datetime.time(14, 25)))
351        self.assertEqual(datetime.time(14, 25, 59), f.clean(datetime.time(14, 25, 59)))
352        self.assertEqual(datetime.time(4, 25), f.clean('4:25 AM'))
353        self.assertEqual(datetime.time(16, 25), f.clean('4:25 PM'))
354        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, '14:30:45')
355
356    # DateTimeField ###############################################################
357
358    def test_datetimefield_1(self):
359        f = DateTimeField()
360        self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean(datetime.date(2006, 10, 25)))
361        self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean(datetime.datetime(2006, 10, 25, 14, 30)))
362        self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 59), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59)))
363        self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 59, 200), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200)))
364        self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 45), f.clean('2006-10-25 14:30:45'))
365        self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('2006-10-25 14:30:00'))
366        self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('2006-10-25 14:30'))
367        self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean('2006-10-25'))
368        self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 45), f.clean('10/25/2006 14:30:45'))
369        self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('10/25/2006 14:30:00'))
370        self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('10/25/2006 14:30'))
371        self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean('10/25/2006'))
372        self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 45), f.clean('10/25/06 14:30:45'))
373        self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('10/25/06 14:30:00'))
374        self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('10/25/06 14:30'))
375        self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean('10/25/06'))
376        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date/time.']", f.clean, 'hello')
377        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date/time.']", f.clean, '2006-10-25 4:30 p.m.')
378
379    def test_datetimefield_2(self):
380        f = DateTimeField(input_formats=['%Y %m %d %I:%M %p'])
381        self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean(datetime.date(2006, 10, 25)))
382        self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean(datetime.datetime(2006, 10, 25, 14, 30)))
383        self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 59), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59)))
384        self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 59, 200), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200)))
385        self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('2006 10 25 2:30 PM'))
386        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date/time.']", f.clean, '2006-10-25 14:30:45')
387
388    def test_datetimefield_3(self):
389        f = DateTimeField(required=False)
390        self.assertEqual(None, f.clean(None))
391        self.assertEqual('None', repr(f.clean(None)))
392        self.assertEqual(None, f.clean(''))
393        self.assertEqual('None', repr(f.clean('')))
394
395    # RegexField ##################################################################
396
397    def test_regexfield_1(self):
398        f = RegexField('^\d[A-F]\d$')
399        self.assertEqual(u'2A2', f.clean('2A2'))
400        self.assertEqual(u'3F3', f.clean('3F3'))
401        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '3G3')
402        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, ' 2A2')
403        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '2A2 ')
404        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
405
406    def test_regexfield_2(self):
407        f = RegexField('^\d[A-F]\d$', required=False)
408        self.assertEqual(u'2A2', f.clean('2A2'))
409        self.assertEqual(u'3F3', f.clean('3F3'))
410        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '3G3')
411        self.assertEqual(u'', f.clean(''))
412
413    def test_regexfield_3(self):
414        f = RegexField(re.compile('^\d[A-F]\d$'))
415        self.assertEqual(u'2A2', f.clean('2A2'))
416        self.assertEqual(u'3F3', f.clean('3F3'))
417        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '3G3')
418        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, ' 2A2')
419        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '2A2 ')
420
421    def test_regexfield_4(self):
422        f = RegexField('^\d\d\d\d$', error_message='Enter a four-digit number.')
423        self.assertEqual(u'1234', f.clean('1234'))
424        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a four-digit number.']", f.clean, '123')
425        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a four-digit number.']", f.clean, 'abcd')
426
427    def test_regexfield_5(self):
428        f = RegexField('^\d+$', min_length=5, max_length=10)
429        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 5 characters (it has 3).']", f.clean, '123')
430        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 5 characters (it has 3).', u'Enter a valid value.']", f.clean, 'abc')
431        self.assertEqual(u'12345', f.clean('12345'))
432        self.assertEqual(u'1234567890', f.clean('1234567890'))
433        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at most 10 characters (it has 11).']", f.clean, '12345678901')
434        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '12345a')
435
436    # EmailField ##################################################################
437
438    def test_emailfield_1(self):
439        f = EmailField()
440        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
441        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
442        self.assertEqual(u'person@example.com', f.clean('person@example.com'))
443        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo')
444        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo@')
445        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo@bar')
446        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'example@invalid-.com')
447        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'example@-invalid.com')
448        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'example@inv-.alid-.com')
449        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'example@inv-.-alid.com')
450        self.assertEqual(u'example@valid-----hyphens.com', f.clean('example@valid-----hyphens.com'))
451        self.assertEqual(u'example@valid-with-hyphens.com', f.clean('example@valid-with-hyphens.com'))
452        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'example@.com')
453        self.assertEqual(u'local@domain.with.idn.xyz\xe4\xf6\xfc\xdfabc.part.com', f.clean('local@domain.with.idn.xyzäöüßabc.part.com'))
454
455    def test_email_regexp_for_performance(self):
456        f = EmailField()
457        # Check for runaway regex security problem. This will take for-freeking-ever
458        # if the security fix isn't in place.
459        self.assertRaisesErrorWithMessage(
460                ValidationError,
461                "[u'Enter a valid e-mail address.']",
462                f.clean,
463                'viewx3dtextx26qx3d@yahoo.comx26latlngx3d15854521645943074058'
464            )
465
466    def test_emailfield_2(self):
467        f = EmailField(required=False)
468        self.assertEqual(u'', f.clean(''))
469        self.assertEqual(u'', f.clean(None))
470        self.assertEqual(u'person@example.com', f.clean('person@example.com'))
471        self.assertEqual(u'example@example.com', f.clean('      example@example.com  \t   \t '))
472        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo')
473        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo@')
474        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo@bar')
475
476    def test_emailfield_3(self):
477        f = EmailField(min_length=10, max_length=15)
478        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 10 characters (it has 9).']", f.clean, 'a@foo.com')
479        self.assertEqual(u'alf@foo.com', f.clean('alf@foo.com'))
480        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at most 15 characters (it has 20).']", f.clean, 'alf123456788@foo.com')
481
482    # FileField ##################################################################
483
484    def test_filefield_1(self):
485        f = FileField()
486        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
487        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '', '')
488        self.assertEqual('files/test1.pdf', f.clean('', 'files/test1.pdf'))
489        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
490        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None, '')
491        self.assertEqual('files/test2.pdf', f.clean(None, 'files/test2.pdf'))
492        self.assertRaisesErrorWithMessage(ValidationError, "[u'No file was submitted. Check the encoding type on the form.']", f.clean, SimpleUploadedFile('', ''))
493        self.assertRaisesErrorWithMessage(ValidationError, "[u'No file was submitted. Check the encoding type on the form.']", f.clean, SimpleUploadedFile('', ''), '')
494        self.assertEqual('files/test3.pdf', f.clean(None, 'files/test3.pdf'))
495        self.assertRaisesErrorWithMessage(ValidationError, "[u'No file was submitted. Check the encoding type on the form.']", f.clean, 'some content that is not a file')
496        self.assertRaisesErrorWithMessage(ValidationError, "[u'The submitted file is empty.']", f.clean, SimpleUploadedFile('name', None))
497        self.assertRaisesErrorWithMessage(ValidationError, "[u'The submitted file is empty.']", f.clean, SimpleUploadedFile('name', ''))
498        self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', 'Some File Content'))))
499        self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('?????????.txt', '???? ??????? ???? ??? ????????? ?? ??? ?'))))
500        self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', 'Some File Content'), 'files/test4.pdf')))
501
502    def test_filefield_2(self):
503        f = FileField(max_length = 5)
504        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this filename has at most 5 characters (it has 18).']", f.clean, SimpleUploadedFile('test_maxlength.txt', 'hello world'))
505        self.assertEqual('files/test1.pdf', f.clean('', 'files/test1.pdf'))
506        self.assertEqual('files/test2.pdf', f.clean(None, 'files/test2.pdf'))
507        self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', 'Some File Content'))))
508
509    # URLField ##################################################################
510
511    def test_urlfield_1(self):
512        f = URLField()
513        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
514        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
515        self.assertEqual(u'http://localhost/', f.clean('http://localhost'))
516        self.assertEqual(u'http://example.com/', f.clean('http://example.com'))
517        self.assertEqual(u'http://example.com./', f.clean('http://example.com.'))
518        self.assertEqual(u'http://www.example.com/', f.clean('http://www.example.com'))
519        self.assertEqual(u'http://www.example.com:8000/test', f.clean('http://www.example.com:8000/test'))
520        self.assertEqual(u'http://valid-with-hyphens.com/', f.clean('valid-with-hyphens.com'))
521        self.assertEqual(u'http://subdomain.domain.com/', f.clean('subdomain.domain.com'))
522        self.assertEqual(u'http://200.8.9.10/', f.clean('http://200.8.9.10'))
523        self.assertEqual(u'http://200.8.9.10:8000/test', f.clean('http://200.8.9.10:8000/test'))
524        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'foo')
525        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://')
526        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example')
527        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example.')
528        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'com.')
529        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, '.')
530        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://.com')
531        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://invalid-.com')
532        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://-invalid.com')
533        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://inv-.alid-.com')
534        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://inv-.-alid.com')
535        self.assertEqual(u'http://valid-----hyphens.com/', f.clean('http://valid-----hyphens.com'))
536        self.assertEqual(u'http://some.idn.xyz\xe4\xf6\xfc\xdfabc.domain.com:123/blah', f.clean('http://some.idn.xyzäöüßabc.domain.com:123/blah'))
537        self.assertEqual(u'http://www.example.com/s/http://code.djangoproject.com/ticket/13804', f.clean('www.example.com/s/http://code.djangoproject.com/ticket/13804'))
538
539    def test_url_regex_ticket11198(self):
540        f = URLField()
541        # hangs "forever" if catastrophic backtracking in ticket:#11198 not fixed
542        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://%s' % ("X"*200,))
543
544        # a second test, to make sure the problem is really addressed, even on
545        # domains that don't fail the domain label length check in the regex
546        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://%s' % ("X"*60,))
547
548    def test_urlfield_2(self):
549        f = URLField(required=False)
550        self.assertEqual(u'', f.clean(''))
551        self.assertEqual(u'', f.clean(None))
552        self.assertEqual(u'http://example.com/', f.clean('http://example.com'))
553        self.assertEqual(u'http://www.example.com/', f.clean('http://www.example.com'))
554        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'foo')
555        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://')
556        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example')
557        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example.')
558        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://.com')
559
560    def test_urlfield_3(self):
561        f = URLField(verify_exists=True)
562        self.assertEqual(u'http://www.google.com/', f.clean('http://www.google.com')) # This will fail if there's no Internet connection
563        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example')
564        self.assertRaises(ValidationError, f.clean, 'http://www.broken.djangoproject.com') # bad domain
565        self.assertRaises(ValidationError, f.clean, 'http://qa-dev.w3.org/link-testsuite/http.php?code=405') # Method not allowed
566        try:
567            f.clean('http://www.broken.djangoproject.com') # bad domain
568        except ValidationError, e:
569            self.assertEqual("[u'This URL appears to be a broken link.']", str(e))
570        self.assertRaises(ValidationError, f.clean, 'http://qa-dev.w3.org/link-testsuite/http.php?code=400') # good domain, bad page
571        try:
572            f.clean('http://google.com/we-love-microsoft.html') # good domain, bad page
573        except ValidationError, e:
574            self.assertEqual("[u'This URL appears to be a broken link.']", str(e))
575
576    def test_urlfield_4(self):
577        f = URLField(verify_exists=True, required=False)
578        self.assertEqual(u'', f.clean(''))
579        self.assertEqual(u'http://www.google.com/', f.clean('http://www.google.com')) # This will fail if there's no Internet connection
580
581    def test_urlfield_5(self):
582        f = URLField(min_length=15, max_length=20)
583        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 15 characters (it has 13).']", f.clean, 'http://f.com')
584        self.assertEqual(u'http://example.com/', f.clean('http://example.com'))
585        self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at most 20 characters (it has 38).']", f.clean, 'http://abcdefghijklmnopqrstuvwxyz.com')
586
587    def test_urlfield_6(self):
588        f = URLField(required=False)
589        self.assertEqual(u'http://example.com/', f.clean('example.com'))
590        self.assertEqual(u'', f.clean(''))
591        self.assertEqual(u'https://example.com/', f.clean('https://example.com'))
592
593    def test_urlfield_7(self):
594        f = URLField()
595        self.assertEqual(u'http://example.com/', f.clean('http://example.com'))
596        self.assertEqual(u'http://example.com/test', f.clean('http://example.com/test'))
597
598    def test_urlfield_8(self):
599        # ticket #11826
600        f = URLField()
601        self.assertEqual(u'http://example.com/?some_param=some_value', f.clean('http://example.com?some_param=some_value'))
602
603    def test_urlfield_9(self):
604        f = URLField(verify_exists=False)
605        urls = (
606            u'http://?????.idn.icann.org/',
607            u'http://sãopaulo.com/',
608            u'http://sãopaulo.com.br/',
609            u'http://??????.?????????/',
610            u'http://????.??????/',
611            u'http://??.??/',
612            u'http://??.??/',
613            u'http://??????.???????/',
614            u'http://??.???/',
615            u'http://????.???????/',
616            u'http://??.???/',
617            u'http://???????.idn.icann.org/',
618        )
619        for url in urls:
620            # Valid and existent IDN
621            self.assertEqual(url, f.clean(url))
622        # Valid but non-existent IDN
623        try:
624            f.clean(u'http://broken.?????.idn.icann.org/')
625        except ValidationError, e:
626            self.assertEqual("[u'This URL appears to be a broken link.']", str(e))
627
628    def test_urlfield_10(self):
629        # UTF-8 in the domain.
630        f = URLField(verify_exists=True)
631        url = u'http://\u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac.idn.icann.org/\u0391\u03c1\u03c7\u03b9\u03ba\u03ae_\u03c3\u03b5\u03bb\u03af\u03b4\u03b1'
632        self.assertEqual(url, f.clean(url)) #This will fail without internet.
633
634    # BooleanField ################################################################
635
636    def test_booleanfield_1(self):
637        f = BooleanField()
638        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
639        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
640        self.assertEqual(True, f.clean(True))
641        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, False)
642        self.assertEqual(True, f.clean(1))
643        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, 0)
644        self.assertEqual(True, f.clean('Django rocks'))
645        self.assertEqual(True, f.clean('True'))
646        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, 'False')
647
648    def test_booleanfield_2(self):
649        f = BooleanField(required=False)
650        self.assertEqual(False, f.clean(''))
651        self.assertEqual(False, f.clean(None))
652        self.assertEqual(True, f.clean(True))
653        self.assertEqual(False, f.clean(False))
654        self.assertEqual(True, f.clean(1))
655        self.assertEqual(False, f.clean(0))
656        self.assertEqual(True, f.clean('1'))
657        self.assertEqual(False, f.clean('0'))
658        self.assertEqual(True, f.clean('Django rocks'))
659        self.assertEqual(False, f.clean('False'))
660
661    # ChoiceField #################################################################
662
663    def test_choicefield_1(self):
664        f = ChoiceField(choices=[('1', 'One'), ('2', 'Two')])
665        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
666        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
667        self.assertEqual(u'1', f.clean(1))
668        self.assertEqual(u'1', f.clean('1'))
669        self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 3 is not one of the available choices.']", f.clean, '3')
670
671    def test_choicefield_2(self):
672        f = ChoiceField(choices=[('1', 'One'), ('2', 'Two')], required=False)
673        self.assertEqual(u'', f.clean(''))
674        self.assertEqual(u'', f.clean(None))
675        self.assertEqual(u'1', f.clean(1))
676        self.assertEqual(u'1', f.clean('1'))
677        self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 3 is not one of the available choices.']", f.clean, '3')
678
679    def test_choicefield_3(self):
680        f = ChoiceField(choices=[('J', 'John'), ('P', 'Paul')])
681        self.assertEqual(u'J', f.clean('J'))
682        self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. John is not one of the available choices.']", f.clean, 'John')
683
684    def test_choicefield_4(self):
685        f = ChoiceField(choices=[('Numbers', (('1', 'One'), ('2', 'Two'))), ('Letters', (('3','A'),('4','B'))), ('5','Other')])
686        self.assertEqual(u'1', f.clean(1))
687        self.assertEqual(u'1', f.clean('1'))
688        self.assertEqual(u'3', f.clean(3))
689        self.assertEqual(u'3', f.clean('3'))
690        self.assertEqual(u'5', f.clean(5))
691        self.assertEqual(u'5', f.clean('5'))
692        self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 6 is not one of the available choices.']", f.clean, '6')
693
694    # TypedChoiceField ############################################################
695    # TypedChoiceField is just like ChoiceField, except that coerced types will
696    # be returned:
697
698    def test_typedchoicefield_1(self):
699        f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int)
700        self.assertEqual(1, f.clean('1'))
701        self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 2 is not one of the available choices.']", f.clean, '2')
702
703    def test_typedchoicefield_2(self):
704        # Different coercion, same validation.
705        f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=float)
706        self.assertEqual(1.0, f.clean('1'))
707
708    def test_typedchoicefield_3(self):
709        # This can also cause weirdness: be careful (bool(-1) == True, remember)
710        f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=bool)
711        self.assertEqual(True, f.clean('-1'))
712
713    def test_typedchoicefield_4(self):
714        # Even more weirdness: if you have a valid choice but your coercion function
715        # can't coerce, you'll still get a validation error. Don't do this!
716        f = TypedChoiceField(choices=[('A', 'A'), ('B', 'B')], coerce=int)
717        self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. B is not one of the available choices.']", f.clean, 'B')
718        # Required fields require values
719        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
720
721    def test_typedchoicefield_5(self):
722        # Non-required fields aren't required
723        f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=False)
724        self.assertEqual('', f.clean(''))
725        # If you want cleaning an empty value to return a different type, tell the field
726
727    def test_typedchoicefield_6(self):
728        f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=False, empty_value=None)
729        self.assertEqual(None, f.clean(''))
730
731    # NullBooleanField ############################################################
732
733    def test_nullbooleanfield_1(self):
734        f = NullBooleanField()
735        self.assertEqual(None, f.clean(''))
736        self.assertEqual(True, f.clean(True))
737        self.assertEqual(False, f.clean(False))
738        self.assertEqual(None, f.clean(None))
739        self.assertEqual(False, f.clean('0'))
740        self.assertEqual(True, f.clean('1'))
741        self.assertEqual(None, f.clean('2'))
742        self.assertEqual(None, f.clean('3'))
743        self.assertEqual(None, f.clean('hello'))
744
745
746    def test_nullbooleanfield_2(self):
747        # Make sure that the internal value is preserved if using HiddenInput (#7753)
748        class HiddenNullBooleanForm(Form):
749            hidden_nullbool1 = NullBooleanField(widget=HiddenInput, initial=True)
750            hidden_nullbool2 = NullBooleanField(widget=HiddenInput, initial=False)
751        f = HiddenNullBooleanForm()
752        self.assertEqual('<input type="hidden" name="hidden_nullbool1" value="True" id="id_hidden_nullbool1" /><input type="hidden" name="hidden_nullbool2" value="False" id="id_hidden_nullbool2" />', str(f))
753
754    def test_nullbooleanfield_3(self):
755        class HiddenNullBooleanForm(Form):
756            hidden_nullbool1 = NullBooleanField(widget=HiddenInput, initial=True)
757            hidden_nullbool2 = NullBooleanField(widget=HiddenInput, initial=False)
758        f = HiddenNullBooleanForm({ 'hidden_nullbool1': 'True', 'hidden_nullbool2': 'False' })
759        self.assertEqual(None, f.full_clean())
760        self.assertEqual(True, f.cleaned_data['hidden_nullbool1'])
761        self.assertEqual(False, f.cleaned_data['hidden_nullbool2'])
762
763    def test_nullbooleanfield_4(self):
764        # Make sure we're compatible with MySQL, which uses 0 and 1 for its boolean
765        # values. (#9609)
766        NULLBOOL_CHOICES = (('1', 'Yes'), ('0', 'No'), ('', 'Unknown'))
767        class MySQLNullBooleanForm(Form):
768            nullbool0 = NullBooleanField(widget=RadioSelect(choices=NULLBOOL_CHOICES))
769            nullbool1 = NullBooleanField(widget=RadioSelect(choices=NULLBOOL_CHOICES))
770            nullbool2 = NullBooleanField(widget=RadioSelect(choices=NULLBOOL_CHOICES))
771        f = MySQLNullBooleanForm({ 'nullbool0': '1', 'nullbool1': '0', 'nullbool2': '' })
772        self.assertEqual(None, f.full_clean())
773        self.assertEqual(True, f.cleaned_data['nullbool0'])
774        self.assertEqual(False, f.cleaned_data['nullbool1'])
775        self.assertEqual(None, f.cleaned_data['nullbool2'])
776
777    # MultipleChoiceField #########################################################
778
779    def test_multiplechoicefield_1(self):
780        f = MultipleChoiceField(choices=[('1', 'One'), ('2', 'Two')])
781        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
782        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
783        self.assertEqual([u'1'], f.clean([1]))
784        self.assertEqual([u'1'], f.clean(['1']))
785        self.assertEqual([u'1', u'2'], f.clean(['1', '2']))
786        self.assertEqual([u'1', u'2'], f.clean([1, '2']))
787        self.assertEqual([u'1', u'2'], f.clean((1, '2')))
788        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a list of values.']", f.clean, 'hello')
789        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, [])
790        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, ())
791        self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 3 is not one of the available choices.']", f.clean, ['3'])
792
793    def test_multiplechoicefield_2(self):
794        f = MultipleChoiceField(choices=[('1', 'One'), ('2', 'Two')], required=False)
795        self.assertEqual([], f.clean(''))
796        self.assertEqual([], f.clean(None))
797        self.assertEqual([u'1'], f.clean([1]))
798        self.assertEqual([u'1'], f.clean(['1']))
799        self.assertEqual([u'1', u'2'], f.clean(['1', '2']))
800        self.assertEqual([u'1', u'2'], f.clean([1, '2']))
801        self.assertEqual([u'1', u'2'], f.clean((1, '2')))
802        self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a list of values.']", f.clean, 'hello')
803        self.assertEqual([], f.clean([]))
804        self.assertEqual([], f.clean(()))
805        self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 3 is not one of the available choices.']", f.clean, ['3'])
806
807    def test_multiplechoicefield_3(self):
808        f = MultipleChoiceField(choices=[('Numbers', (('1', 'One'), ('2', 'Two'))), ('Letters', (('3','A'),('4','B'))), ('5','Other')])
809        self.assertEqual([u'1'], f.clean([1]))
810        self.assertEqual([u'1'], f.clean(['1']))
811        self.assertEqual([u'1', u'5'], f.clean([1, 5]))
812        self.assertEqual([u'1', u'5'], f.clean([1, '5']))
813        self.assertEqual([u'1', u'5'], f.clean(['1', 5]))
814        self.assertEqual([u'1', u'5'], f.clean(['1', '5']))
815        self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 6 is not one of the available choices.']", f.clean, ['6'])
816        self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 6 is not one of the available choices.']", f.clean, ['1','6'])
817
818    # TypedMultipleChoiceField ############################################################
819    # TypedMultipleChoiceField is just like MultipleChoiceField, except that coerced types
820    # will be return…

Large files files are truncated, but you can click here to view the full file