From e26a7a8ef41f0d69951affb21655cdc2cf94a209 Mon Sep 17 00:00:00 2001 From: Jacob Walls Date: Sun, 20 Sep 2020 10:14:54 -0400 Subject: [PATCH] Fixed #27906 -- Fixed test tools counting of HTML matches for subsets of elements. Previously examples such as '' would not match in ''. --- django/test/html.py | 18 ++++++++++++++++++ tests/test_utils/tests.py | 21 ++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/django/test/html.py b/django/test/html.py index 36b44b0466..3b04217822 100644 --- a/django/test/html.py +++ b/django/test/html.py @@ -86,6 +86,7 @@ class Element: if self.children == element.children: return 1 i = 0 + elem_child_idx = 0 for child in self.children: # child is text content and element is also text content, then # make a simple "text" in "text" @@ -96,9 +97,26 @@ class Element: elif element in child: return 1 else: + # Look for element wholly within this child. i += child._count(element, count=count) if not count and i: return i + # Also look for a sequence of element's children among self's + # children. self.children == element.children is tested above, + # but will fail if self has additional children. Ex: '' + # is contained in ''. + if isinstance(element, RootElement) and element.children: + elem_child = element.children[elem_child_idx] + # Start or continue match, advance index. + if elem_child == child: + elem_child_idx += 1 + # Match found, reset index. + if elem_child_idx == len(element.children): + i += 1 + elem_child_idx = 0 + # No match, reset index. + else: + elem_child_idx = 0 return i def __contains__(self, element): diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py index 87e2f56979..51e3c0548a 100644 --- a/tests/test_utils/tests.py +++ b/tests/test_utils/tests.py @@ -768,11 +768,30 @@ class HTMLEqualTests(SimpleTestCase): dom2 = parse_html('

foo

bar

') self.assertEqual(dom2.count(dom1), 0) - # html with a root element contains the same html with no root element + # HTML with a root element contains the same HTML with no root element. dom1 = parse_html('

foo

bar

') dom2 = parse_html('

foo

bar

') self.assertEqual(dom2.count(dom1), 1) + # Target of search is a sequence of child elements and appears more + # than once. + dom2 = parse_html('

foo

bar

foo

bar

') + self.assertEqual(dom2.count(dom1), 2) + + # Searched HTML has additional children. + dom1 = parse_html('
') + dom2 = parse_html('') + self.assertEqual(dom2.count(dom1), 1) + + # No match found in children. + dom1 = parse_html('') + self.assertEqual(dom2.count(dom1), 0) + + # Target of search found among children and grandchildren. + dom1 = parse_html('') + dom2 = parse_html('') + self.assertEqual(dom2.count(dom1), 2) + def test_parsing_errors(self): with self.assertRaises(AssertionError): self.assertHTMLEqual('

', '')