Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #16921 -- Added assertHTMLEqual and assertHTMLNotEqual assertio…

…ns, and converted Django tests to use them where appropriate. Thanks Greg Müllegger.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17414 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 844a24bbb97af663ebf8dbeab4499acafe105943 1 parent c82f1dc
@carljm carljm authored
Showing with 1,345 additions and 639 deletions.
  1. +221 −0 django/test/html.py
  2. +62 −4 django/test/testcases.py
  3. +94 −0 django/utils/htmlparser.py
  4. +15 −0 docs/releases/1.4.txt
  5. +60 −2 docs/topics/testing.txt
  6. +4 −4 tests/modeltests/generic_relations/tests.py
  7. +24 −24 tests/modeltests/model_forms/tests.py
  8. +42 −42 tests/modeltests/model_formsets/tests.py
  9. +3 −3 tests/regressiontests/admin_inlines/tests.py
  10. +25 −26 tests/regressiontests/admin_views/tests.py
  11. +19 −19 tests/regressiontests/admin_widgets/tests.py
  12. +5 −6 tests/regressiontests/forms/tests/error_messages.py
  13. +19 −16 tests/regressiontests/forms/tests/extra.py
  14. +2 −1  tests/regressiontests/forms/tests/fields.py
  15. +180 −177 tests/regressiontests/forms/tests/forms.py
  16. +19 −19 tests/regressiontests/forms/tests/formsets.py
  17. +2 −2 tests/regressiontests/forms/tests/models.py
  18. +14 −14 tests/regressiontests/forms/tests/regressions.py
  19. +14 −13 tests/regressiontests/forms/tests/util.py
  20. +202 −202 tests/regressiontests/forms/tests/widgets.py
  21. +8 −8 tests/regressiontests/generic_inline_admin/tests.py
  22. +5 −5 tests/regressiontests/i18n/tests.py
  23. +1 −1  tests/regressiontests/localflavor/ar/tests.py
  24. +1 −1  tests/regressiontests/localflavor/at/tests.py
  25. +1 −1  tests/regressiontests/localflavor/au/tests.py
  26. +2 −2 tests/regressiontests/localflavor/be/tests.py
  27. +1 −1  tests/regressiontests/localflavor/br/tests.py
  28. +1 −1  tests/regressiontests/localflavor/ca/tests.py
  29. +1 −1  tests/regressiontests/localflavor/ch/tests.py
  30. +1 −1  tests/regressiontests/localflavor/cl/tests.py
  31. +1 −1  tests/regressiontests/localflavor/cn/tests.py
  32. +1 −1  tests/regressiontests/localflavor/co/tests.py
  33. +1 −1  tests/regressiontests/localflavor/cz/tests.py
  34. +1 −1  tests/regressiontests/localflavor/de/tests.py
  35. +1 −1  tests/regressiontests/localflavor/ec/tests.py
  36. +2 −2 tests/regressiontests/localflavor/es/tests.py
  37. +1 −1  tests/regressiontests/localflavor/fi/tests.py
  38. +1 −1  tests/regressiontests/localflavor/fr/tests.py
  39. +3 −3 tests/regressiontests/localflavor/hr/tests.py
  40. +2 −2 tests/regressiontests/localflavor/id/tests.py
  41. +1 −1  tests/regressiontests/localflavor/ie/tests.py
  42. +1 −1  tests/regressiontests/localflavor/in_/tests.py
  43. +1 −1  tests/regressiontests/localflavor/is_/tests.py
  44. +1 −1  tests/regressiontests/localflavor/it/tests.py
  45. +1 −1  tests/regressiontests/localflavor/jp/tests.py
  46. +2 −2 tests/regressiontests/localflavor/mk/tests.py
  47. +2 −2 tests/regressiontests/localflavor/mx/tests.py
  48. +1 −1  tests/regressiontests/localflavor/nl/tests.py
  49. +2 −2 tests/regressiontests/localflavor/pl/tests.py
  50. +2 −2 tests/regressiontests/localflavor/py/tests.py
  51. +1 −1  tests/regressiontests/localflavor/ro/tests.py
  52. +2 −2 tests/regressiontests/localflavor/ru/tests.py
  53. +1 −1  tests/regressiontests/localflavor/se/tests.py
  54. +1 −1  tests/regressiontests/localflavor/si/tests.py
  55. +2 −2 tests/regressiontests/localflavor/sk/tests.py
  56. +3 −3 tests/regressiontests/localflavor/us/tests.py
  57. +1 −1  tests/regressiontests/localflavor/uy/tests.py
  58. +1 −1  tests/regressiontests/model_forms_regress/tests.py
  59. +2 −2 tests/regressiontests/modeladmin/tests.py
  60. +254 −0 tests/regressiontests/test_utils/tests.py
  61. +1 −1  tests/regressiontests/views/tests/generic/create_update.py
View
221 django/test/html.py
@@ -0,0 +1,221 @@
+"""
+Comparing two html documents.
+"""
+import re
+from HTMLParser import HTMLParseError
+from django.utils.encoding import force_unicode
+from django.utils.htmlparser import HTMLParser
+
+
+WHITESPACE = re.compile('\s+')
+
+
+def normalize_whitespace(string):
+ return WHITESPACE.sub(' ', string)
+
+
+class Element(object):
+ def __init__(self, name, attributes):
+ self.name = name
+ self.attributes = sorted(attributes)
+ self.children = []
+
+ def append(self, element):
+ if isinstance(element, basestring):
+ element = force_unicode(element)
+ element = normalize_whitespace(element)
+ if self.children:
+ if isinstance(self.children[-1], basestring):
+ self.children[-1] += element
+ self.children[-1] = normalize_whitespace(self.children[-1])
+ return
+ elif self.children:
+ # removing last children if it is only whitespace
+ # this can result in incorrect dom representations since
+ # whitespace between inline tags like <span> is significant
+ if isinstance(self.children[-1], basestring):
+ if self.children[-1].isspace():
+ self.children.pop()
+ if element:
+ self.children.append(element)
+
+ def finalize(self):
+ def rstrip_last_element(children):
+ if children:
+ if isinstance(children[-1], basestring):
+ children[-1] = children[-1].rstrip()
+ if not children[-1]:
+ children.pop()
+ children = rstrip_last_element(children)
+ return children
+
+ rstrip_last_element(self.children)
+ for i, child in enumerate(self.children):
+ if isinstance(child, basestring):
+ self.children[i] = child.strip()
+ elif hasattr(child, 'finalize'):
+ child.finalize()
+
+ def __eq__(self, element):
+ if not hasattr(element, 'name'):
+ return False
+ if hasattr(element, 'name') and self.name != element.name:
+ return False
+ if len(self.attributes) != len(element.attributes):
+ return False
+ if self.attributes != element.attributes:
+ # attributes without a value is same as attribute with value that
+ # equals the attributes name:
+ # <input checked> == <input checked="checked">
+ for i in range(len(self.attributes)):
+ attr, value = self.attributes[i]
+ other_attr, other_value = element.attributes[i]
+ if value is None:
+ value = attr
+ if other_value is None:
+ other_value = other_attr
+ if attr != other_attr or value != other_value:
+ return False
+ if self.children != element.children:
+ return False
+ return True
+
+ def __ne__(self, element):
+ return not self.__eq__(element)
+
+ def _count(self, element, count=True):
+ if not isinstance(element, basestring):
+ if self == element:
+ return 1
+ i = 0
+ for child in self.children:
+ # child is text content and element is also text content, then
+ # make a simple "text" in "text"
+ if isinstance(child, basestring):
+ if isinstance(element, basestring):
+ if count:
+ i += child.count(element)
+ elif element in child:
+ return 1
+ else:
+ i += child._count(element, count=count)
+ if not count and i:
+ return i
+ return i
+
+ def __contains__(self, element):
+ return self._count(element, count=False) > 0
+
+ def count(self, element):
+ return self._count(element, count=True)
+
+ def __getitem__(self, key):
+ return self.children[key]
+
+ def __unicode__(self):
+ output = u'<%s' % self.name
+ for key, value in self.attributes:
+ if value:
+ output += u' %s="%s"' % (key, value)
+ else:
+ output += u' %s' % key
+ if self.children:
+ output += u'>\n'
+ output += u''.join(unicode(c) for c in self.children)
+ output += u'\n</%s>' % self.name
+ else:
+ output += u' />'
+ return output
+
+ def __repr__(self):
+ return unicode(self)
+
+
+class RootElement(Element):
+ def __init__(self):
+ super(RootElement, self).__init__(None, ())
+
+ def __unicode__(self):
+ return u''.join(unicode(c) for c in self.children)
+
+
+class Parser(HTMLParser):
+ SELF_CLOSING_TAGS = ('br' , 'hr', 'input', 'img', 'meta', 'spacer',
+ 'link', 'frame', 'base', 'col')
+
+ def __init__(self):
+ HTMLParser.__init__(self)
+ self.root = RootElement()
+ self.open_tags = []
+ self.element_positions = {}
+
+ def error(self, msg):
+ raise HTMLParseError(msg, self.getpos())
+
+ def format_position(self, position=None, element=None):
+ if not position and element:
+ position = self.element_positions[element]
+ if position is None:
+ position = self.getpos()
+ if hasattr(position, 'lineno'):
+ position = position.lineno, position.offset
+ return 'Line %d, Column %d' % position
+
+ @property
+ def current(self):
+ if self.open_tags:
+ return self.open_tags[-1]
+ else:
+ return self.root
+
+ def handle_startendtag(self, tag, attrs):
+ self.handle_starttag(tag, attrs)
+ if tag not in self.SELF_CLOSING_TAGS:
+ self.handle_endtag(tag)
+
+ def handle_starttag(self, tag, attrs):
+ element = Element(tag, attrs)
+ self.current.append(element)
+ if tag not in self.SELF_CLOSING_TAGS:
+ self.open_tags.append(element)
+ self.element_positions[element] = self.getpos()
+
+ def handle_endtag(self, tag):
+ if not self.open_tags:
+ self.error("Unexpected end tag `%s` (%s)" % (
+ tag, self.format_position()))
+ element = self.open_tags.pop()
+ while element.name != tag:
+ if not self.open_tags:
+ self.error("Unexpected end tag `%s` (%s)" % (
+ tag, self.format_position()))
+ element = self.open_tags.pop()
+
+ def handle_data(self, data):
+ self.current.append(data)
+
+ def handle_charref(self, name):
+ self.current.append('&%s;' % name)
+
+ def handle_entityref(self, name):
+ self.current.append('&%s;' % name)
+
+
+def parse_html(html):
+ """
+ Takes a string that contains *valid* HTML and turns it into a Python object
+ structure that can be easily compared against other HTML on semantic
+ equivilance. Syntactical differences like which quotation is used on
+ arguments will be ignored.
+
+ """
+ parser = Parser()
+ parser.feed(html)
+ parser.close()
+ document = parser.root
+ document.finalize()
+ # Removing ROOT element if it's not necessary
+ if len(document.children) == 1:
+ if not isinstance(document.children[0], basestring):
+ document = document.children[0]
+ return document
View
66 django/test/testcases.py
@@ -1,5 +1,6 @@
from __future__ import with_statement
+import difflib
import os
import re
import sys
@@ -29,12 +30,14 @@
from django.http import QueryDict
from django.test import _doctest as doctest
from django.test.client import Client
+from django.test.html import HTMLParseError, parse_html
from django.test.signals import template_rendered
from django.test.utils import (get_warnings_state, restore_warnings_state,
override_settings)
from django.test.utils import ContextList
from django.utils import simplejson, unittest as ut2
from django.utils.encoding import smart_str, force_unicode
+from django.utils.unittest.util import safe_repr
from django.views.static import serve
__all__ = ('DocTestRunner', 'OutputChecker', 'TestCase', 'TransactionTestCase',
@@ -78,6 +81,16 @@ def restore_transaction_methods():
transaction.leave_transaction_management = real_leave_transaction_management
transaction.managed = real_managed
+
+def assert_and_parse_html(self, html, user_msg, msg):
+ try:
+ dom = parse_html(html)
+ except HTMLParseError, e:
+ standardMsg = u'%s\n%s' % (msg, e.msg)
+ self.fail(self._formatMessage(user_msg, standardMsg))
+ return dom
+
+
class OutputChecker(doctest.OutputChecker):
def check_output(self, want, got, optionflags):
"""
@@ -396,6 +409,39 @@ def assertFieldOutput(self, fieldclass, valid, invalid, field_args=None,
self.assertTrue(isinstance(fieldclass(*field_args, **field_kwargs),
fieldclass))
+ def assertHTMLEqual(self, html1, html2, msg=None):
+ """
+ Asserts that two html snippets are semantically the same,
+ e.g. whitespace in most cases is ignored, attribute ordering is not
+ significant. The passed in arguments must be valid HTML.
+
+ """
+ dom1 = assert_and_parse_html(self, html1, msg,
+ u'First argument is not valid html:')
+ dom2 = assert_and_parse_html(self, html2, msg,
+ u'Second argument is not valid html:')
+
+ if dom1 != dom2:
+ standardMsg = '%s != %s' % (
+ safe_repr(dom1, True), safe_repr(dom2, True))
+ diff = ('\n' + '\n'.join(difflib.ndiff(
+ unicode(dom1).splitlines(),
+ unicode(dom2).splitlines())))
+ standardMsg = self._truncateMessage(standardMsg, diff)
+ self.fail(self._formatMessage(msg, standardMsg))
+
+ def assertHTMLNotEqual(self, html1, html2, msg=None):
+ """Asserts that two HTML snippets are not semantically equivalent."""
+ dom1 = assert_and_parse_html(self, html1, msg,
+ u'First argument is not valid html:')
+ dom2 = assert_and_parse_html(self, html2, msg,
+ u'Second argument is not valid html:')
+
+ if dom1 == dom2:
+ standardMsg = '%s == %s' % (
+ safe_repr(dom1, True), safe_repr(dom2, True))
+ self.fail(self._formatMessage(msg, standardMsg))
+
class TransactionTestCase(SimpleTestCase):
# The class we'll use for the test client self.client.
@@ -554,7 +600,7 @@ def assertRedirects(self, response, expected_url, status_code=302,
(url, expected_url))
def assertContains(self, response, text, count=None, status_code=200,
- msg_prefix=''):
+ msg_prefix='', html=False):
"""
Asserts that a response indicates that some content was retrieved
successfully, (i.e., the HTTP status code was as expected), and that
@@ -576,7 +622,13 @@ def assertContains(self, response, text, count=None, status_code=200,
msg_prefix + "Couldn't retrieve content: Response code was %d"
" (expected %d)" % (response.status_code, status_code))
text = smart_str(text, response._charset)
- real_count = response.content.count(text)
+ content = response.content
+ if html:
+ content = assert_and_parse_html(self, content, None,
+ u"Response's content is not valid html:")
+ text = assert_and_parse_html(self, text, None,
+ u"Second argument is not valid html:")
+ real_count = content.count(text)
if count is not None:
self.assertEqual(real_count, count,
msg_prefix + "Found %d instances of '%s' in response"
@@ -586,7 +638,7 @@ def assertContains(self, response, text, count=None, status_code=200,
msg_prefix + "Couldn't find '%s' in response" % text)
def assertNotContains(self, response, text, status_code=200,
- msg_prefix=''):
+ msg_prefix='', html=False):
"""
Asserts that a response indicates that some content was retrieved
successfully, (i.e., the HTTP status code was as expected), and that
@@ -606,7 +658,13 @@ def assertNotContains(self, response, text, status_code=200,
msg_prefix + "Couldn't retrieve content: Response code was %d"
" (expected %d)" % (response.status_code, status_code))
text = smart_str(text, response._charset)
- self.assertEqual(response.content.count(text), 0,
+ content = response.content
+ if html:
+ content = assert_and_parse_html(self, content, None,
+ u'Response\'s content is no valid html:')
+ text = assert_and_parse_html(self, text, None,
+ u'Second argument is no valid html:')
+ self.assertEqual(content.count(text), 0,
msg_prefix + "Response should not contain '%s'" % text)
def assertFormError(self, response, form, field, errors, msg_prefix=''):
View
94 django/utils/htmlparser.py
@@ -0,0 +1,94 @@
+import HTMLParser as _HTMLParser
+
+
+class HTMLParser(_HTMLParser.HTMLParser):
+ """
+ Patched version of stdlib's HTMLParser with patch from:
+ http://bugs.python.org/issue670664
+ """
+ def __init__(self):
+ _HTMLParser.HTMLParser.__init__(self)
+ self.cdata_tag = None
+
+ def set_cdata_mode(self, tag):
+ self.interesting = _HTMLParser.interesting_cdata
+ self.cdata_tag = tag.lower()
+
+ def clear_cdata_mode(self):
+ self.interesting = _HTMLParser.interesting_normal
+ self.cdata_tag = None
+
+ # Internal -- handle starttag, return end or -1 if not terminated
+ def parse_starttag(self, i):
+ self.__starttag_text = None
+ endpos = self.check_for_whole_start_tag(i)
+ if endpos < 0:
+ return endpos
+ rawdata = self.rawdata
+ self.__starttag_text = rawdata[i:endpos]
+
+ # Now parse the data between i+1 and j into a tag and attrs
+ attrs = []
+ match = _HTMLParser.tagfind.match(rawdata, i + 1)
+ assert match, 'unexpected call to parse_starttag()'
+ k = match.end()
+ self.lasttag = tag = rawdata[i + 1:k].lower()
+
+ while k < endpos:
+ m = _HTMLParser.attrfind.match(rawdata, k)
+ if not m:
+ break
+ attrname, rest, attrvalue = m.group(1, 2, 3)
+ if not rest:
+ attrvalue = None
+ elif attrvalue[:1] == '\'' == attrvalue[-1:] or \
+ attrvalue[:1] == '"' == attrvalue[-1:]:
+ attrvalue = attrvalue[1:-1]
+ attrvalue = self.unescape(attrvalue)
+ attrs.append((attrname.lower(), attrvalue))
+ k = m.end()
+
+ end = rawdata[k:endpos].strip()
+ if end not in (">", "/>"):
+ lineno, offset = self.getpos()
+ if "\n" in self.__starttag_text:
+ lineno = lineno + self.__starttag_text.count("\n")
+ offset = len(self.__starttag_text) \
+ - self.__starttag_text.rfind("\n")
+ else:
+ offset = offset + len(self.__starttag_text)
+ self.error("junk characters in start tag: %r"
+ % (rawdata[k:endpos][:20],))
+ if end.endswith('/>'):
+ # XHTML-style empty tag: <span attr="value" />
+ self.handle_startendtag(tag, attrs)
+ else:
+ self.handle_starttag(tag, attrs)
+ if tag in self.CDATA_CONTENT_ELEMENTS:
+ self.set_cdata_mode(tag) # <--------------------------- Changed
+ return endpos
+
+ # Internal -- parse endtag, return end or -1 if incomplete
+ def parse_endtag(self, i):
+ rawdata = self.rawdata
+ assert rawdata[i:i + 2] == "</", "unexpected call to parse_endtag"
+ match = _HTMLParser.endendtag.search(rawdata, i + 1) # >
+ if not match:
+ return -1
+ j = match.end()
+ match = _HTMLParser.endtagfind.match(rawdata, i) # </ + tag + >
+ if not match:
+ if self.cdata_tag is not None: # *** add ***
+ self.handle_data(rawdata[i:j]) # *** add ***
+ return j # *** add ***
+ self.error("bad end tag: %r" % (rawdata[i:j],))
+ # --- changed start ---------------------------------------------------
+ tag = match.group(1).strip()
+ if self.cdata_tag is not None:
+ if tag.lower() != self.cdata_tag:
+ self.handle_data(rawdata[i:j])
+ return j
+ # --- changed end -----------------------------------------------------
+ self.handle_endtag(tag.lower())
+ self.clear_cdata_mode()
+ return j
View
15 docs/releases/1.4.txt
@@ -475,6 +475,21 @@ Time zone support is enabled by default in new projects created with
:djadmin:`startproject`. If you want to use this feature in an existing
project, read the :ref:`migration guide <time-zones-migration-guide>`.
+HTML comparisons in tests
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The :class:`~django.test.testcase.TestCase` base class now has some helpers to
+compare HTML without tripping over irrelevant differences in whitespace,
+argument quoting and ordering, and closing of self-closing tags. HTML can
+either be compared directly with the new
+:meth:`~django.test.testcase.TestCase.assertHTMLEqual` and
+:meth:`~django.test.testcase.TestCase.assertHTMLNotEqual` assertions, or use
+the ``html=True`` flag with
+:meth:`~django.test.testcase.TestCase.assertContains` and
+:meth:`~django.test.testcase.TestCase.assertNotContains` to test if the test
+client's response contains a given HTML fragment. See the :ref:`assertion
+documentation<assertions>` for more information.
+
Minor features
~~~~~~~~~~~~~~
View
62 docs/topics/testing.txt
@@ -1542,17 +1542,33 @@ your test suite.
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='')
+.. method:: TestCase.assertContains(response, text, count=None, status_code=200, msg_prefix='', html=False)
Asserts that a ``Response`` instance produced the given ``status_code`` and
that ``text`` appears in the content of the response. If ``count`` is
provided, ``text`` must occur exactly ``count`` times in the response.
-.. method:: TestCase.assertNotContains(response, text, status_code=200, msg_prefix='')
+ .. versionadded:: 1.4
+
+ Set ``html`` to ``True`` to handle ``text`` as HTML. The comparison with
+ the response content will be based on HTML semantics instead of
+ character-by-character equality. Whitespace is ignored in most cases,
+ attribute ordering is not significant. See
+ :func:`~TestCase.assertHTMLEqual` for more details.
+
+.. method:: TestCase.assertNotContains(response, text, status_code=200, msg_prefix='', html=False)
Asserts that a ``Response`` instance produced the given ``status_code`` and
that ``text`` does not appears in the content of the response.
+ .. versionadded:: 1.4
+
+ Set ``html`` to ``True`` to handle ``text`` as HTML. The comparison with
+ the response content will be based on HTML semantics instead of
+ character-by-character equality. Whitespace is ignored in most cases,
+ attribute ordering is not significant. See
+ :func:`~TestCase.assertHTMLEqual` for more details.
+
.. method:: TestCase.assertFormError(response, form, field, errors, msg_prefix='')
Asserts that a field on a form raises the provided list of errors when
@@ -1656,6 +1672,48 @@ your test suite.
Person.objects.create(name="Aaron")
Person.objects.create(name="Daniel")
+.. method:: TestCase.assertHTMLEqual(html1, html2, msg=None)
+
+ .. versionadded:: 1.4
+
+ Asserts that the strings ``html1`` and ``html2`` are equal. The comparison
+ is based on HTML semantics. The comparison takes following things into
+ account:
+
+ * Whitespace before and after HTML tags is ignored
+ * All types of whitespace are considered equivalent
+ * All open tags are closed implicitly, i.e. when a surrounding tag is
+ closed or the HTML document ends
+ * Empty tags are equivalent to their self-closing version
+ * The ordering of attributes of an HTML element is not significant
+ * Attributes without an argument are equal to attributes that equal in
+ name and value (see the examples)
+
+ The following examples are valid tests and don't raise any
+ ``AssertionError``::
+
+ self.assertHTMLEqual('<p>Hello <b>world!</p>',
+ '''<p>
+ Hello <b>world! <b/>
+ </p>''')
+ self.assertHTMLEqual(
+ '<input type="checkbox" checked="checked" id="id_accept_terms" />',
+ '<input id="id_accept_terms" type='checkbox' checked>')
+
+ ``html1`` and ``html2`` must be valid HTML. An ``AssertionError`` will be
+ raised if one of them cannot be parsed.
+
+.. method:: TestCase.assertHTMLNotEqual(html1, html2, msg=None)
+
+ .. versionadded:: 1.4
+
+ Asserts that the strings ``html1`` and ``html2`` are *not* equal. The
+ comparison is based on HTML semantics. See
+ :func:`~TestCase.assertHTMLEqual` for details.
+
+ ``html1`` and ``html2`` must be valid HTML. An ``AssertionError`` will be
+ raised if one of them cannot be parsed.
+
.. _topics-testing-email:
View
8 tests/modeltests/generic_relations/tests.py
@@ -200,11 +200,11 @@ def test_gfk_subclasses(self):
def test_generic_inline_formsets(self):
GenericFormSet = generic_inlineformset_factory(TaggedItem, extra=1)
formset = GenericFormSet()
- self.assertEqual(u''.join(form.as_p() for form in formset.forms), u"""<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-tag">Tag:</label> <input id="id_generic_relations-taggeditem-content_type-object_id-0-tag" type="text" name="generic_relations-taggeditem-content_type-object_id-0-tag" maxlength="50" /></p>
+ self.assertHTMLEqual(u''.join(form.as_p() for form in formset.forms), u"""<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-tag">Tag:</label> <input id="id_generic_relations-taggeditem-content_type-object_id-0-tag" type="text" name="generic_relations-taggeditem-content_type-object_id-0-tag" maxlength="50" /></p>
<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-DELETE">Delete:</label> <input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-0-DELETE" id="id_generic_relations-taggeditem-content_type-object_id-0-DELETE" /><input type="hidden" name="generic_relations-taggeditem-content_type-object_id-0-id" id="id_generic_relations-taggeditem-content_type-object_id-0-id" /></p>""")
formset = GenericFormSet(instance=Animal())
- self.assertEqual(u''.join(form.as_p() for form in formset.forms), u"""<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-tag">Tag:</label> <input id="id_generic_relations-taggeditem-content_type-object_id-0-tag" type="text" name="generic_relations-taggeditem-content_type-object_id-0-tag" maxlength="50" /></p>
+ self.assertHTMLEqual(u''.join(form.as_p() for form in formset.forms), u"""<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-tag">Tag:</label> <input id="id_generic_relations-taggeditem-content_type-object_id-0-tag" type="text" name="generic_relations-taggeditem-content_type-object_id-0-tag" maxlength="50" /></p>
<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-DELETE">Delete:</label> <input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-0-DELETE" id="id_generic_relations-taggeditem-content_type-object_id-0-DELETE" /><input type="hidden" name="generic_relations-taggeditem-content_type-object_id-0-id" id="id_generic_relations-taggeditem-content_type-object_id-0-id" /></p>""")
platypus = Animal.objects.create(
@@ -216,13 +216,13 @@ def test_generic_inline_formsets(self):
tagged_item_id = TaggedItem.objects.get(
tag='shiny', object_id=platypus.id
).id
- self.assertEqual(u''.join(form.as_p() for form in formset.forms), u"""<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-tag">Tag:</label> <input id="id_generic_relations-taggeditem-content_type-object_id-0-tag" type="text" name="generic_relations-taggeditem-content_type-object_id-0-tag" value="shiny" maxlength="50" /></p>
+ self.assertHTMLEqual(u''.join(form.as_p() for form in formset.forms), u"""<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-tag">Tag:</label> <input id="id_generic_relations-taggeditem-content_type-object_id-0-tag" type="text" name="generic_relations-taggeditem-content_type-object_id-0-tag" value="shiny" maxlength="50" /></p>
<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-DELETE">Delete:</label> <input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-0-DELETE" id="id_generic_relations-taggeditem-content_type-object_id-0-DELETE" /><input type="hidden" name="generic_relations-taggeditem-content_type-object_id-0-id" value="%s" id="id_generic_relations-taggeditem-content_type-object_id-0-id" /></p><p><label for="id_generic_relations-taggeditem-content_type-object_id-1-tag">Tag:</label> <input id="id_generic_relations-taggeditem-content_type-object_id-1-tag" type="text" name="generic_relations-taggeditem-content_type-object_id-1-tag" maxlength="50" /></p>
<p><label for="id_generic_relations-taggeditem-content_type-object_id-1-DELETE">Delete:</label> <input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-1-DELETE" id="id_generic_relations-taggeditem-content_type-object_id-1-DELETE" /><input type="hidden" name="generic_relations-taggeditem-content_type-object_id-1-id" id="id_generic_relations-taggeditem-content_type-object_id-1-id" /></p>""" % tagged_item_id)
lion = Animal.objects.create(common_name="Lion", latin_name="Panthera leo")
formset = GenericFormSet(instance=lion, prefix='x')
- self.assertEqual(u''.join(form.as_p() for form in formset.forms), u"""<p><label for="id_x-0-tag">Tag:</label> <input id="id_x-0-tag" type="text" name="x-0-tag" maxlength="50" /></p>
+ self.assertHTMLEqual(u''.join(form.as_p() for form in formset.forms), u"""<p><label for="id_x-0-tag">Tag:</label> <input id="id_x-0-tag" type="text" name="x-0-tag" maxlength="50" /></p>
<p><label for="id_x-0-DELETE">Delete:</label> <input type="checkbox" name="x-0-DELETE" id="id_x-0-DELETE" /><input type="hidden" name="x-0-id" id="id_x-0-id" /></p>""")
def test_gfk_manager(self):
View
48 tests/modeltests/model_forms/tests.py
@@ -298,7 +298,7 @@ class SubclassMeta(SomeCategoryForm):
class Meta(SomeCategoryForm.Meta):
exclude = ['url']
- self.assertEqual(
+ self.assertHTMLEqual(
str(SubclassMeta()),
"""<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="20" /></td></tr>
<tr><th><label for="id_slug">Slug:</label></th><td><input id="id_slug" type="text" name="slug" maxlength="20" /></td></tr>
@@ -313,7 +313,7 @@ class Meta:
self.assertEqual(OrderFields.base_fields.keys(),
['url', 'name'])
- self.assertEqual(
+ self.assertHTMLEqual(
str(OrderFields()),
"""<tr><th><label for="id_url">The URL:</label></th><td><input id="id_url" type="text" name="url" maxlength="40" /></td></tr>
<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="20" /></td></tr>"""
@@ -344,15 +344,15 @@ class Meta:
class TestWidgets(TestCase):
def test_base_widgets(self):
frm = TestWidgetForm()
- self.assertEqual(
+ self.assertHTMLEqual(
str(frm['name']),
'<textarea id="id_name" rows="10" cols="40" name="name"></textarea>'
)
- self.assertEqual(
+ self.assertHTMLEqual(
str(frm['url']),
'<input id="id_url" type="text" class="url" name="url" maxlength="40" />'
)
- self.assertEqual(
+ self.assertHTMLEqual(
str(frm['slug']),
'<input id="id_slug" type="text" name="slug" maxlength="20" />'
)
@@ -563,25 +563,25 @@ class OldFormForXTests(TestCase):
def test_base_form(self):
self.assertEqual(Category.objects.count(), 0)
f = BaseCategoryForm()
- self.assertEqual(
+ self.assertHTMLEqual(
str(f),
"""<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="20" /></td></tr>
<tr><th><label for="id_slug">Slug:</label></th><td><input id="id_slug" type="text" name="slug" maxlength="20" /></td></tr>
<tr><th><label for="id_url">The URL:</label></th><td><input id="id_url" type="text" name="url" maxlength="40" /></td></tr>"""
)
- self.assertEqual(
+ self.assertHTMLEqual(
str(f.as_ul()),
"""<li><label for="id_name">Name:</label> <input id="id_name" type="text" name="name" maxlength="20" /></li>
<li><label for="id_slug">Slug:</label> <input id="id_slug" type="text" name="slug" maxlength="20" /></li>
<li><label for="id_url">The URL:</label> <input id="id_url" type="text" name="url" maxlength="40" /></li>"""
)
- self.assertEqual(
+ self.assertHTMLEqual(
str(f["name"]),
"""<input id="id_name" type="text" name="name" maxlength="20" />""")
def test_auto_id(self):
f = BaseCategoryForm(auto_id=False)
- self.assertEqual(
+ self.assertHTMLEqual(
str(f.as_ul()),
"""<li>Name: <input type="text" name="name" maxlength="20" /></li>
<li>Slug: <input type="text" name="slug" maxlength="20" /></li>
@@ -653,7 +653,7 @@ def test_with_data(self):
# ManyToManyFields are represented by a MultipleChoiceField, ForeignKeys and any
# fields with the 'choices' attribute are represented by a ChoiceField.
f = ArticleForm(auto_id=False)
- self.assertEqual(unicode(f), '''<tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr>
+ self.assertHTMLEqual(unicode(f), '''<tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr>
<tr><th>Slug:</th><td><input type="text" name="slug" maxlength="50" /></td></tr>
<tr><th>Pub date:</th><td><input type="text" name="pub_date" /></td></tr>
<tr><th>Writer:</th><td><select name="writer">
@@ -681,14 +681,14 @@ def test_with_data(self):
# a value of None. If a field isn't specified on a form, the object created
# from the form can't provide a value for that field!
f = PartialArticleForm(auto_id=False)
- self.assertEqual(unicode(f), '''<tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr>
+ self.assertHTMLEqual(unicode(f), '''<tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr>
<tr><th>Pub date:</th><td><input type="text" name="pub_date" /></td></tr>''')
# When the ModelForm is passed an instance, that instance's current values are
# inserted as 'initial' data in each Field.
w = Writer.objects.get(name='Mike Royko')
f = RoykoForm(auto_id=False, instance=w)
- self.assertEqual(unicode(f), '''<tr><th>Name:</th><td><input type="text" name="name" value="Mike Royko" maxlength="50" /><br /><span class="helptext">Use both first and last names.</span></td></tr>''')
+ self.assertHTMLEqual(unicode(f), '''<tr><th>Name:</th><td><input type="text" name="name" value="Mike Royko" maxlength="50" /><br /><span class="helptext">Use both first and last names.</span></td></tr>''')
art = Article(
headline='Test article',
@@ -701,7 +701,7 @@ def test_with_data(self):
art_id_1 = art.id
self.assertEqual(art_id_1 is not None, True)
f = TestArticleForm(auto_id=False, instance=art)
- self.assertEqual(f.as_ul(), '''<li>Headline: <input type="text" name="headline" value="Test article" maxlength="50" /></li>
+ self.assertHTMLEqual(f.as_ul(), '''<li>Headline: <input type="text" name="headline" value="Test article" maxlength="50" /></li>
<li>Slug: <input type="text" name="slug" value="test-article" maxlength="50" /></li>
<li>Pub date: <input type="text" name="pub_date" value="1988-01-04" /></li>
<li>Writer: <select name="writer">
@@ -741,7 +741,7 @@ def test_with_data(self):
'slug': 'new-headline',
'pub_date': u'1988-01-04'
}, auto_id=False, instance=art)
- self.assertEqual(f.as_ul(), '''<li>Headline: <input type="text" name="headline" value="New headline" maxlength="50" /></li>
+ self.assertHTMLEqual(f.as_ul(), '''<li>Headline: <input type="text" name="headline" value="New headline" maxlength="50" /></li>
<li>Slug: <input type="text" name="slug" value="new-headline" maxlength="50" /></li>
<li>Pub date: <input type="text" name="pub_date" value="1988-01-04" /></li>''')
self.assertEqual(f.is_valid(), True)
@@ -755,7 +755,7 @@ def test_with_data(self):
new_art.categories.add(Category.objects.get(name='Entertainment'))
self.assertEqual(map(lambda o: o.name, new_art.categories.all()), ["Entertainment"])
f = TestArticleForm(auto_id=False, instance=new_art)
- self.assertEqual(f.as_ul(), '''<li>Headline: <input type="text" name="headline" value="New headline" maxlength="50" /></li>
+ self.assertHTMLEqual(f.as_ul(), '''<li>Headline: <input type="text" name="headline" value="New headline" maxlength="50" /></li>
<li>Slug: <input type="text" name="slug" value="new-headline" maxlength="50" /></li>
<li>Pub date: <input type="text" name="pub_date" value="1988-01-04" /></li>
<li>Writer: <select name="writer">
@@ -783,7 +783,7 @@ def test_with_data(self):
'headline': 'Your headline here',
'categories': [str(c1.id), str(c2.id)]
})
- self.assertEqual(f.as_ul(), '''<li>Headline: <input type="text" name="headline" value="Your headline here" maxlength="50" /></li>
+ self.assertHTMLEqual(f.as_ul(), '''<li>Headline: <input type="text" name="headline" value="Your headline here" maxlength="50" /></li>
<li>Slug: <input type="text" name="slug" maxlength="50" /></li>
<li>Pub date: <input type="text" name="pub_date" /></li>
<li>Writer: <select name="writer">
@@ -877,7 +877,7 @@ def test_with_data(self):
# at runtime, based on the data in the database when the form is displayed, not
# the data in the database when the form is instantiated.
f = ArticleForm(auto_id=False)
- self.assertEqual(f.as_ul(), '''<li>Headline: <input type="text" name="headline" maxlength="50" /></li>
+ self.assertHTMLEqual(f.as_ul(), '''<li>Headline: <input type="text" name="headline" maxlength="50" /></li>
<li>Slug: <input type="text" name="slug" maxlength="50" /></li>
<li>Pub date: <input type="text" name="pub_date" /></li>
<li>Writer: <select name="writer">
@@ -902,7 +902,7 @@ def test_with_data(self):
self.assertEqual(c4.name, 'Fourth')
w_bernstein = Writer.objects.create(name='Carl Bernstein')
self.assertEqual(w_bernstein.name, 'Carl Bernstein')
- self.assertEqual(f.as_ul(), '''<li>Headline: <input type="text" name="headline" maxlength="50" /></li>
+ self.assertHTMLEqual(f.as_ul(), '''<li>Headline: <input type="text" name="headline" maxlength="50" /></li>
<li>Slug: <input type="text" name="slug" maxlength="50" /></li>
<li>Pub date: <input type="text" name="pub_date" /></li>
<li>Writer: <select name="writer">
@@ -1081,7 +1081,7 @@ def test_with_data(self):
bw2.delete()
form = WriterProfileForm()
- self.assertEqual(form.as_p(), '''<p><label for="id_writer">Writer:</label> <select name="writer" id="id_writer">
+ self.assertHTMLEqual(form.as_p(), '''<p><label for="id_writer">Writer:</label> <select name="writer" id="id_writer">
<option value="" selected="selected">---------</option>
<option value="%s">Bob Woodward</option>
<option value="%s">Carl Bernstein</option>
@@ -1099,7 +1099,7 @@ def test_with_data(self):
self.assertEqual(unicode(instance), 'Bob Woodward is 65')
form = WriterProfileForm(instance=instance)
- self.assertEqual(form.as_p(), '''<p><label for="id_writer">Writer:</label> <select name="writer" id="id_writer">
+ self.assertHTMLEqual(form.as_p(), '''<p><label for="id_writer">Writer:</label> <select name="writer" id="id_writer">
<option value="">---------</option>
<option value="%s" selected="selected">Bob Woodward</option>
<option value="%s">Carl Bernstein</option>
@@ -1374,7 +1374,7 @@ def test_media_on_modelform(self):
# Similar to a regular Form class you can define custom media to be used on
# the ModelForm.
f = ModelFormWithMedia()
- self.assertEqual(unicode(f.media), '''<link href="/some/form/css" type="text/css" media="all" rel="stylesheet" />
+ self.assertHTMLEqual(unicode(f.media), '''<link href="/some/form/css" type="text/css" media="all" rel="stylesheet" />
<script type="text/javascript" src="/some/form/javascript"></script>''')
f = CommaSeparatedIntegerForm({'field': '1,2,3'})
@@ -1443,7 +1443,7 @@ def test_foreignkeys_which_use_to_field(self):
(22, u'Pear')))
form = InventoryForm(instance=core)
- self.assertEqual(unicode(form['parent']), '''<select name="parent" id="id_parent">
+ self.assertHTMLEqual(unicode(form['parent']), '''<select name="parent" id="id_parent">
<option value="">---------</option>
<option value="86" selected="selected">Apple</option>
<option value="87">Core</option>
@@ -1464,7 +1464,7 @@ class Meta:
self.assertEqual(CategoryForm.base_fields.keys(),
['description', 'url'])
- self.assertEqual(unicode(CategoryForm()), '''<tr><th><label for="id_description">Description:</label></th><td><input type="text" name="description" id="id_description" /></td></tr>
+ self.assertHTMLEqual(unicode(CategoryForm()), '''<tr><th><label for="id_description">Description:</label></th><td><input type="text" name="description" id="id_description" /></td></tr>
<tr><th><label for="id_url">The URL:</label></th><td><input id="id_url" type="text" name="url" maxlength="40" /></td></tr>''')
# to_field_name should also work on ModelMultipleChoiceField ##################
@@ -1479,5 +1479,5 @@ class Meta:
def test_model_field_that_returns_none_to_exclude_itself_with_explicit_fields(self):
self.assertEqual(CustomFieldForExclusionForm.base_fields.keys(), ['name'])
- self.assertEqual(unicode(CustomFieldForExclusionForm()),
+ self.assertHTMLEqual(unicode(CustomFieldForExclusionForm()),
'''<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="10" /></td></tr>''')
View
84 tests/modeltests/model_formsets/tests.py
@@ -95,11 +95,11 @@ def test_simple_save(self):
formset = AuthorFormSet(queryset=qs)
self.assertEqual(len(formset.forms), 3)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_form-0-name">Name:</label> <input id="id_form-0-name" type="text" name="form-0-name" maxlength="100" /><input type="hidden" name="form-0-id" id="id_form-0-id" /></p>')
- self.assertEqual(formset.forms[1].as_p(),
+ self.assertHTMLEqual(formset.forms[1].as_p(),
'<p><label for="id_form-1-name">Name:</label> <input id="id_form-1-name" type="text" name="form-1-name" maxlength="100" /><input type="hidden" name="form-1-id" id="id_form-1-id" /></p>')
- self.assertEqual(formset.forms[2].as_p(),
+ self.assertHTMLEqual(formset.forms[2].as_p(),
'<p><label for="id_form-2-name">Name:</label> <input id="id_form-2-name" type="text" name="form-2-name" maxlength="100" /><input type="hidden" name="form-2-id" id="id_form-2-id" /></p>')
data = {
@@ -133,11 +133,11 @@ def test_simple_save(self):
formset = AuthorFormSet(queryset=qs)
self.assertEqual(len(formset.forms), 3)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_form-0-name">Name:</label> <input id="id_form-0-name" type="text" name="form-0-name" value="Arthur Rimbaud" maxlength="100" /><input type="hidden" name="form-0-id" value="%d" id="id_form-0-id" /></p>' % author2.id)
- self.assertEqual(formset.forms[1].as_p(),
+ self.assertHTMLEqual(formset.forms[1].as_p(),
'<p><label for="id_form-1-name">Name:</label> <input id="id_form-1-name" type="text" name="form-1-name" value="Charles Baudelaire" maxlength="100" /><input type="hidden" name="form-1-id" value="%d" id="id_form-1-id" /></p>' % author1.id)
- self.assertEqual(formset.forms[2].as_p(),
+ self.assertHTMLEqual(formset.forms[2].as_p(),
'<p><label for="id_form-2-name">Name:</label> <input id="id_form-2-name" type="text" name="form-2-name" maxlength="100" /><input type="hidden" name="form-2-id" id="id_form-2-id" /></p>')
data = {
@@ -171,16 +171,16 @@ def test_simple_save(self):
formset = AuthorFormSet(queryset=qs)
self.assertEqual(len(formset.forms), 4)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_form-0-name">Name:</label> <input id="id_form-0-name" type="text" name="form-0-name" value="Arthur Rimbaud" maxlength="100" /></p>\n'
'<p><label for="id_form-0-DELETE">Delete:</label> <input type="checkbox" name="form-0-DELETE" id="id_form-0-DELETE" /><input type="hidden" name="form-0-id" value="%d" id="id_form-0-id" /></p>' % author2.id)
- self.assertEqual(formset.forms[1].as_p(),
+ self.assertHTMLEqual(formset.forms[1].as_p(),
'<p><label for="id_form-1-name">Name:</label> <input id="id_form-1-name" type="text" name="form-1-name" value="Charles Baudelaire" maxlength="100" /></p>\n'
'<p><label for="id_form-1-DELETE">Delete:</label> <input type="checkbox" name="form-1-DELETE" id="id_form-1-DELETE" /><input type="hidden" name="form-1-id" value="%d" id="id_form-1-id" /></p>' % author1.id)
- self.assertEqual(formset.forms[2].as_p(),
+ self.assertHTMLEqual(formset.forms[2].as_p(),
'<p><label for="id_form-2-name">Name:</label> <input id="id_form-2-name" type="text" name="form-2-name" value="Paul Verlaine" maxlength="100" /></p>\n'
'<p><label for="id_form-2-DELETE">Delete:</label> <input type="checkbox" name="form-2-DELETE" id="id_form-2-DELETE" /><input type="hidden" name="form-2-id" value="%d" id="id_form-2-id" /></p>' % author3.id)
- self.assertEqual(formset.forms[3].as_p(),
+ self.assertHTMLEqual(formset.forms[3].as_p(),
'<p><label for="id_form-3-name">Name:</label> <input id="id_form-3-name" type="text" name="form-3-name" maxlength="100" /></p>\n'
'<p><label for="id_form-3-DELETE">Delete:</label> <input type="checkbox" name="form-3-DELETE" id="id_form-3-DELETE" /><input type="hidden" name="form-3-id" id="id_form-3-id" /></p>')
@@ -381,7 +381,7 @@ def test_model_inheritance(self):
BetterAuthorFormSet = modelformset_factory(BetterAuthor)
formset = BetterAuthorFormSet()
self.assertEqual(len(formset.forms), 1)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_form-0-name">Name:</label> <input id="id_form-0-name" type="text" name="form-0-name" maxlength="100" /></p>\n'
'<p><label for="id_form-0-write_speed">Write speed:</label> <input type="text" name="form-0-write_speed" id="id_form-0-write_speed" /><input type="hidden" name="form-0-author_ptr" id="id_form-0-author_ptr" /></p>')
@@ -404,10 +404,10 @@ def test_model_inheritance(self):
formset = BetterAuthorFormSet()
self.assertEqual(len(formset.forms), 2)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_form-0-name">Name:</label> <input id="id_form-0-name" type="text" name="form-0-name" value="Ernest Hemingway" maxlength="100" /></p>\n'
'<p><label for="id_form-0-write_speed">Write speed:</label> <input type="text" name="form-0-write_speed" value="10" id="id_form-0-write_speed" /><input type="hidden" name="form-0-author_ptr" value="%d" id="id_form-0-author_ptr" /></p>' % hemingway_id)
- self.assertEqual(formset.forms[1].as_p(),
+ self.assertHTMLEqual(formset.forms[1].as_p(),
'<p><label for="id_form-1-name">Name:</label> <input id="id_form-1-name" type="text" name="form-1-name" maxlength="100" /></p>\n'
'<p><label for="id_form-1-write_speed">Write speed:</label> <input type="text" name="form-1-write_speed" id="id_form-1-write_speed" /><input type="hidden" name="form-1-author_ptr" id="id_form-1-author_ptr" /></p>')
@@ -436,11 +436,11 @@ def test_inline_formsets(self):
formset = AuthorBooksFormSet(instance=author)
self.assertEqual(len(formset.forms), 3)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_book_set-0-title">Title:</label> <input id="id_book_set-0-title" type="text" name="book_set-0-title" maxlength="100" /><input type="hidden" name="book_set-0-author" value="%d" id="id_book_set-0-author" /><input type="hidden" name="book_set-0-id" id="id_book_set-0-id" /></p>' % author.id)
- self.assertEqual(formset.forms[1].as_p(),
+ self.assertHTMLEqual(formset.forms[1].as_p(),
'<p><label for="id_book_set-1-title">Title:</label> <input id="id_book_set-1-title" type="text" name="book_set-1-title" maxlength="100" /><input type="hidden" name="book_set-1-author" value="%d" id="id_book_set-1-author" /><input type="hidden" name="book_set-1-id" id="id_book_set-1-id" /></p>' % author.id)
- self.assertEqual(formset.forms[2].as_p(),
+ self.assertHTMLEqual(formset.forms[2].as_p(),
'<p><label for="id_book_set-2-title">Title:</label> <input id="id_book_set-2-title" type="text" name="book_set-2-title" maxlength="100" /><input type="hidden" name="book_set-2-author" value="%d" id="id_book_set-2-author" /><input type="hidden" name="book_set-2-id" id="id_book_set-2-id" /></p>' % author.id)
data = {
@@ -470,11 +470,11 @@ def test_inline_formsets(self):
formset = AuthorBooksFormSet(instance=author)
self.assertEqual(len(formset.forms), 3)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_book_set-0-title">Title:</label> <input id="id_book_set-0-title" type="text" name="book_set-0-title" value="Les Fleurs du Mal" maxlength="100" /><input type="hidden" name="book_set-0-author" value="%d" id="id_book_set-0-author" /><input type="hidden" name="book_set-0-id" value="%d" id="id_book_set-0-id" /></p>' % (author.id, book1.id))
- self.assertEqual(formset.forms[1].as_p(),
+ self.assertHTMLEqual(formset.forms[1].as_p(),
'<p><label for="id_book_set-1-title">Title:</label> <input id="id_book_set-1-title" type="text" name="book_set-1-title" maxlength="100" /><input type="hidden" name="book_set-1-author" value="%d" id="id_book_set-1-author" /><input type="hidden" name="book_set-1-id" id="id_book_set-1-id" /></p>' % author.id)
- self.assertEqual(formset.forms[2].as_p(),
+ self.assertHTMLEqual(formset.forms[2].as_p(),
'<p><label for="id_book_set-2-title">Title:</label> <input id="id_book_set-2-title" type="text" name="book_set-2-title" maxlength="100" /><input type="hidden" name="book_set-2-author" value="%d" id="id_book_set-2-author" /><input type="hidden" name="book_set-2-id" id="id_book_set-2-id" /></p>' % author.id)
data = {
@@ -534,9 +534,9 @@ def test_inline_formsets_save_as_new(self):
formset = AuthorBooksFormSet(prefix="test")
self.assertEqual(len(formset.forms), 2)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_test-0-title">Title:</label> <input id="id_test-0-title" type="text" name="test-0-title" maxlength="100" /><input type="hidden" name="test-0-author" id="id_test-0-author" /><input type="hidden" name="test-0-id" id="id_test-0-id" /></p>')
- self.assertEqual(formset.forms[1].as_p(),
+ self.assertHTMLEqual(formset.forms[1].as_p(),
'<p><label for="id_test-1-title">Title:</label> <input id="id_test-1-title" type="text" name="test-1-title" maxlength="100" /><input type="hidden" name="test-1-author" id="id_test-1-author" /><input type="hidden" name="test-1-id" id="id_test-1-id" /></p>')
def test_inline_formsets_with_custom_pk(self):
@@ -548,7 +548,7 @@ def test_inline_formsets_with_custom_pk(self):
formset = AuthorBooksFormSet2(instance=author)
self.assertEqual(len(formset.forms), 1)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_bookwithcustompk_set-0-my_pk">My pk:</label> <input type="text" name="bookwithcustompk_set-0-my_pk" id="id_bookwithcustompk_set-0-my_pk" /></p>\n'
'<p><label for="id_bookwithcustompk_set-0-title">Title:</label> <input id="id_bookwithcustompk_set-0-title" type="text" name="bookwithcustompk_set-0-title" maxlength="100" /><input type="hidden" name="bookwithcustompk_set-0-author" value="1" id="id_bookwithcustompk_set-0-author" /></p>')
@@ -580,7 +580,7 @@ def test_inline_formsets_with_multi_table_inheritance(self):
formset = AuthorBooksFormSet3(instance=author)
self.assertEqual(len(formset.forms), 1)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_alternatebook_set-0-title">Title:</label> <input id="id_alternatebook_set-0-title" type="text" name="alternatebook_set-0-title" maxlength="100" /></p>\n'
'<p><label for="id_alternatebook_set-0-notes">Notes:</label> <input id="id_alternatebook_set-0-notes" type="text" name="alternatebook_set-0-notes" maxlength="100" /><input type="hidden" name="alternatebook_set-0-author" value="1" id="id_alternatebook_set-0-author" /><input type="hidden" name="alternatebook_set-0-book_ptr" id="id_alternatebook_set-0-book_ptr" /></p>')
@@ -671,15 +671,15 @@ def save(self, commit=True):
custom_qs = Book.objects.order_by('-title')
formset = AuthorBooksFormSet(instance=author, queryset=custom_qs)
self.assertEqual(len(formset.forms), 5)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_book_set-0-title">Title:</label> <input id="id_book_set-0-title" type="text" name="book_set-0-title" value="Les Paradis Artificiels" maxlength="100" /><input type="hidden" name="book_set-0-author" value="1" id="id_book_set-0-author" /><input type="hidden" name="book_set-0-id" value="1" id="id_book_set-0-id" /></p>')
- self.assertEqual(formset.forms[1].as_p(),
+ self.assertHTMLEqual(formset.forms[1].as_p(),
'<p><label for="id_book_set-1-title">Title:</label> <input id="id_book_set-1-title" type="text" name="book_set-1-title" value="Les Fleurs du Mal" maxlength="100" /><input type="hidden" name="book_set-1-author" value="1" id="id_book_set-1-author" /><input type="hidden" name="book_set-1-id" value="2" id="id_book_set-1-id" /></p>')
- self.assertEqual(formset.forms[2].as_p(),
+ self.assertHTMLEqual(formset.forms[2].as_p(),
'<p><label for="id_book_set-2-title">Title:</label> <input id="id_book_set-2-title" type="text" name="book_set-2-title" value="Flowers of Evil" maxlength="100" /><input type="hidden" name="book_set-2-author" value="1" id="id_book_set-2-author" /><input type="hidden" name="book_set-2-id" value="3" id="id_book_set-2-id" /></p>')
- self.assertEqual(formset.forms[3].as_p(),
+ self.assertHTMLEqual(formset.forms[3].as_p(),
'<p><label for="id_book_set-3-title">Title:</label> <input id="id_book_set-3-title" type="text" name="book_set-3-title" maxlength="100" /><input type="hidden" name="book_set-3-author" value="1" id="id_book_set-3-author" /><input type="hidden" name="book_set-3-id" id="id_book_set-3-id" /></p>')
- self.assertEqual(formset.forms[4].as_p(),
+ self.assertHTMLEqual(formset.forms[4].as_p(),
'<p><label for="id_book_set-4-title">Title:</label> <input id="id_book_set-4-title" type="text" name="book_set-4-title" maxlength="100" /><input type="hidden" name="book_set-4-author" value="1" id="id_book_set-4-author" /><input type="hidden" name="book_set-4-id" id="id_book_set-4-id" /></p>')
data = {
@@ -700,11 +700,11 @@ def save(self, commit=True):
custom_qs = Book.objects.filter(title__startswith='F')
formset = AuthorBooksFormSet(instance=author, queryset=custom_qs)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_book_set-0-title">Title:</label> <input id="id_book_set-0-title" type="text" name="book_set-0-title" value="Flowers of Evil" maxlength="100" /><input type="hidden" name="book_set-0-author" value="1" id="id_book_set-0-author" /><input type="hidden" name="book_set-0-id" value="3" id="id_book_set-0-id" /></p>')
- self.assertEqual(formset.forms[1].as_p(),
+ self.assertHTMLEqual(formset.forms[1].as_p(),
'<p><label for="id_book_set-1-title">Title:</label> <input id="id_book_set-1-title" type="text" name="book_set-1-title" maxlength="100" /><input type="hidden" name="book_set-1-author" value="1" id="id_book_set-1-author" /><input type="hidden" name="book_set-1-id" id="id_book_set-1-id" /></p>')
- self.assertEqual(formset.forms[2].as_p(),
+ self.assertHTMLEqual(formset.forms[2].as_p(),
'<p><label for="id_book_set-2-title">Title:</label> <input id="id_book_set-2-title" type="text" name="book_set-2-title" maxlength="100" /><input type="hidden" name="book_set-2-author" value="1" id="id_book_set-2-author" /><input type="hidden" name="book_set-2-id" id="id_book_set-2-id" /></p>')
data = {
@@ -725,7 +725,7 @@ def test_custom_pk(self):
CustomPrimaryKeyFormSet = modelformset_factory(CustomPrimaryKey)
formset = CustomPrimaryKeyFormSet()
self.assertEqual(len(formset.forms), 1)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_form-0-my_pk">My pk:</label> <input id="id_form-0-my_pk" type="text" name="form-0-my_pk" maxlength="10" /></p>\n'
'<p><label for="id_form-0-some_field">Some field:</label> <input id="id_form-0-some_field" type="text" name="form-0-some_field" maxlength="100" /></p>')
@@ -736,9 +736,9 @@ def test_custom_pk(self):
FormSet = inlineformset_factory(Place, Owner, extra=2, can_delete=False)
formset = FormSet(instance=place)
self.assertEqual(len(formset.forms), 2)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_owner_set-0-name">Name:</label> <input id="id_owner_set-0-name" type="text" name="owner_set-0-name" maxlength="100" /><input type="hidden" name="owner_set-0-place" value="1" id="id_owner_set-0-place" /><input type="hidden" name="owner_set-0-auto_id" id="id_owner_set-0-auto_id" /></p>')
- self.assertEqual(formset.forms[1].as_p(),
+ self.assertHTMLEqual(formset.forms[1].as_p(),
'<p><label for="id_owner_set-1-name">Name:</label> <input id="id_owner_set-1-name" type="text" name="owner_set-1-name" maxlength="100" /><input type="hidden" name="owner_set-1-place" value="1" id="id_owner_set-1-place" /><input type="hidden" name="owner_set-1-auto_id" id="id_owner_set-1-auto_id" /></p>')
data = {
@@ -760,12 +760,12 @@ def test_custom_pk(self):
formset = FormSet(instance=place)
self.assertEqual(len(formset.forms), 3)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_owner_set-0-name">Name:</label> <input id="id_owner_set-0-name" type="text" name="owner_set-0-name" value="Joe Perry" maxlength="100" /><input type="hidden" name="owner_set-0-place" value="1" id="id_owner_set-0-place" /><input type="hidden" name="owner_set-0-auto_id" value="%d" id="id_owner_set-0-auto_id" /></p>'
% owner1.auto_id)
- self.assertEqual(formset.forms[1].as_p(),
+ self.assertHTMLEqual(formset.forms[1].as_p(),
'<p><label for="id_owner_set-1-name">Name:</label> <input id="id_owner_set-1-name" type="text" name="owner_set-1-name" maxlength="100" /><input type="hidden" name="owner_set-1-place" value="1" id="id_owner_set-1-place" /><input type="hidden" name="owner_set-1-auto_id" id="id_owner_set-1-auto_id" /></p>')
- self.assertEqual(formset.forms[2].as_p(),
+ self.assertHTMLEqual(formset.forms[2].as_p(),
'<p><label for="id_owner_set-2-name">Name:</label> <input id="id_owner_set-2-name" type="text" name="owner_set-2-name" maxlength="100" /><input type="hidden" name="owner_set-2-place" value="1" id="id_owner_set-2-place" /><input type="hidden" name="owner_set-2-auto_id" id="id_owner_set-2-auto_id" /></p>')
data = {
@@ -791,7 +791,7 @@ def test_custom_pk(self):
FormSet = modelformset_factory(OwnerProfile)
formset = FormSet()
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_form-0-owner">Owner:</label> <select name="form-0-owner" id="id_form-0-owner">\n'
'<option value="" selected="selected">---------</option>\n'
'<option value="%d">Joe Perry at Giordanos</option>\n'
@@ -806,7 +806,7 @@ def test_custom_pk(self):
formset = FormSet(instance=owner1)
self.assertEqual(len(formset.forms), 1)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_ownerprofile-0-age">Age:</label> <input type="text" name="ownerprofile-0-age" id="id_ownerprofile-0-age" /><input type="hidden" name="ownerprofile-0-owner" value="%d" id="id_ownerprofile-0-owner" /></p>'
% owner1.auto_id)
@@ -827,7 +827,7 @@ def test_custom_pk(self):
formset = FormSet(instance=owner1)
self.assertEqual(len(formset.forms), 1)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_ownerprofile-0-age">Age:</label> <input type="text" name="ownerprofile-0-age" value="54" id="id_ownerprofile-0-age" /><input type="hidden" name="ownerprofile-0-owner" value="%d" id="id_ownerprofile-0-owner" /></p>'
% owner1.auto_id)
@@ -856,7 +856,7 @@ def test_unique_true_enforces_max_num_one(self):
formset = FormSet(instance=place)
self.assertEqual(len(formset.forms), 1)
- self.assertEqual(formset.forms[0].as_p(),
+ self.assertHTMLEqual(formset.forms[0].as_p(),
'<p><label for="id_location_set-0-lat">Lat:</label> <input id="id_location_set-0-lat" type="text" name="location_set-0-lat" maxlength="100" /></p>\n'
'<p><label for="id_location_set-0-lon">Lon:</label> <input id="id_location_set-0-lon" type="text" name="location_set-0-lon" maxlength="100" /><input type="hidden" name="location_set-0-place" value="1" id="id_location_set-0-place" /><input type="hidden" name="location_set-0-id" id="id_location_set-0-id" /></p>')
@@ -982,7 +982,7 @@ def test_callable_defaults(self):
now = form.fields['date_joined'].initial()
result = form.as_p()
result = re.sub(r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)?', '__DATETIME__', result)
- self.assertEqual(result,
+ self.assertHTMLEqual(result,
'<p><label for="id_membership_set-0-date_joined">Date joined:</label> <input type="text" name="membership_set-0-date_joined" value="__DATETIME__" id="id_membership_set-0-date_joined" /><input type="hidden" name="initial-membership_set-0-date_joined" value="__DATETIME__" id="initial-membership_set-0-id_membership_set-0-date_joined" /></p>\n'
'<p><label for="id_membership_set-0-karma">Karma:</label> <input type="text" name="membership_set-0-karma" id="id_membership_set-0-karma" /><input type="hidden" name="membership_set-0-person" value="%d" id="id_membership_set-0-person" /><input type="hidden" name="membership_set-0-id" id="id_membership_set-0-id" /></p>'
% person.id)
View
6 tests/regressiontests/admin_inlines/tests.py
@@ -34,7 +34,7 @@ def test_can_delete(self):
can_delete should be passed to inlineformset factory.
"""
response = self.client.get(self.change_url)
- inner_formset = response.context[-1]['inline_admin_formsets'][0].formset
+ inner_formset = response.context['inline_admin_formsets'][0].formset
expected = InnerInline.can_delete
actual = inner_formset.can_delete
self.assertEqual(expected, actual, 'can_delete must be equal')
@@ -134,7 +134,7 @@ def test_non_related_name_inline(self):
'id="id_-1-0-capo_famiglia" />')
self.assertContains(response,
'<input id="id_-1-0-name" type="text" class="vTextField" '
- 'name="-1-0-name" maxlength="100" />')
+ 'name="-1-0-name" maxlength="100" />', html=True)
self.assertContains(response,
'<input type="hidden" name="-2-0-id" id="id_-2-0-id" />')
@@ -143,7 +143,7 @@ def test_non_related_name_inline(self):
'id="id_-2-0-capo_famiglia" />')
self.assertContains(response,
'<input id="id_-2-0-name" type="text" class="vTextField" '
- 'name="-2-0-name" maxlength="100" />')
+ 'name="-2-0-name" maxlength="100" />', html=True)
class TestInlineMedia(TestCase):
urls = "regressiontests.admin_inlines.urls"
View
51 tests/regressiontests/admin_views/tests.py
@@ -1696,7 +1696,7 @@ def test_non_field_errors(self):
"_save": "Save",
}
response = self.client.post('/test_admin/admin/admin_views/fooddelivery/', data)
- self.assertContains(response, '<tr><td colspan="4"><ul class="errorlist"><li>Food delivery with this Driver and Restaurant already exists.</li></ul></td></tr>', 1)
+ self.assertContains(response, '<tr><td colspan="4"><ul class="errorlist"><li>Food delivery with this Driver and Restaurant already exists.</li></ul></td></tr>', 1, html=True)
data = {
"form-TOTAL_FORMS": "3",
@@ -1723,7 +1723,7 @@ def test_non_field_errors(self):
"_save": "Save",
}
response = self.client.post('/test_admin/admin/admin_views/fooddelivery/', data)
- self.assertContains(response, '<tr><td colspan="4"><ul class="errorlist"><li>Food delivery with this Driver and Restaurant already exists.</li></ul></td></tr>', 2)
+ self.assertContains(response, '<tr><td colspan="4"><ul class="errorlist"><li>Food delivery with this Driver and Restaurant already exists.</li></ul></td></tr>', 2, html=True)
def test_non_form_errors(self):
# test if non-form errors are handled; ticket #12716
@@ -1880,7 +1880,7 @@ def test_pk_hidden_fields(self):
response = self.client.get('/test_admin/admin/admin_views/story/')
self.assertContains(response, 'id="id_form-0-id"', 1) # Only one hidden field, in a separate place than the table.
self.assertContains(response, 'id="id_form-1-id"', 1)
- self.assertContains(response, '<div class="hiddenfields">\n<input type="hidden" name="form-0-id" value="%d" id="id_form-0-id" /><input type="hidden" name="form-1-id" value="%d" id="id_form-1-id" />\n</div>' % (story2.id, story1.id))
+ self.assertContains(response, '<div class="hiddenfields">\n<input type="hidden" name="form-0-id" value="%d" id="id_form-0-id" /><input type="hidden" name="form-1-id" value="%d" id="id_form-1-id" />\n</div>' % (story2.id, story1.id), html=True)
self.assertContains(response, '<td>%d</td>' % story1.id, 1)
self.assertContains(response, '<td>%d</td>' % story2.id, 1)
@@ -1894,7 +1894,7 @@ def test_pk_hidden_fields_with_list_display_links(self):
response = self.client.get('/test_admin/admin/admin_views/otherstory/')
self.assertContains(response, 'id="id_form-0-id"', 1) # Only one hidden field, in a separate place than the table.
self.assertContains(response, 'id="id_form-1-id"', 1)
- self.assertContains(response, '<div class="hiddenfields">\n<input type="hidden" name="form-0-id" value="%d" id="id_form-0-id" /><input type="hidden" name="form-1-id" value="%d" id="id_form-1-id" />\n</div>' % (story2.id, story1.id))
+ self.assertContains(response, '<div class="hiddenfields">\n<input type="hidden" name="form-0-id" value="%d" id="id_form-0-id" /><input type="hidden" name="form-1-id" value="%d" id="id_form-1-id" />\n</div>' % (story2.id, story1.id), html=True)
self.assertContains(response, '<th><a href="%d/">%d</a></th>' % (story1.id, story1.id), 1)
self.assertContains(response, '<th><a href="%d/">%d</a></th>' % (story2.id, story2.id), 1)
@@ -1923,7 +1923,7 @@ def test_with_fk_to_field(self):
from django.contrib.admin.views.main import TO_FIELD_VAR
response = self.client.get('/test_admin/admin/auth/user/?q=joe&%s=username' % TO_FIELD_VAR)
self.assertContains(response, "\n1 user\n")
- self.assertContains(response, '<input type="hidden" name="t" value="username"/>')
+ self.assertContains(response, '<input type="hidden" name="t" value="username"/>', html=True)
def test_exact_matches(self):
response = self.client.get('/test_admin/admin/admin_views/recommendation/?q=bar')
@@ -2114,8 +2114,8 @@ def test_model_admin_default_delete_action_protected(self):
response = self.client.post("/test_admin/admin/admin_views/question/", action_data)
self.assertContains(response, "would require deleting the following protected related objects")
- self.assertContains(response, '<li>Answer: <a href="/test_admin/admin/admin_views/answer/%s/">Because.</a></li>' % a1.pk)
- self.assertContains(response, '<li>Answer: <a href="/test_admin/admin/admin_views/answer/%s/">Yes.</a></li>' % a2.pk)
+ self.assertContains(response, '<li>Answer: <a href="/test_admin/admin/admin_views/answer/%s/">Because.</a></li>' % a1.pk, html=True)
+ self.assertContains(response, '<li>Answer: <a href="/test_admin/admin/admin_views/answer/%s/">Yes.</a></li>' % a2.pk, html=True)
def test_custom_function_mail_action(self):
"Tests a custom action defined in a function"
@@ -2159,13 +2159,12 @@ def test_actions_ordering(self):
Refs #15964.
"""
response = self.client.get('/test_admin/admin/admin_views/externalsubscriber/')
- self.assertTrue('''<label>Action: <select name="action">
+ self.assertContains(response, '''<label>Action: <select name="action">
<option value="" selected="selected">---------</option>
<option value="delete_selected">Delete selected external subscribers</option>
<option value="redirect_to">Redirect to (Awesome action)</option>
<option value="external_mail">External mail (Another awesome action)</option>
-</select>'''in response.content,
- )
+</select>''', html=True)
def test_model_without_action(self):
"Tests a ModelAdmin without any action"
@@ -2338,7 +2337,7 @@ def test_add_model_modeladmin_only_qs(self):
post_data, follow=True)
self.assertEqual(response.status_code, 200)
# Message should contain non-ugly model name. Instance representation is set by unicode() (ugly)
- self.assertContains(response, '<li class="info">The paper &quot;Paper_Deferred_author object&quot; was changed successfully.</li>')
+ self.assertContains(response, '<li class="info">The paper &quot;Paper_Deferred_author object&quot; was changed successfully.</li>', html=True)
# defer() is used in ModelAdmin.queryset()
cl = CoverLetter.objects.create(author=u"John Doe")
@@ -2353,7 +2352,7 @@ def test_add_model_modeladmin_only_qs(self):
post_data, follow=True)
self.assertEqual(response.status_code, 200)
# Message should contain non-ugly model name. Instance representation is set by model's __unicode__()
- self.assertContains(response, '<li class="info">The cover letter &quot;John Doe II&quot; was changed successfully.</li>')
+ self.assertContains(response, '<li class="info">The cover letter &quot;John Doe II&quot; was changed successfully.</li>', html=True)
class AdminInlineFileUploadTest(TestCase):
urls = "regressiontests.admin_views.urls"
@@ -2859,9 +2858,9 @@ def test_readonly_get(self):
self.assertContains(response, '<div class="form-row field-value">')
self.assertContains(response, '<div class="form-row">')
self.assertContains(response, '<p class="help">', 3)
- self.assertContains(response, '<p class="help">Some help text for the title (with unicode ŠĐĆŽćžšđ)</p>')
- self.assertContains(response, '<p class="help">Some help text for the content (with unicode ŠĐĆŽćžšđ)</p>')
- self.assertContains(response, '<p class="help">Some help text for the date (with unicode ŠĐĆŽćžšđ)</p>')
+ self.assertContains(response, '<p class="help">Some help text for the title (with unicode ŠĐĆŽćžšđ)</p>', html=True)
+ self.assertContains(response, '<p class="help">Some help text for the content (with unicode ŠĐĆŽćžšđ)</p>', html=True)
+ self.assertContains(response, '<p class="help">Some help text for the date (with unicode ŠĐĆŽćžšđ)</p>', html=True)
p = Post.objects.create(title="I worked on readonly_fields", content="Its good stuff")
response = self.client.get('/test_admin/admin/admin_views/post/%d/' % p.pk)
@@ -3099,32 +3098,32 @@ def test_tags(self):
response = self.client.get('/test_admin/admin/doc/tags/')
# The builtin tag group exists
- self.assertContains(response, "<h2>Built-in tags</h2>", count=2)
+ self.assertContains(response, "<h2>Built-in tags</h2>", count=2, html=True)
# A builtin tag exists in both the index and detail
- self.assertContains(response, '<h3 id="built_in-autoescape">autoescape</h3>')
- self.assertContains(response, '<li><a href="#built_in-autoescape">autoescape</a></li>')
+ self.assertContains(response, '<h3 id="built_in-autoescape">autoescape</h3>', html=True)
+ self.assertContains(response, '<li><a href="#built_in-autoescape">autoescape</a></li>', html=True)
# An app tag exists in both the index and detail
- self.assertContains(response, '<h3 id="flatpages-get_flatpages">get_flatpages</h3>')
- self.assertContains(response, '<li><a href="#flatpages-get_flatpages">get_flatpages</a></li>')
+ self.assertContains(response, '<h3 id="flatpages-get_flatpages">get_flatpages</h3>', html=True)
+ self.assertContains(response, '<li><a href="#flatpages-get_flatpages">get_flatpages</a></li>', html=True)
# The admin list tag group exists
- self.assertContains(response, "<h2>admin_list</h2>", count=2)
+ self.assertContains(response, "<h2>admin_list</h2>", count=2, html=True)
# An admin list tag exists in both the index and detail
- self.assertContains(response, '<h3 id="admin_list-admin_actions">admin_actions</h3>')
- self.assertContains(response, '<li><a href="#admin_list-admin_actions">admin_actions</a></li>')
+ self.assertContains(response, '<h3 id="admin_list-admin_actions">admin_actions</h3>', html=True)
+ self.assertContains(response, '<li><a href="#admin_list-admin_actions">admin_actions</a></li>', html=True)
def test_filters(self):
response = self.client.get('/test_admin/admin/doc/filters/')
# The builtin filter group exists
- self.assertContains(response, "<h2>Built-in filters</h2>", count=2)
+ self.assertContains(response, "<h2>Built-in filters</h2>", count=2, html=True)
# A builtin filter exists in both the index and detail
- self.assertContains(response, '<h3 id="built_in-add">add</h3>')
- self.assertContains(response, '<li><a href="#built_in-add">add</a></li>')
+ self.assertContains(response, '<h3 id="built_in-add">add</h3>', html=True)
+ self.assertContains(response, '<li><a href="#built_in-add">add</a></li>', html=True)
AdminDocsTest = unittest.skipUnless(docutils, "no docutils installed.")(AdminDocsTest)
View
38 tests/regressiontests/admin_widgets/tests.py
@@ -194,14 +194,14 @@ def test_url_params_from_lookup_dict_any_iterable(self):
class FilteredSelectMultipleWidgetTest(DjangoTestCase):
def test_render(self):
w = widgets.FilteredSelectMultiple('test', False)
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('test', 'test')),
'<select multiple="multiple" name="test" class="selectfilter">\n</select><script type="text/javascript">addEvent(window, "load", function(e) {SelectFilter.init("id_test", "test", 0, "%(ADMIN_MEDIA_PREFIX)s"); });</script>\n' % admin_media_prefix()
)
def test_stacked_render(self):
w = widgets.FilteredSelectMultiple('test', True)
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('test', 'test')),
'<select multiple="multiple" name="test" class="selectfilterstacked">\n</select><script type="text/javascript">addEvent(window, "load", function(e) {SelectFilter.init("id_test", "test", 1, "%(ADMIN_MEDIA_PREFIX)s"); });</script>\n' % admin_media_prefix()
)
@@ -213,13 +213,13 @@ def test_attrs(self):
Refs #12073.
"""
w = widgets.AdminDateWidget()
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('test', datetime(2007, 12, 1, 9, 30))),
'<input value="2007-12-01" type="text" class="vDateField" name="test" size="10" />',
)
# pass attrs to widget
w = widgets.AdminDateWidget(attrs={'size': 20, 'class': 'myDateField'})
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('test', datetime(2007, 12, 1, 9, 30))),
'<input value="2007-12-01" type="text" class="myDateField" name="test" size="20" />',
)
@@ -231,13 +231,13 @@ def test_attrs(self):
Refs #12073.
"""
w = widgets.AdminTimeWidget()
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('test', datetime(2007, 12, 1, 9, 30))),
'<input value="09:30:00" type="text" class="vTimeField" name="test" size="8" />',
)
# pass attrs to widget
w = widgets.AdminTimeWidget(attrs={'size': 20, 'class': 'myTimeField'})
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('test', datetime(2007, 12, 1, 9, 30))),
'<input value="09:30:00" type="text" class="myTimeField" name="test" size="20" />',
)
@@ -245,7 +245,7 @@ def test_attrs(self):
class AdminSplitDateTimeWidgetTest(DjangoTestCase):
def test_render(self):
w = widgets.AdminSplitDateTime()
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('test', datetime(2007, 12, 1, 9, 30))),
'<p class="datetime">Date: <input value="2007-12-01" type="text" class="vDateField" name="test_0" size="10" /><br />Time: <input value="09:30:00" type="text" class="vTimeField" name="test_1" size="8" /></p>',
)
@@ -256,7 +256,7 @@ def test_localization(self):
with self.settings(USE_L10N=True):
with translation.override('de-at'):
w.is_localized = True
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('test', datetime(2007, 12, 1, 9, 30))),
'<p class="datetime">Datum: <input value="01.12.2007" type="text" class="vDateField" name="test_0" size="10" /><br />Zeit: <input value="09:30:00" type="text" class="vTimeField" name="test_1" size="8" /></p>',
)
@@ -270,12 +270,12 @@ def test_render(self):
)
w = widgets.AdminFileWidget()
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('test', album.cover_art)),
'<p class="file-upload">Currently: <a href="%(STORAGE_URL)salbums/hybrid_theory.jpg">albums\hybrid_theory.jpg</a> <span class="clearable-file-input"><input type="checkbox" name="test-clear" id="test-clear_id" /> <label for="test-clear_id">Clear</label></span><br />Change: <input type="file" name="test" /></p>' % { 'STORAGE_URL': default_storage.url('') },
)
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('test', SimpleUploadedFile('test', 'content'))),
'<input type="file" name="test" />',
)
@@ -290,7 +290,7 @@ def test_render(self):
rel = models.Album._meta.get_field('band').rel
w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('test', band.pk, attrs={})),
'<input type="text" name="test" value="%(bandpk)s" class="vForeignKeyRawIdAdminField" /><a href="/widget_admin/admin_widgets/band/?t=id" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>&nbsp;<strong>Linkin Park</strong>' % dict(admin_media_prefix(), bandpk=band.pk)
)
@@ -305,7 +305,7 @@ def test_relations_to_non_primary_key(self):
)
rel = models.Inventory._meta.get_field('parent').rel
w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
- self.assertEqual(
+ self.assertHTMLEqual(
w.render('test', core.parent_id, attrs={}),
'<input type="text" name="test" value="86" class="vForeignKeyRawIdAdminField" /><a href="/widget_admin/admin_widgets/inventory/?t=barcode" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>&nbsp;<strong>Apple</strong>' % admin_media_prefix()
)
@@ -318,7 +318,7 @@ def test_fk_related_model_not_in_admin(self):
rel = models.Bee._meta.get_field('honeycomb').rel
w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('honeycomb_widget', big_honeycomb.pk, attrs={})),
'<input type="text" name="honeycomb_widget" value="%(hcombpk)s" />&nbsp;<strong>Honeycomb object</strong>' % {'hcombpk': big_honeycomb.pk}
)
@@ -331,7 +331,7 @@ def test_fk_to_self_model_not_in_admin(self):
rel = models.Individual._meta.get_field('parent').rel
w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('individual_widget', subject1.pk, attrs={})),
'<input type="text" name="individual_widget" value="%(subj1pk)s" />&nbsp;<strong>Individual object</strong>' % {'subj1pk': subject1.pk}
)
@@ -347,7 +347,7 @@ def test_proper_manager_for_label_lookup(self):
child_of_hidden = models.Inventory.objects.create(
barcode=94, name='Child of hidden', parent=hidden
)
- self.assertEqual(
+ self.assertHTMLEqual(
w.render('test', child_of_hidden.parent_id, attrs={}),
'<input type="text" name="test" value="93" class="vForeignKeyRawIdAdminField" /><a href="/widget_admin/admin_widgets/inventory/?t=barcode" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>&nbsp;<strong>Hidden</strong>' % admin_media_prefix()
)
@@ -363,12 +363,12 @@ def test_render(self):
rel = models.Band._meta.get_field('members').rel
w = widgets.ManyToManyRawIdWidget(rel, widget_admin_site)
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('test', [m1.pk, m2.pk], attrs={})),
'<input type="text" name="test" value="%(m1pk)s,%(m2pk)s" class="vManyToManyRawIdAdminField" /><a href="/widget_admin/admin_widgets/member/" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="/static/admin/img/selector-search.gif" width="16" height="16" alt="Lookup" /></a>' % dict(admin_media_prefix(), m1pk=m1.pk, m2pk=m2.pk)
)
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('test', [m1.pk])),
'<input type="text" name="test" value="%(m1pk)s" class="vManyToManyRawIdAdminField" /><a href="/widget_admin/admin_widgets/member/" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>' % dict(admin_media_prefix(), m1pk=m1.pk)
)
@@ -391,12 +391,12 @@ def test_m2m_related_model_not_in_admin(self):
rel = models.Advisor._meta.get_field('companies').rel
w = widgets.ManyToManyRawIdWidget(rel, widget_admin_site)
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('company_widget1', [c1.pk, c2.pk], attrs={})),
'<input type="text" name="company_widget1" value="%(c1pk)s,%(c2pk)s" />' % {'c1pk': c1.pk, 'c2pk': c2.pk}
)
- self.assertEqual(
+ self.assertHTMLEqual(
conditional_escape(w.render('company_widget2', [c1.pk])),
'<input type="text" name="company_widget2" value="%(c1pk)s" />' % {'c1pk': c1.pk}
)
View
11 tests/regressiontests/forms/tests/error_messages.py
@@ -5,7 +5,6 @@
from django.core.files.uploadedfile import SimpleUploadedFile
from django.forms import *
from django.test import TestCase
-from django.utils import unittest
from django.utils.safestring import mark_safe
from .fields import verify_exists_urls
@@ -19,7 +18,7 @@ def assertFormErrors(self, expected, the_callable, *args, **kwargs):
except ValidationError, e:
self.assertEqual(e.messages, expected)
-class FormsErrorMessagesTestCase(unittest.TestCase, AssertFormErrorsMixin):
+class FormsErrorMessagesTestCase(TestCase, AssertFormErrorsMixin):
def test_charfield(self):
e = {
'required': 'REQUIRED',
@@ -230,13 +229,13 @@ def as_divs(self):
# This form should print errors the default way.
form1 = TestForm({'first_name': 'John'})
- self.assertEqual(str(form1['last_name'].errors), '<ul class="errorlist"><li>This field is required.</li></ul>')
- self.assertEqual(str(form1.errors['__all__']), '<ul class="errorlist"><li>I like to be awkward.</li></ul>')
+ self.assertHTMLEqual(str(form1['last_name'].errors), '<ul class="errorlist"><li>This field is required.</li></ul>')
+ self.assertHTMLEqual(str(form1.errors['__all__']), '<ul class="errorlist"><li>I like to be awkward.</li></ul>')
# This one should wrap error groups in the customized way.
form2 = TestForm({'first_name': 'John'}, error_class=CustomErrorList)
- self.assertEqual(str(form2['last_name'].errors), '<div class="error"><p>This field is required.</p></div>')
- self.assertEqual(str(form2.errors['__all__']), '<div class="error"><p>I like to be awkward.</p></div>')
+ self.assertHTMLEqual(str(form2['last_name'].errors), '<div class="error"><p>This field is required.</p></div>')
+ self.assertHTMLEqual(str(form2.errors['__all__']), '<div class="error"><p>I like to be awkward.</p></div>')
class ModelChoiceFieldErrorMessagesTestCase(TestCase, AssertFormErrorsMixin):
View
35 tests/regressiontests/forms/tests/extra.py
@@ -8,7 +8,8 @@
from django.forms import *
from django.forms.extras import SelectDateWidget
from django.forms.util import ErrorList
-from django.utils import translation, unittest
+from django.test import TestCase
+from django.utils import translation
from django.utils.encoding import force_unicode, smart_unicode
from .error_messages import AssertFormErrorsMixin
@@ -20,7 +21,7 @@ class GetDate(Form):
class GetDateShowHiddenInitial(Form):
mydate = DateField(widget=SelectDateWidget, show_hidden_initial=True)
-class FormsExtraTestCase(unittest.TestCase, AssertFormErrorsMixin):
+class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
###############
# Extra stuff #
###############
@@ -28,7 +29,7 @@ class FormsExtraTestCase(unittest.TestCase, AssertFormErrorsMixin):
# The forms library comes with some extra, higher-level Field and Widget
def test_selectdate(self):
w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'))
- self.assertEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
+ self.assertHTMLEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
<option value="0">---</option>
<option value="1">January</option>
<option value="2">February</option>
@@ -43,6 +44,7 @@ def test_selectdate(self):
<option value="11">November</option>
<option value="12">December</option>
</select>
+
<select name="mydate_day" id="id_mydate_day">
<option value="0">---</option>
<option value="1">1</option>
@@ -77,6 +79,7 @@ def test_selectdate(self):
<option value="30">30</option>
<option value="31">31</option>
</select>
+
<select name="mydate_year" id="id_mydate_year">
<option value="0">---</option>
<option value="2007">2007</option>
@@ -90,9 +93,9 @@ def test_selectdate(self):
<option value="2015">2015</option>
<option value="2016">2016</option>
</select>""")
- self.assertEqual(w.render('mydate', None), w.render('mydate', ''))
+ self.assertHTMLEqual(w.render('mydate', None), w.render('mydate', ''))
- self.assertEqual(w.render('mydate', '2010-04-15'), """<select name="mydate_month" id="id_mydate_month">
+ self.assertHTMLEqual(w.render('mydate', '2010-04-15'), """<select name="mydate_month" id="id_mydate_month">
<option value="1">January</option>
<option value="2">February</option>
<option value="3">March</option>
@@ -153,10 +156,10 @@ def test_selectdate(self):
</select>""")
# Accepts a datetime or a string:
- self.assertEqual(w.render('mydate', datetime.date(2010, 4, 15)), w.render('mydate', '2010-04-15'))
+ self.assertHTMLEqual(w.render('mydate', datetime.date(2010, 4, 15)), w.render('mydate', '2010-04-15'))
# Invalid dates still render the failed date:
- self.assertEqual(w.render('mydate', '2010-02-31'), """<select name="mydate_month" id="id_mydate_month">
+ self.assertHTMLEqual(w.render('mydate', '2010-02-31'), """<select name="mydate_month" id="id_mydate_month">
<option value="1">January</option>
<option value="2" selected="selected">February</option>
<option value="3">March</option>
@@ -218,7 +221,7 @@ def test_selectdate(self):
# Using a SelectDateWidget in a form:
w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'), required=False)
- self.assertEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
+ self.assertHTMLEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
<option value="0">---</option>
<option value="1">January</option>
<option value="2">February</option>
@@ -280,7 +283,7 @@ def test_selectdate(self):
<option value="2015">2015</option>
<option value="2016">2016</option>
</select>""")
- self.assertEqual(w.render('mydate', '2010-04-15'), """<select name="mydate_month" id="id_mydate_month">
+ self.assertHTMLEqual(w.render('mydate', '2010-04-15'), """<select name="mydate_month" id="id_mydate_month">
<option value="0">---</option>
<option value="1">January</option>
<option value="2">February</option>
@@ -351,7 +354,7 @@ def test_selectdate(self):
# we must be prepared to accept the input from the "as_hidden"
# rendering as well.
- self.assertEqual(a['mydate'].as_hidden(), '<input type="hidden" name="mydate" value="2008-4-1" id="id_mydate" />')
+ self.assertHTMLEqual(a['mydate'].as_hidden(), '<input type="hidden" name="mydate" value="2008-4-1" id="id_mydate" />')
b = GetDate({'mydate':'2008-4-1'})
self.assertTrue(b.is_valid())
@@ -392,7 +395,7 @@ def format_output(self, rendered_widgets):
return u'\n'.join(rendered_widgets)
w = ComplexMultiWidget()
- self.assertEqual(w.render('name', 'some text,JP,2007-04-25 06:24:00'), """<input type="text" name="name_0" value="some text" />
+ self.assertHTMLEqual(w.render('name', 'some text,JP,2007-04-25 06:24:00'), """<input type="text" name="name_0" value="some text" />
<select multiple="multiple" name="name_1">
<option value="J" selected="selected">John</option>
<option value="P" selected="selected">Paul</option>
@@ -426,7 +429,7 @@ class ComplexFieldForm(Form):
field1 = ComplexField(widget=w)
f = ComplexFieldForm()
- self.assertEqual(f.as_table(), """<tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" id="id_field1_0" />
+ self.assertHTMLEqual(f.as_table(), """<tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" id="id_field1_0" />
<select multiple="multiple" name="field1_1" id="id_field1_1">
<option value="J">John</option>
<option value="P">Paul</option>
@@ -436,7 +439,7 @@ class ComplexFieldForm(Form):
<input type="text" name="field1_2_0" id="id_field1_2_0" /><input type="text" name="field1_2_1" id="id_field1_2_1" /></td></tr>""")
f = ComplexFieldForm({'field1_0':'some text','field1_1':['J','P'], 'field1_2_0':'2007-04-25', 'field1_2_1':'06:24:00'})
- self.assertEqual(f.as_table(), """<tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" value="some text" id="id_field1_0" />
+ self.assertHTMLEqual(f.as_table(), """<tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" value="some text" id="id_field1_0" />
<select multiple="multiple" name="field1_1" id="id_field1_1">
<option value="J" selected="selected">John</option>
<option value="P" selected="selected">Paul</option>
@@ -595,7 +598,7 @@ class CommentForm(Form):
data = dict(email='invalid')
f = CommentForm(data, auto_id=False, error_class=DivErrorList)
- self.assertEqual(f.as_p(), """<p>Name: <input type="text" name="name" maxlength="50" /></p>
+ self.assertHTMLEqual(f.as_p(), """<p>Name: <input type="text" name="name" maxlength="50" /></p>
<div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div>
<p>Email: <input type="text" name="email" value="invalid" /></p>
<div class="errorlist"><div class="error">This field is required.</div></div>
@@ -617,7 +620,7 @@ class FormWithImage(Form):
self.assertTrue(FormWithImage().is_multipart())
-class FormsExtraL10NTestCase(unittest.TestCase):
+class FormsExtraL10NTestCase(TestCase):
def setUp(self):
super(FormsExtraL10NTestCase, self).setUp()
self.old_use_l10n = getattr(settings, 'USE_L10N', False)
@@ -633,7 +636,7 @@ def test_l10n(self):
w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'), required=False)
self.assertEqual(w.value_from_datadict({'date_year': '2010', 'date_month': '8', 'date_day': '13'}, {}, 'date'), '13-08-2010')
- self.assertEqual(w.render('date', '13-08-2010'), """<select name="date_day" id="id_date_day">
+ self.assertHTMLEqual(w.render('date', '13-08-2010'), """<select name="date_day" id="id_date_day">
<option value="0">---</option>
<option value="1">1</option>
<option value="2">2</option>
View
3  tests/regressiontests/forms/tests/fields.py
@@ -674,6 +674,7 @@ def test_urlfield_4(self):
self.assertEqual(u'', f.clean(''))
self.assertEqual(u'http://www.google.com/', f.clean('http://www.google.com'))
+ @verify_exists_urls(('http://example.com/',))
def test_urlfield_5(self):
f = URLField(min_length=15, max_length=20)
self.assertRaisesMessage(ValidationError, "[u'Ensure this value has at least 15 characters (it has 13).']", f.clean, 'http://f.com')
@@ -852,7 +853,7 @@ class HiddenNullBooleanForm(Form):
hidden_nullbool1 = NullBooleanField(widget=HiddenInput, initial=True)
hidden_nullbool2 = NullBooleanField(widget=HiddenInput, initial=False)
f = HiddenNullBooleanForm()
- 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))
+ self.assertHTMLEqual('<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))
def test_nullbooleanfield_3(self):
class HiddenNullBooleanForm(Form):
View
357 tests/regressiontests/forms/tests/forms.py
@@ -5,9 +5,9 @@
from django.forms import *
from django.http import QueryDict
from django.template import Template, Context
+from django.test import TestCase
from django.utils.datastructures import MultiValueDict, MergeDict
from django.utils.safestring import mark_safe
-from django.utils.unittest import TestCase
class Person(Form):
@@ -34,14 +34,14 @@ def test_form(self):
self.assertTrue(p.is_bound)
self.assertEqual(p.errors, {})
self.assertTrue(p.is_valid())
- self.assertEqual(p.errors.as_ul(), u'')
+ self.assertHTMLEqual(p.errors.as_ul(), u'')
self.assertEqual(p.errors.as_text(), u'')
self.assertEqual(p.cleaned_data["first_name"], u'John')
self.assertEqual(p.cleaned_data["last_name"], u'Lennon')
self.assertEqual(p.cleaned_data["birthday"], datetime.date(1940, 10, 9))
- self.assertEqual(str(p['first_name']), '<input type="text" name="first_name" value="John" id="id_first_name" />')
- self.assertEqual(str(p['last_name']), '<input type="text" name="last_name" value="Lennon" id="id_last_name" />')
- self.assertEqual(str(p['birthday']), '<input type="text" name="birthday" value="1940-10-9" id="id_birthday" />')
+ self.assertHTMLEqual(str(p['first_name']), '<input type="text" name="first_name" value="John" id="id_first_name" />')
+ self.assertHTMLEqual(str(p['last_name']), '<input type="text" name="last_name" value="Lennon" id="id_last_name" />')
+ self.assertHTMLEqual(str(p['birthday']), '<input type="text" name="birthday" value="1940-10-9" id="id_birthday" />')
try:
p['nonexistentfield']
self.fail('Attempts to access non-existent fields should fail.')
@@ -53,7 +53,7 @@ def test_form(self):
for boundfield in p:
form_output.append(str(boundfield))
- self.assertEqual('\n'.join(form_output), """<input type="text" name="first_name" value="John" id="id_first_name" />
+ self.assertHTMLEqual('\n'.join(form_output), """<input type="text" name="first_name" value="John" id="id_first_name" />
<input type="text" name="last_name" value="Lennon" id="id_last_name" />
<input type="text" name="birthday" value="1940-10-9" id="id_birthday" />""")
@@ -67,7 +67,7 @@ def test_form(self):
['Last name', u'Lennon'],
['Birthday', u'1940-10-9']
])
- self.assertEqual(str(p), """<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" value="John" id="id_first_name" /></td></tr>
+ self.assertHTMLEqual(str(p), """<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" value="John" id="id_first_name" /></td></tr>
<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" value="Lennon" id="id_last_name" /></td></tr>
<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></td></tr>""")
@@ -84,16 +84,16 @@ def test_empty_dict(self):
self.fail('Attempts to access cleaned_data when validation fails should fail.')
except AttributeError:
pass
- self.assertEqual(str(p), """<tr><th><label for="id_first_name">First name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="first_name" id="id_first_name" /></td></tr>
+ self.assertHTMLEqual(str(p), """<tr><th><label for="id_first_name">First name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="first_name" id="id_first_name" /></td></tr>
<tr><th><label for="id_last_name">Last name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="last_name" id="id_last_name" /></td></tr>
<tr><th><label for="id_birthday">Birthday:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="birthday" id="id_birthday" /></td></tr>""")
- self.assertEqual(p.as_table(), """<tr><th><label for="id_first_name">First name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="first_name" id="id_first_name" /></td></tr>
+ self.assertHTMLEqual(p.as_table(), """<tr><th><label for="id_first_name">First name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="first_name" id="id_first_name" /></td></tr>
<tr><th><label for="id_last_name">Last name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="last_name" id="id_last_name" /></td></tr>
<tr><th><label for="id_birthday">Birthday:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="birthday" id="id_birthday" /></td></tr>""")
- self.assertEqual(p.as_ul(), """<li><ul class="errorlist"><li>This field is required.</li></ul><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li>
+ self.assertHTMLEqual(p.as_ul(), """<li><ul class="errorlist"><li>This field is required.</li></ul><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li>
<li><ul class="errorlist"><li>This field is required.</li></ul><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li>
<li><ul class="errorlist"><li>This field is required.</li></ul><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></li>""")
- self.assertEqual(p.as_p(), """<ul class="errorlist"><li>This field is required.</li></ul>
+ self.assertHTMLEqual(p.as_p(), """<ul class="errorlist"><li>This field is required.</li></ul>
<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p>
<ul class="errorlist"><li>This field is required.</li></ul>
<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p>
@@ -113,31 +113,31 @@ def test_unbound_form(self):
self.fail('Attempts to access cleaned_data when validation fails should fail.')
except AttributeError:
pass
- self.assertEqual(str(p), """<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
+ self.assertHTMLEqual(str(p), """<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr>
<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" id="id_birthday" /></td></tr>""")
- self.assertEqual(p.as_table(), """<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
+ self.assertHTMLEqual(p.as_table(), """<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr>
<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" id="id_birthday" /></td></tr>""")
- self.assertEqual(p.as_ul(), """<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li>
+ self.assertHTMLEqual(p.as_ul(), """<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li>
<li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li>
<li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></li>""")
- self.assertEqual(p.as_p(), """<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p>
+ self.assertHTMLEqual(p.as_p(), """<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p>
<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p>
<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></p>""")
def test_unicode_values(self):
# Unicode values are handled properly.
p = Person({'first_name': u'John', 'last_name': u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111', 'birthday': '1940-10-9'})
- self.assertEqual(p.as_table(), u'<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" value="John" id="id_first_name" /></td></tr>\n<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></td></tr>\n<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></td></tr>')
- self.assertEqual(p.as_ul(), u'<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" value="John" id="id_first_name" /></li>\n<li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></li>\n<li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></li>')
- self.assertEqual(p.as_p(), u'<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" value="John" id="id_first_name" /></p>\n<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></p>\n<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></p>')
+ self.assertHTMLEqual(p.as_table(), u'<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" value="John" id="id_first_name" /></td></tr>\n<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></td></tr>\n<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></td></tr>')
+ self.assertHTMLEqual(p.as_ul(), u'<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" value="John" id="id_first_name" /></li>\n<li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></li>\n<li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></li>')
+ self.assertHTMLEqual(p.as_p(), u'<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" value="John" id="id_first_name" /></p>\n<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></p>\n<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></p>')
p = Person({'last_name': u'Lennon'})
self.assertEqual(p.errors['first_name'], [u'This field is required.'])
self.assertEqual(p.errors['birthday'], [u'This field is required.'])
self.assertFalse(p.is_valid())
- self.assertEqual(p.errors.as_ul(), u'<ul class="errorlist"><li>first_name<ul class="errorlist"><li>This field is required.</li></ul></li><li>birthday<ul class="errorlist"><li>This field is required.</li></ul></li></ul>')
+ self.assertHTMLEqual(p.errors.as_ul(), u'<ul class="errorlist"><li>first_name<ul class="errorlist"><li>This field is required.</li></ul></li><li>birthday<ul class="errorlist"><li>This field is required.</li></ul></li></ul>')
self.assertEqual(p.errors.as_text(), """* first_name
* This field is required.
* birthday
@@ -148,13 +148,13 @@ def test_unicode_values(self):
except AttributeError:
pass
self.assertEqual(p['first_name'].errors, [u'This field is required.'])
- self.assertEqual(p['first_name'].errors.as_ul(), u'<ul class="errorlist"><li>This field is required.</li></ul>')
+ self.assertHTMLEqual(p['first_name'].errors.as_ul(), u'<ul class="errorlist"><li>This field is required.</li></ul>')
self.assertEqual(p['first_name'].errors.as_text(), u'* This field is required.')
p = Person()
- self.assertEqual(str(p['first_name']), '<input type="text" name="first_name" id="id_first_name" />')
- self.assertEqual(str(p['last_name']), '<input type="text" name="last_name" id="id_last_name" />')
- self.assertEqual(str(p['birthday']), '<input type="text" name="birthday" id="id_birthday" />')
+ self.assertHTMLEqual(str(p['first_name']), '<input type="text" name="first_name" id="id_first_name" />')
+ self.assertHTMLEqual(str(p['last_name']), '<input type="text" name="last_name" id="id_last_name" />')
+ self.assertHTMLEqual(str(p['birthday']), '<input type="text" name="birthday" id="id_birthday" />')
def test_cleaned_data_only_fields(self):
# cleaned_data will always *only* contain a key for fields defined in the
@@ -205,13 +205,13 @@ def test_auto_id(self):
# into which the field's name will be inserted. It will also put a <label> around
# the human-readable labels for a field.
p = Person(auto_id='%s_id')
- self.assertEqual(p.as_table(), """<tr><th><label for="first_name_id">First name:</label></th><td><input type="text" name="first_name" id="first_name_id" /></td></tr>
+ self.assertHTMLEqual(p.as_table(), """<tr><th><label for="first_name_id">First name:</label></th><td><input type="text" name="first_name" id="first_name_id" /></td></tr>
<tr><th><label for="last_name_id">Last name:</label></th><td><input type="text" name="last_name" id="last_name_id" /></td></tr>
<tr><th><label for="birthday_id">Birthday:</label></th><td><input type="text" name="birthday" id="birthday_id" /></td></tr>""")
- self.assertEqual(p.as_ul(), """<li><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /></li>
+ self.assertHTMLEqual(p.as_ul(), """<li><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /></li>
<li><label for="last_name_id">Last name:</label> <input type="text" name="last_name" id="last_name_id" /></li>
<li><label for="birthday_id">Birthday:</label> <input type="text" name="birthday" id="birthday_id" /></li>""")
- self.assertEqual(p.as_p(), """<p><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /></p>
+ self.assertHTMLEqual(p.as_p(), """<p><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /></p>
<p><label for="last_name_id">Last name:</label> <input type="text" name="last_name" id="last_name_id" /></p>
<p><label for="birthday_id">Birthday:</label> <input type="text" name="birthday" id="birthday_id" /></p>""")
@@ -219,7 +219,7 @@ def test_auto_id_true(self):
# If auto_id is any True value whose str() does not contain '%s', the "id"
# attribute will be the name of the field.
p = Person(auto_id=True)
- self.assertEqual(p.as_ul(), """<li><label for="first_name">First name:</label> <input type="text" name="first_name" id="first_name" /></li>
+ self.assertHTMLEqual(p.as_ul(), """<li><label for="first_name">First name:</label> <input type="text" name="first_name" id="first_name" /></li>
<li><label for="last_name">Last name:</label> <input type="text" name="last_name" id="last_name" /></li>
<li><label for="birthday">Birthday:</label> <input type="text" name="birthday" id="birthday" /></li>""")
@@ -227,7 +227,7 @@ def test_auto_id_false(self):
# If auto_id is any False value, an "id" attribute won't be output unless it
# was manually entered.
p = Person(auto_id=False)
- self.assertEqual(p.as_ul(), """<li>First name: <input type="text" name="first_name" /></li>
+ self.assertHTMLEqual(p.as_ul(), """<li>First name: <input type="text" name="first_name" /></li>
<li>Last name: <input type="text" name="last_name" /></li>
<li>Birthday: <input type="text" name="birthday" /></li>""")
@@ -235,7 +235,7 @@ def test_id_on_field(self):
# In this example, auto_id is False, but the "id" attribute for the "first_name"
# field is given. Also note that field gets a <label>, while the others don't.
p = PersonNew(auto_id=False)
- self.assertEqual(p.as_ul(), """<li><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /></li>
+ self.assertHTMLEqual(p.as_ul(), """<li><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /></li>
<li>Last name: <input type="text" name="last_name" /></li>
<li>Birthday: <input type="text" name="birthday" /></li>""")
@@ -243,7 +243,7 @@ def test_auto_id_on_form_and_field(self):
# If the "id" attribute is specified in the Form and auto_id is True, the "id"
# attribute in the Form gets precedence.
p = PersonNew(auto_id=True)
- self.assertEqual(p.as_ul(), """<li><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /></li>
+ self.assertHTMLEqual(p.as_ul(), """<li><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /></li>
<li><label for="last_name">Last name:</label> <input type="text" name="last_name" id="last_name" /></li>
<li><label for="birthday">Birthday:</label> <input type="text" name="birthday" id="birthday" /></li>""")
@@ -253,26 +253,26 @@ class SignupForm(Form):
get_spam = BooleanField()
f = SignupForm(auto_id=False)
- self.assertEqual(str(f['email']), '<input type="text" name="email" />')
- self.assertEqual(str(f['get_spam']), '<input type="checkbox" name="get_spam" />')
+ self.assertHTMLEqual(str(f['email']), '<input type="text" name="email" />')
+ self.assertHTMLEqual(str(f['get_spam']), '<input type="checkbox" name="get_spam" />')
f = SignupForm({'email': 'test@example.com', 'get_spam': True}, auto_id=False)
- self.assertEqual(str(f['email']), '<input type="text" name="email" value="test@example.com" />')
- self.assertEqual(str(f['get_spam']), '<input checked="checked" type="checkbox" name="get_spam" />')
+ self.assertHTMLEqual(str(f['email']), '<input type="text" name="email" value="test@example.com" />')
+ self.assertHTMLEqual(str(f['get_spam']), '<input checked="checked" type="checkbox" name="get_spam" />')
# 'True' or 'true' should be rendered without a value attribute
f = SignupForm({'email': 'test@example.com', 'get_spam': 'True'}, auto_id=False)
- self.assertEqual(str(f['get_spam']), '<input checked="checked" type="checkbox" name="get_spam" />')
+ self.assertHTMLEqual(str(f['get_spam']), '<input checked="checked" type="checkbox" name="get_spam" />')
f = SignupForm({'email': 'test@example.com', 'get_spam': 'true'}, auto_id=False)
- self.assertEqual(str(f['get_spam']), '<input checked="checked" type="checkbox" name="get_spam" />')
+ self.assertHTMLEqual(str(f['get_spam']), '<input checked="checked" type="checkbox" name="get_spam" />')
# A value of 'False' or 'false' should be rendered unchecked
f = SignupForm({'email': 'test@example.com', 'get_spam': 'False'}, auto_id=False)
- self.assertEqual(str(f['get_spam']), '<input type="checkbox" name="get_spam" />')
+ self.assertHTMLEqual(str(f['get_spam']), '<input type="checkbox" name="get_spam" />')
f = SignupForm({'email': 'test@example.com', 'get_spam': 'false'}, auto_id=False)
- self.assertEqual(str(f['get_spam']), '<input type="checkbox" name="get_spam" />')
+ self.assertHTMLEqual(str(f['get_spam']), '<input type="checkbox" name="get_spam" />')
def test_widget_output(self):
# Any Field can have a Widget class passed to its constructor:
@@ -281,14 +281,14 @@ class ContactForm(Form):
message = CharField(widget=Textarea)
f = ContactForm(auto_id=False)
- self.assertEqual(str(f['subject']), '<input type="text" name="subject" />')
- self.assertEqual(str(f['message']), '<textarea rows="10" cols="40" name="message"></textarea>')
+ self.assertHTMLEqual(str(f['subject']), '<input type="text" name="subject" />')
+ self.assertHTMLEqual(str(f['message']), '<textarea name="message" rows="10" cols="40"></textarea>')
# as_textarea(), as_text() and as_hidden() are shortcuts for changing the output
# widget type:
- self.assertEqual(f['subject'].as_textarea(), u'<textarea rows="10" cols="40" name="subject"></textarea>')
- self.assertEqual(f['message'].as_text(), u'<input type="text" name="message" />')
- self.assertEqual(f['message'].as_hidden(), u'<input type="hidden" name="message" />')
+ self.assertHTMLEqual(f['subject'].as_textarea(), u'<textarea name="subject" rows="10" cols="40"></textarea>')
+ self.assertHTMLEqual(f['message'].as_text(), u'<input type="text" name="message" />')
+ self.assertHTMLEqual(f['message'].as_hidden(), u'<input type="hidden" name="message" />')