From 5ac2aa62c1247e059c566f2e3d9f7079b96e2942 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 27 Feb 2017 17:43:15 +0000 Subject: [PATCH] Add assertTagInHTML test helper This asserts that the given tag exists in the HTML content, respecting tag name and attributes but ignoring content. --- wagtail/tests/utils.py | 43 +++++++++++++++++++++++++ wagtail/wagtailcore/tests/test_tests.py | 23 ++++++++++++- 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/wagtail/tests/utils.py b/wagtail/tests/utils.py index da90f80547..b488b475f0 100644 --- a/wagtail/tests/utils.py +++ b/wagtail/tests/utils.py @@ -8,6 +8,7 @@ import django from django.contrib.auth import get_user_model from django.core.urlresolvers import reverse from django.test import TestCase +from django.test.testcases import assert_and_parse_html from django.utils import six from django.utils.text import slugify @@ -113,6 +114,48 @@ class WagtailTestUtils(object): finally: hooks._hooks[hook_name].remove((fn, order)) + def _tag_is_equal(self, tag1, tag2): + if not hasattr(tag1, 'name') or not hasattr(tag2, 'name'): + return False + if tag1.name != tag2.name: + return False + if len(tag1.attributes) != len(tag2.attributes): + return False + if tag1.attributes != tag2.attributes: + # attributes without a value is same as attribute with value that + # equals the attributes name: + # == + for i in range(len(tag1.attributes)): + attr, value = tag1.attributes[i] + other_attr, other_value = tag2.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 + return True + + def _count_tag_occurrences(self, needle, haystack): + count = 1 if self._tag_is_equal(needle, haystack) else 0 + + if hasattr(haystack, 'children'): + count += sum(self._count_tag_occurrences(needle, child) for child in haystack.children) + + return count + + def assertTagInHTML(self, needle, haystack, count=None, msg_prefix=''): + needle = assert_and_parse_html(self, needle, None, 'First argument is not valid HTML:') + haystack = assert_and_parse_html(self, haystack, None, 'Second argument is not valid HTML:') + real_count = self._count_tag_occurrences(needle, haystack) + if count is not None: + self.assertEqual( + real_count, count, + msg_prefix + "Found %d instances of '%s' in response (expected %d)" % (real_count, needle, count) + ) + else: + self.assertTrue(real_count != 0, msg_prefix + "Couldn't find '%s' in response" % needle) + class WagtailPageTests(WagtailTestUtils, TestCase): """ diff --git a/wagtail/wagtailcore/tests/test_tests.py b/wagtail/wagtailcore/tests/test_tests.py index d813789eab..a94ca13870 100644 --- a/wagtail/wagtailcore/tests/test_tests.py +++ b/wagtail/wagtailcore/tests/test_tests.py @@ -1,14 +1,35 @@ from __future__ import absolute_import, unicode_literals +from django.test import TestCase from django.utils import six from wagtail.tests.testapp.models import ( BusinessChild, BusinessIndex, BusinessNowherePage, BusinessSubIndex, EventIndex, EventPage, SimplePage, StreamPage) -from wagtail.tests.utils import WagtailPageTests +from wagtail.tests.utils import WagtailPageTests, WagtailTestUtils from wagtail.wagtailcore.models import PAGE_MODEL_CLASSES, Page, Site +class TestAssertTagInHTML(TestCase, WagtailTestUtils): + def test_assert_tag_in_html(self): + haystack = """""" + self.assertTagInHTML('
  • ', haystack) + self.assertTagInHTML('
  • ', haystack, count=2) + + with self.assertRaises(AssertionError): + self.assertTagInHTML('
    ', haystack) + with self.assertRaises(AssertionError): + self.assertTagInHTML('
  • ', haystack, count=2) + with self.assertRaises(AssertionError): + self.assertTagInHTML('
  • ', haystack) + with self.assertRaises(AssertionError): + self.assertTagInHTML('
  • ', haystack) + + class TestWagtailPageTests(WagtailPageTests): def setUp(self): super(TestWagtailPageTests, self).setUp()