Skip to content

Commit 9e48d7b

Browse files
authored
Fix IDOM preloader trying to parse commented out HTML templates (#106)
* Fix IDOM preloader trying to parse commented out HTML templates * Fix windows tests with channels >=4.0.0
1 parent 6f49037 commit 9e48d7b

File tree

5 files changed

+51
-10
lines changed

5 files changed

+51
-10
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ Using the following categories, list your changes in this order:
3636
- Allow `use_mutation` to have `refetch=None`, as the docs suggest is possible.
3737
- `use_query` will now prefetch all fields to prevent `SynchronousOnlyOperation` exceptions.
3838
- `view_to_component`, `django_css`, and `django_js` type hints will now display like normal functions.
39+
- IDOM preloader no longer attempts to parse commented out IDOM components.
40+
- Tests are now fully functional on Windows
3941

4042
## [1.2.0] - 2022-09-19
4143

requirements/test-env.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
django
22
playwright
33
twisted
4+
channels[daphne]>=4.0.0

src/django_idom/utils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
_component_tag = r"(?P<tag>component)"
1919
_component_path = r"(?P<path>(\"[^\"'\s]+\")|('[^\"'\s]+'))"
2020
_component_kwargs = r"(?P<kwargs>(.*?|\s*?)*)"
21+
COMMENT_REGEX = re.compile(r"(<!--)(.|\s)*?(-->)")
2122
COMPONENT_REGEX = re.compile(
2223
r"{%\s*"
2324
+ _component_tag
@@ -112,7 +113,8 @@ def _get_components(self, templates: set[str]) -> set[str]:
112113
for template in templates:
113114
with contextlib.suppress(Exception):
114115
with open(template, "r", encoding="utf-8") as template_file:
115-
regex_iterable = COMPONENT_REGEX.finditer(template_file.read())
116+
clean_template = COMMENT_REGEX.sub("", template_file.read())
117+
regex_iterable = COMPONENT_REGEX.finditer(clean_template)
116118
component_paths = [
117119
match.group("path").replace('"', "").replace("'", "")
118120
for match in regex_iterable

tests/test_app/tests/test_components.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import asyncio
12
import os
23
import sys
3-
from unittest import SkipTest
44

55
from channels.testing import ChannelsLiveServerTestCase
66
from playwright.sync_api import TimeoutError, sync_playwright
@@ -13,13 +13,7 @@ class TestIdomCapabilities(ChannelsLiveServerTestCase):
1313
@classmethod
1414
def setUpClass(cls):
1515
if sys.platform == "win32":
16-
raise SkipTest("These tests are broken on Windows.")
17-
18-
# FIXME: The following lines will be needed once Django channels fixes Windows tests
19-
# See: https://github.com/django/channels/issues/1207
20-
21-
# import asyncio
22-
# asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
16+
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
2317

2418
# FIXME: This is required otherwise the tests will throw a `SynchronousOnlyOperation`
2519
# error when deleting the test datatabase. Potentially a Django bug.

tests/test_app/tests/test_regex.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from django.test import TestCase
22

3-
from django_idom.utils import COMPONENT_REGEX
3+
from django_idom.utils import COMMENT_REGEX, COMPONENT_REGEX
44

55

66
class RegexTests(TestCase):
@@ -41,3 +41,45 @@ def test_component_regex(self):
4141
r'{{ component "" }}',
4242
}:
4343
self.assertNotRegex(fake_component, COMPONENT_REGEX)
44+
45+
def test_comment_regex(self):
46+
for comment in {
47+
r"<!-- comment -->",
48+
r"""<!-- comment
49+
-->""",
50+
r"""<!--
51+
comment -->""",
52+
r"""<!--
53+
comment
54+
-->""",
55+
r"""<!--
56+
a comment
57+
another comments
58+
drink some cement
59+
-->""", # noqa: W291
60+
}:
61+
self.assertRegex(comment, COMMENT_REGEX)
62+
63+
for fake_comment in {
64+
r"<!-- a comment ",
65+
r"another comment -->",
66+
r"<! - - comment - - >",
67+
r'{% component "my.component" %}',
68+
}:
69+
self.assertNotRegex(fake_comment, COMMENT_REGEX)
70+
71+
for embedded_comment in {
72+
r'{% component "my.component" %} <!-- comment -->',
73+
r'<!-- comment --> {% component "my.component" %}',
74+
r'<!-- comment --> {% component "my.component" %} <!-- comment -->',
75+
r"""<!-- comment
76+
--> {% component "my.component" %}
77+
<!-- comment -->
78+
<!--
79+
comment -->""",
80+
}: # noqa: W291
81+
text = COMMENT_REGEX.sub("", embedded_comment)
82+
if text.strip() != '{% component "my.component" %}':
83+
raise self.failureException(
84+
f"Regex pattern {COMMENT_REGEX.pattern} failed to remove comment from {embedded_comment}"
85+
)

0 commit comments

Comments
 (0)