1
0
mirror of https://github.com/django/django.git synced 2025-10-26 15:16:09 +00:00

Fixed #16921 -- Added assertHTMLEqual and assertHTMLNotEqual assertions, 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
This commit is contained in:
Carl Meyer
2012-01-31 20:36:11 +00:00
parent c82f1dcf95
commit 844a24bbb9
61 changed files with 1345 additions and 639 deletions

View File

@@ -1,5 +1,6 @@
from __future__ import with_statement
import difflib
import os
import re
import sys
@@ -29,12 +30,14 @@ from django.forms.fields import CharField
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 @@ class SimpleTestCase(ut2.TestCase):
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 @@ class TransactionTestCase(SimpleTestCase):
(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 @@ class TransactionTestCase(SimpleTestCase):
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 @@ class TransactionTestCase(SimpleTestCase):
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 @@ class TransactionTestCase(SimpleTestCase):
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=''):