#32507 closed Cleanup/optimization (fixed)
assertInHTML('<a>', '<a><b/></a>') fails when tag implicitly closed
Reported by: | Jacob Walls | Owned by: | Jacob Walls |
---|---|---|---|
Component: | Documentation | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Antoine Humbert | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description
If the needle ('<a>') is an open tag without children, and the haystack is a closed tag with children ('<a><b/></a>'), no match is found.
Spotted by Antoine Humbert in the patch for #31867.
Something like this appears to work:
diff --git a/django/test/html.py b/django/test/html.py index 486a0d358d..4443540a70 100644 --- a/django/test/html.py +++ b/django/test/html.py @@ -82,6 +82,9 @@ class Element: return 1 i = 0 elem_child_idx = 0 + # Begin search against a childless copy, e.g. '<a>' in '<a><b/></a>'. + if Element(self.name, self.attributes) == element: + i = 1 for child in self.children: # child is text content and element is also text content, then # make a simple "text" in "text"
But it breaks the fourth assertion here from the original commit 844a24bbb97af663ebf8dbeab4499acafe105943:
def test_contains_html(self): response = HttpResponse('''<body> This is a form: <form method="get"> <input type="text" name="Hello" /> </form></body>''') self.assertNotContains(response, "<input name='Hello' type='text'>") self.assertContains(response, '<form method="get">') self.assertContains(response, "<input name='Hello' type='text'>", html=True) self.assertNotContains(response, '<form method="get">', html=True)
I'm having trouble seeing why the fourth assertion is correct. I see from the docs for assertHTMLEqual that "All open tags are closed implicitly, e.g. when a surrounding tag is closed or the HTML document ends.", which is fine to insist on for equality, but for contains, I would expect the test case for this ticket to pass.
Or, if we decide not to support it, we should explain in the docs for assertInHTML
that an implicit closing tag is being added.
Change History (6)
comment:1 by , 4 years ago
comment:2 by , 4 years ago
The documentation for assertContains(), which is similar, refers the reader to assertHTMLEqual()
for more details. So maybe this can be addressed simply by adding that same wording to assertInHTML()
.
comment:3 by , 4 years ago
Component: | Testing framework → Documentation |
---|---|
Easy pickings: | set |
Triage Stage: | Unreviewed → Accepted |
Type: | Bug → Cleanup/optimization |
I agree with Chris. Adding "See assertHTMLEqual() for more details." should be enough.
This probably verges on new feature territory, because my suggested approach will be unexpected for someone who does pass a complete tag and expects '<a></a>' in '<a><b/></a>' to fail.
So, I suppose my proposal is to either:
assertInHTML
, orallow_additional_children=False
kwarg that can be set to True (orstrict=True
that can be set to False, etc.) to satisfy this use case.