From 0247c9b08f8da4a2d93b9cede6c615011552b55a Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Sat, 9 Apr 2016 20:17:34 +0300 Subject: [PATCH] Split form's test_fields.py into different files. --- tests/forms_tests/field_tests/__init__.py | 9 + tests/forms_tests/field_tests/test_base.py | 22 + .../field_tests/test_booleanfield.py | 56 + .../forms_tests/field_tests/test_charfield.py | 109 + .../field_tests/test_choicefield.py | 86 + .../field_tests/test_combofield.py | 29 + .../forms_tests/field_tests/test_datefield.py | 87 +- .../field_tests/test_datetimefield.py | 88 + .../field_tests/test_decimalfield.py | 158 ++ .../field_tests/test_durationfield.py | 39 + .../field_tests/test_emailfield.py | 50 + .../forms_tests/field_tests/test_filefield.py | 81 + .../field_tests/test_filepathfield.py | 121 ++ .../field_tests/test_floatfield.py | 81 + .../field_tests/test_genericipaddressfield.py | 129 ++ .../field_tests/test_imagefield.py | 60 + .../field_tests/test_integerfield.py | 136 ++ .../field_tests/test_multiplechoicefield.py | 72 + .../field_tests/test_multivaluefield.py | 8 +- .../field_tests/test_nullbooleanfield.py | 69 + .../field_tests/test_regexfield.py | 71 + .../forms_tests/field_tests/test_slugfield.py | 22 + .../field_tests/test_splitdatetimefield.py | 64 + .../forms_tests/field_tests/test_timefield.py | 47 + .../field_tests/test_typedchoicefield.py | 79 + .../test_typedmultiplechoicefield.py | 76 + .../forms_tests/field_tests/test_urlfield.py | 153 ++ .../forms_tests/field_tests/test_uuidfield.py | 30 + tests/forms_tests/tests/test_fields.py | 1887 ----------------- 29 files changed, 2022 insertions(+), 1897 deletions(-) create mode 100644 tests/forms_tests/field_tests/test_base.py create mode 100644 tests/forms_tests/field_tests/test_booleanfield.py create mode 100644 tests/forms_tests/field_tests/test_charfield.py create mode 100644 tests/forms_tests/field_tests/test_choicefield.py create mode 100644 tests/forms_tests/field_tests/test_combofield.py create mode 100644 tests/forms_tests/field_tests/test_datetimefield.py create mode 100644 tests/forms_tests/field_tests/test_decimalfield.py create mode 100644 tests/forms_tests/field_tests/test_durationfield.py create mode 100644 tests/forms_tests/field_tests/test_emailfield.py create mode 100644 tests/forms_tests/field_tests/test_filefield.py create mode 100644 tests/forms_tests/field_tests/test_filepathfield.py create mode 100644 tests/forms_tests/field_tests/test_floatfield.py create mode 100644 tests/forms_tests/field_tests/test_genericipaddressfield.py create mode 100644 tests/forms_tests/field_tests/test_imagefield.py create mode 100644 tests/forms_tests/field_tests/test_integerfield.py create mode 100644 tests/forms_tests/field_tests/test_multiplechoicefield.py create mode 100644 tests/forms_tests/field_tests/test_nullbooleanfield.py create mode 100644 tests/forms_tests/field_tests/test_regexfield.py create mode 100644 tests/forms_tests/field_tests/test_slugfield.py create mode 100644 tests/forms_tests/field_tests/test_splitdatetimefield.py create mode 100644 tests/forms_tests/field_tests/test_timefield.py create mode 100644 tests/forms_tests/field_tests/test_typedchoicefield.py create mode 100644 tests/forms_tests/field_tests/test_typedmultiplechoicefield.py create mode 100644 tests/forms_tests/field_tests/test_urlfield.py create mode 100644 tests/forms_tests/field_tests/test_uuidfield.py delete mode 100644 tests/forms_tests/tests/test_fields.py diff --git a/tests/forms_tests/field_tests/__init__.py b/tests/forms_tests/field_tests/__init__.py index e69de29bb2..b984c6fb40 100644 --- a/tests/forms_tests/field_tests/__init__.py +++ b/tests/forms_tests/field_tests/__init__.py @@ -0,0 +1,9 @@ +from django import forms + + +class FormFieldAssertionsMixin(object): + + def assertWidgetRendersTo(self, field, to): + class Form(forms.Form): + f = field + self.assertHTMLEqual(str(Form()['f']), to) diff --git a/tests/forms_tests/field_tests/test_base.py b/tests/forms_tests/field_tests/test_base.py new file mode 100644 index 0000000000..2eea92a149 --- /dev/null +++ b/tests/forms_tests/field_tests/test_base.py @@ -0,0 +1,22 @@ +from django.forms import Field +from django.test import SimpleTestCase + + +class BasicFieldsTests(SimpleTestCase): + + def test_field_sets_widget_is_required(self): + self.assertTrue(Field(required=True).widget.is_required) + self.assertFalse(Field(required=False).widget.is_required) + + def test_cooperative_multiple_inheritance(self): + class A(object): + def __init__(self): + self.class_a_var = True + super(A, self).__init__() + + class ComplexField(Field, A): + def __init__(self): + super(ComplexField, self).__init__() + + f = ComplexField() + self.assertTrue(f.class_a_var) diff --git a/tests/forms_tests/field_tests/test_booleanfield.py b/tests/forms_tests/field_tests/test_booleanfield.py new file mode 100644 index 0000000000..9c69c96762 --- /dev/null +++ b/tests/forms_tests/field_tests/test_booleanfield.py @@ -0,0 +1,56 @@ +from __future__ import unicode_literals + +import pickle + +from django.forms import BooleanField, ValidationError +from django.test import SimpleTestCase + + +class BooleanFieldTest(SimpleTestCase): + + def test_booleanfield_clean_1(self): + f = BooleanField() + with self.assertRaisesMessage(ValidationError, "'This field is required.'"): + f.clean('') + with self.assertRaisesMessage(ValidationError, "'This field is required.'"): + f.clean(None) + self.assertTrue(f.clean(True)) + with self.assertRaisesMessage(ValidationError, "'This field is required.'"): + f.clean(False) + self.assertTrue(f.clean(1)) + with self.assertRaisesMessage(ValidationError, "'This field is required.'"): + f.clean(0) + self.assertTrue(f.clean('Django rocks')) + self.assertTrue(f.clean('True')) + with self.assertRaisesMessage(ValidationError, "'This field is required.'"): + f.clean('False') + + def test_booleanfield_clean_2(self): + f = BooleanField(required=False) + self.assertEqual(False, f.clean('')) + self.assertEqual(False, f.clean(None)) + self.assertEqual(True, f.clean(True)) + self.assertEqual(False, f.clean(False)) + self.assertEqual(True, f.clean(1)) + self.assertEqual(False, f.clean(0)) + self.assertEqual(True, f.clean('1')) + self.assertEqual(False, f.clean('0')) + self.assertEqual(True, f.clean('Django rocks')) + self.assertEqual(False, f.clean('False')) + self.assertEqual(False, f.clean('false')) + self.assertEqual(False, f.clean('FaLsE')) + + def test_boolean_picklable(self): + self.assertIsInstance(pickle.loads(pickle.dumps(BooleanField())), BooleanField) + + def test_booleanfield_changed(self): + f = BooleanField() + self.assertFalse(f.has_changed(None, None)) + self.assertFalse(f.has_changed(None, '')) + self.assertFalse(f.has_changed('', None)) + self.assertFalse(f.has_changed('', '')) + self.assertTrue(f.has_changed(False, 'on')) + self.assertFalse(f.has_changed(True, 'on')) + self.assertTrue(f.has_changed(True, '')) + # Initial value may have mutated to a string due to show_hidden_initial (#19537) + self.assertTrue(f.has_changed('False', 'on')) diff --git a/tests/forms_tests/field_tests/test_charfield.py b/tests/forms_tests/field_tests/test_charfield.py new file mode 100644 index 0000000000..82f2035ea5 --- /dev/null +++ b/tests/forms_tests/field_tests/test_charfield.py @@ -0,0 +1,109 @@ +from __future__ import unicode_literals + +from django.forms import ( + CharField, PasswordInput, Textarea, TextInput, ValidationError, +) +from django.test import SimpleTestCase + +from . import FormFieldAssertionsMixin + + +class CharFieldTest(FormFieldAssertionsMixin, SimpleTestCase): + + def test_charfield_1(self): + f = CharField() + self.assertEqual('1', f.clean(1)) + self.assertEqual('hello', f.clean('hello')) + with self.assertRaisesMessage(ValidationError, "'This field is required.'"): + f.clean(None) + with self.assertRaisesMessage(ValidationError, "'This field is required.'"): + f.clean('') + self.assertEqual('[1, 2, 3]', f.clean([1, 2, 3])) + self.assertIsNone(f.max_length) + self.assertIsNone(f.min_length) + + def test_charfield_2(self): + f = CharField(required=False) + self.assertEqual('1', f.clean(1)) + self.assertEqual('hello', f.clean('hello')) + self.assertEqual('', f.clean(None)) + self.assertEqual('', f.clean('')) + self.assertEqual('[1, 2, 3]', f.clean([1, 2, 3])) + self.assertIsNone(f.max_length) + self.assertIsNone(f.min_length) + + def test_charfield_3(self): + f = CharField(max_length=10, required=False) + self.assertEqual('12345', f.clean('12345')) + self.assertEqual('1234567890', f.clean('1234567890')) + msg = "'Ensure this value has at most 10 characters (it has 11).'" + with self.assertRaisesMessage(ValidationError, msg): + f.clean('1234567890a') + self.assertEqual(f.max_length, 10) + self.assertIsNone(f.min_length) + + def test_charfield_4(self): + f = CharField(min_length=10, required=False) + self.assertEqual('', f.clean('')) + msg = "'Ensure this value has at least 10 characters (it has 5).'" + with self.assertRaisesMessage(ValidationError, msg): + f.clean('12345') + self.assertEqual('1234567890', f.clean('1234567890')) + self.assertEqual('1234567890a', f.clean('1234567890a')) + self.assertIsNone(f.max_length) + self.assertEqual(f.min_length, 10) + + def test_charfield_5(self): + f = CharField(min_length=10, required=True) + with self.assertRaisesMessage(ValidationError, "'This field is required.'"): + f.clean('') + msg = "'Ensure this value has at least 10 characters (it has 5).'" + with self.assertRaisesMessage(ValidationError, msg): + f.clean('12345') + self.assertEqual('1234567890', f.clean('1234567890')) + self.assertEqual('1234567890a', f.clean('1234567890a')) + self.assertIsNone(f.max_length) + self.assertEqual(f.min_length, 10) + + def test_charfield_length_not_int(self): + """ + Setting min_length or max_length to something that is not a number + raises an exception. + """ + with self.assertRaises(ValueError): + CharField(min_length='a') + with self.assertRaises(ValueError): + CharField(max_length='a') + with self.assertRaises(ValueError): + CharField('a') + + def test_charfield_widget_attrs(self): + """ + CharField.widget_attrs() always returns a dictionary (#15912). + """ + # Return an empty dictionary if max_length is None + f = CharField() + self.assertEqual(f.widget_attrs(TextInput()), {}) + self.assertEqual(f.widget_attrs(Textarea()), {}) + + # Otherwise, return a maxlength attribute equal to max_length + f = CharField(max_length=10) + self.assertEqual(f.widget_attrs(TextInput()), {'maxlength': '10'}) + self.assertEqual(f.widget_attrs(PasswordInput()), {'maxlength': '10'}) + self.assertEqual(f.widget_attrs(Textarea()), {'maxlength': '10'}) + + def test_charfield_strip(self): + """ + Values have whitespace stripped but not if strip=False. + """ + f = CharField() + self.assertEqual(f.clean(' 1'), '1') + self.assertEqual(f.clean('1 '), '1') + + f = CharField(strip=False) + self.assertEqual(f.clean(' 1'), ' 1') + self.assertEqual(f.clean('1 '), '1 ') + + def test_charfield_disabled(self): + f = CharField(disabled=True) + self.assertWidgetRendersTo(f, '') diff --git a/tests/forms_tests/field_tests/test_choicefield.py b/tests/forms_tests/field_tests/test_choicefield.py new file mode 100644 index 0000000000..013766d50b --- /dev/null +++ b/tests/forms_tests/field_tests/test_choicefield.py @@ -0,0 +1,86 @@ +from __future__ import unicode_literals + +from django.forms import ChoiceField, Form, ValidationError +from django.test import SimpleTestCase + +from . import FormFieldAssertionsMixin + + +class ChoiceFieldTest(FormFieldAssertionsMixin, SimpleTestCase): + + def test_choicefield_1(self): + f = ChoiceField(choices=[('1', 'One'), ('2', 'Two')]) + with self.assertRaisesMessage(ValidationError, "'This field is required.'"): + f.clean('') + with self.assertRaisesMessage(ValidationError, "'This field is required.'"): + f.clean(None) + self.assertEqual('1', f.clean(1)) + self.assertEqual('1', f.clean('1')) + msg = "'Select a valid choice. 3 is not one of the available choices.'" + with self.assertRaisesMessage(ValidationError, msg): + f.clean('3') + + def test_choicefield_2(self): + f = ChoiceField(choices=[('1', 'One'), ('2', 'Two')], required=False) + self.assertEqual('', f.clean('')) + self.assertEqual('', f.clean(None)) + self.assertEqual('1', f.clean(1)) + self.assertEqual('1', f.clean('1')) + msg = "'Select a valid choice. 3 is not one of the available choices.'" + with self.assertRaisesMessage(ValidationError, msg): + f.clean('3') + + def test_choicefield_3(self): + f = ChoiceField(choices=[('J', 'John'), ('P', 'Paul')]) + self.assertEqual('J', f.clean('J')) + msg = "'Select a valid choice. John is not one of the available choices.'" + with self.assertRaisesMessage(ValidationError, msg): + f.clean('John') + + def test_choicefield_4(self): + f = ChoiceField( + choices=[ + ('Numbers', (('1', 'One'), ('2', 'Two'))), + ('Letters', (('3', 'A'), ('4', 'B'))), ('5', 'Other'), + ] + ) + self.assertEqual('1', f.clean(1)) + self.assertEqual('1', f.clean('1')) + self.assertEqual('3', f.clean(3)) + self.assertEqual('3', f.clean('3')) + self.assertEqual('5', f.clean(5)) + self.assertEqual('5', f.clean('5')) + msg = "'Select a valid choice. 6 is not one of the available choices.'" + with self.assertRaisesMessage(ValidationError, msg): + f.clean('6') + + def test_choicefield_callable(self): + def choices(): + return [('J', 'John'), ('P', 'Paul')] + f = ChoiceField(choices=choices) + self.assertEqual('J', f.clean('J')) + + def test_choicefield_callable_may_evaluate_to_different_values(self): + choices = [] + + def choices_as_callable(): + return choices + + class ChoiceFieldForm(Form): + choicefield = ChoiceField(choices=choices_as_callable) + + choices = [('J', 'John')] + form = ChoiceFieldForm() + self.assertEqual([('J', 'John')], list(form.fields['choicefield'].choices)) + + choices = [('P', 'Paul')] + form = ChoiceFieldForm() + self.assertEqual([('P', 'Paul')], list(form.fields['choicefield'].choices)) + + def test_choicefield_disabled(self): + f = ChoiceField(choices=[('J', 'John'), ('P', 'Paul')], disabled=True) + self.assertWidgetRendersTo( + f, + '' + ) diff --git a/tests/forms_tests/field_tests/test_combofield.py b/tests/forms_tests/field_tests/test_combofield.py new file mode 100644 index 0000000000..6ca91233bc --- /dev/null +++ b/tests/forms_tests/field_tests/test_combofield.py @@ -0,0 +1,29 @@ +from __future__ import unicode_literals + +from django.forms import CharField, ComboField, EmailField, ValidationError +from django.test import SimpleTestCase + + +class ComboFieldTest(SimpleTestCase): + + def test_combofield_1(self): + f = ComboField(fields=[CharField(max_length=20), EmailField()]) + self.assertEqual('test@example.com', f.clean('test@example.com')) + with self.assertRaisesMessage(ValidationError, "'Ensure this value has at most 20 characters (it has 28).'"): + f.clean('longemailaddress@example.com') + with self.assertRaisesMessage(ValidationError, "'Enter a valid email address.'"): + f.clean('not an email') + with self.assertRaisesMessage(ValidationError, "'This field is required.'"): + f.clean('') + with self.assertRaisesMessage(ValidationError, "'This field is required.'"): + f.clean(None) + + def test_combofield_2(self): + f = ComboField(fields=[CharField(max_length=20), EmailField()], required=False) + self.assertEqual('test@example.com', f.clean('test@example.com')) + with self.assertRaisesMessage(ValidationError, "'Ensure this value has at most 20 characters (it has 28).'"): + f.clean('longemailaddress@example.com') + with self.assertRaisesMessage(ValidationError, "'Enter a valid email address.'"): + f.clean('not an email') + self.assertEqual('', f.clean('')) + self.assertEqual('', f.clean(None)) diff --git a/tests/forms_tests/field_tests/test_datefield.py b/tests/forms_tests/field_tests/test_datefield.py index 6b66cb2d52..75dda3425b 100644 --- a/tests/forms_tests/field_tests/test_datefield.py +++ b/tests/forms_tests/field_tests/test_datefield.py @@ -1,6 +1,9 @@ -from datetime import date +# -*- coding: utf-8 -*- +from datetime import date, datetime -from django.forms import DateField, Form, HiddenInput, SelectDateWidget +from django.forms import ( + DateField, Form, HiddenInput, SelectDateWidget, ValidationError, +) from django.test import SimpleTestCase, override_settings from django.utils import translation @@ -40,8 +43,8 @@ class DateFieldTest(SimpleTestCase): @translation.override('nl') def test_l10n_date_changed(self): """ - Ensure that DateField.has_changed() with SelectDateWidget works - correctly with a localized date format (#17165). + DateField.has_changed() with SelectDateWidget works with a localized + date format (#17165). """ # With Field.show_hidden_initial=False b = GetDate({ @@ -109,3 +112,79 @@ class DateFieldTest(SimpleTestCase): # label tag is correctly associated with first rendered dropdown a = GetDate({'mydate_month': '1', 'mydate_day': '1', 'mydate_year': '2010'}) self.assertIn('