Commit 2664fa18 authored by Russell Keith-Magee's avatar Russell Keith-Magee
Browse files

Fixed #15838 -- Promoted assertFieldOutput to a general test utility. Thanks...

Fixed #15838 -- Promoted assertFieldOutput to a general test utility. Thanks to Ramiro Morales for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16653 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 46ef2983
Loading
Loading
Loading
Loading
+54 −4
Original line number Diff line number Diff line
@@ -8,11 +8,14 @@ from xml.dom.minidom import parseString, Node

from django.conf import settings
from django.core import mail
from django.core.exceptions import ValidationError
from django.core.management import call_command
from django.core.signals import request_started
from django.core.urlresolvers import clear_url_caches
from django.core.validators import EMPTY_VALUES
from django.db import (transaction, connection, connections, DEFAULT_DB_ALIAS,
    reset_queries)
from django.forms.fields import CharField
from django.http import QueryDict
from django.test import _doctest as doctest
from django.test.client import Client
@@ -271,6 +274,53 @@ class SimpleTestCase(ut2.TestCase):
        return self.assertRaisesRegexp(expected_exception,
                re.escape(expected_message), callable_obj, *args, **kwargs)

    def assertFieldOutput(self, fieldclass, valid, invalid, field_args=None,
            field_kwargs=None, empty_value=u''):
        """
        Asserts that a form field behaves correctly with various inputs.

        Args:
            fieldclass: the class of the field to be tested.
            valid: a dictionary mapping valid inputs to their expected
                    cleaned values.
            invalid: a dictionary mapping invalid inputs to one or more
                    raised error messages.
            field_args: the args passed to instantiate the field
            field_kwargs: the kwargs passed to instantiate the field
            empty_value: the expected clean output for inputs in EMPTY_VALUES

        """
        if field_args is None:
            field_args = []
        if field_kwargs is None:
            field_kwargs = {}
        required = fieldclass(*field_args, **field_kwargs)
        optional = fieldclass(*field_args, **dict(field_kwargs, required=False))
        # test valid inputs
        for input, output in valid.items():
            self.assertEqual(required.clean(input), output)
            self.assertEqual(optional.clean(input), output)
        # test invalid inputs
        for input, errors in invalid.items():
            with self.assertRaises(ValidationError) as context_manager:
                required.clean(input)
            self.assertEqual(context_manager.exception.messages, errors)

            with self.assertRaises(ValidationError) as context_manager:
                optional.clean(input)
            self.assertEqual(context_manager.exception.messages, errors)
        # test required inputs
        error_required = [u'This field is required.']
        for e in EMPTY_VALUES:
            with self.assertRaises(ValidationError) as context_manager:
                required.clean(e)
            self.assertEqual(context_manager.exception.messages, error_required)
            self.assertEqual(optional.clean(e), empty_value)
        # test that max_length and min_length are always accepted
        if issubclass(fieldclass, CharField):
            field_kwargs.update({'min_length':2, 'max_length':20})
            self.assertTrue(isinstance(fieldclass(*field_args, **field_kwargs), fieldclass))

class TransactionTestCase(SimpleTestCase):
    # The class we'll use for the test client self.client.
    # Can be overridden in derived classes.
@@ -356,8 +406,8 @@ class TransactionTestCase(SimpleTestCase):
        # be created with the wrong time).
        # To make sure this doesn't happen, get a clean connection at the
        # start of every test.
        for connection in connections.all():
            connection.close()
        for conn in connections.all():
            conn.close()

    def _fixture_teardown(self):
        pass
@@ -552,9 +602,9 @@ class TransactionTestCase(SimpleTestCase):

    def assertNumQueries(self, num, func=None, *args, **kwargs):
        using = kwargs.pop("using", DEFAULT_DB_ALIAS)
        connection = connections[using]
        conn = connections[using]

        context = _AssertNumQueriesContext(self, num, connection)
        context = _AssertNumQueriesContext(self, num, conn)
        if func is None:
            return context

+21 −0
Original line number Diff line number Diff line
@@ -1178,6 +1178,7 @@ basic functionality like:

 * Saving and restoring the Python warning machinery state.
 * Checking that a callable :meth:`raises a certain exeception <TestCase.assertRaisesMessage>`.
 * :meth:`Testing form field rendering <assertFieldOutput>`.

If you need any of the other more complex and heavyweight Django-specific
features like:
@@ -1523,6 +1524,26 @@ your test suite.
    failure. Similar to unittest's ``assertRaisesRegexp`` with the difference
    that ``expected_message`` isn't a regular expression.

.. method:: assertFieldOutput(self, fieldclass, valid, invalid, field_args=None, field_kwargs=None, empty_value=u'')

    Asserts that a form field behaves correctly with various inputs.

    :param fieldclass: the class of the field to be tested.
    :param valid: a dictionary mapping valid inputs to their expected cleaned
        values.
    :param invalid: a dictionary mapping invalid inputs to one or more raised
        error messages.
    :param field_args: the args passed to instantiate the field.
    :param field_kwargs: the kwargs passed to instantiate the field.
    :param empty_value: the expected clean output for inputs in ``EMPTY_VALUES``.

    For example, the following code tests that an ``EmailField`` accepts
    "a@a.com" as a valid email address, but rejects "aaa" with a reasonable
    error message::

        self.assertFieldOutput(EmailField, {'a@a.com': 'a@a.com'}, {'aaa': [u'Enter a valid e-mail address.']})


.. method:: TestCase.assertContains(response, text, count=None, status_code=200, msg_prefix='')

    Asserts that a ``Response`` instance produced the given ``status_code`` and
+1 −11
Original line number Diff line number Diff line
from django.forms import EmailField
from utils import LocalFlavorTestCase

class AssertFieldOutputTests(LocalFlavorTestCase):

    def test_assert_field_output(self):
        error_invalid = [u'Enter a valid e-mail address.']
        self.assertFieldOutput(EmailField, {'a@a.com': 'a@a.com'}, {'aaa': error_invalid})
        self.assertRaises(AssertionError, self.assertFieldOutput, EmailField, {'a@a.com': 'a@a.com'}, {'aaa': error_invalid + [u'Another error']})
        self.assertRaises(AssertionError, self.assertFieldOutput, EmailField, {'a@a.com': 'Wrong output'}, {'aaa': error_invalid})
        self.assertRaises(AssertionError, self.assertFieldOutput, EmailField, {'a@a.com': 'a@a.com'}, {'aaa': [u'Come on, gimme some well formatted data, dude.']})
#
+2 −2
Original line number Diff line number Diff line
from django.contrib.localflavor.ar.forms import (ARProvinceSelect,
    ARPostalCodeField, ARDNIField, ARCUITField)

from utils import LocalFlavorTestCase
from django.test import SimpleTestCase


class ARLocalFlavorTests(LocalFlavorTestCase):
class ARLocalFlavorTests(SimpleTestCase):
    def test_ARProvinceSelect(self):
        f = ARProvinceSelect()
        out = u'''<select name="provincias">
+2 −2
Original line number Diff line number Diff line
from django.contrib.localflavor.at.forms import (ATZipCodeField, ATStateSelect,
    ATSocialSecurityNumberField)

from utils import LocalFlavorTestCase
from django.test import SimpleTestCase


class ATLocalFlavorTests(LocalFlavorTestCase):
class ATLocalFlavorTests(SimpleTestCase):
    def test_ATStateSelect(self):
        f = ATStateSelect()
        out = u'''<select name="bundesland">
Loading