import sys import unittest try: from tools.lib.template_parser import ( TemplateParserError, is_django_block_tag, tokenize, validate, ) except ImportError: print("ERROR!!! You need to run this via tools/test-tools.") sys.exit(1) class ParserTest(unittest.TestCase): def _assert_validate_error( self, error: str, fn: str | None = None, text: str | None = None, template_format: str | None = None, ) -> None: with self.assertRaisesRegex(TemplateParserError, error): validate(fn=fn, text=text, template_format=template_format) def test_is_django_block_tag(self) -> None: self.assertTrue(is_django_block_tag("block")) self.assertFalse(is_django_block_tag("not a django tag")) def test_validate_vanilla_html(self) -> None: """ Verify that validate() does not raise errors for well-formed HTML. """ my_html = """
foo |
{{stream}}
{{/with}} """ validate(text=my_html, template_format="handlebars") def test_validate_handlebars_partial_block(self) -> None: my_html = """ {{#> generic_thing }}hello!
{{/generic_thing}} """ validate(text=my_html, template_format="handlebars") def test_validate_bad_handlebars_partial_block(self) -> None: my_html = """ {{#> generic_thing }}hello!
{{# generic_thing}} """ self._assert_validate_error( "Missing end tag for the token at row 4 13!", text=my_html, template_format="handlebars" ) def test_validate_comment(self) -> None: my_html = """ """ validate(text=my_html) def test_validate_django(self) -> None: my_html = """ {% include "some_other.html" %} {% if foo %}bar
{% endif %} """ validate(text=my_html, template_format="django") my_html = """ {% block "content" %} {% with className="class" %} {% include 'foobar' %} {% endwith %} {% endblock %} """ validate(text=my_html) def test_validate_no_start_tag(self) -> None: my_html = """ foo """ self._assert_validate_error("No start tag", text=my_html) def test_validate_mismatched_tag(self) -> None: my_html = """ foo """ self._assert_validate_error(r"Mismatched tags: \(b != i\)", text=my_html) def test_validate_bad_indentation(self) -> None: my_html = """foo
""" self._assert_validate_error("Indentation for start/end tags does not match.", text=my_html) def test_validate_state_depth(self) -> None: my_html = """ """ self._assert_validate_error("Missing end tag", text=my_html) def test_validate_incomplete_handlebars_tag_1(self) -> None: my_html = """ {{# foo """ self._assert_validate_error( '''Tag missing "}}" at line 2 col 13:"{{# foo "''', text=my_html, template_format="handlebars", ) def test_validate_incomplete_handlebars_tag_2(self) -> None: my_html = """ {{# foo } """ self._assert_validate_error( 'Tag missing "}}" at line 2 col 13:"{{# foo }\n"', text=my_html, template_format="handlebars", ) def test_validate_incomplete_django_tag_1(self) -> None: my_html = """ {% foo """ self._assert_validate_error( '''Tag missing "%}" at line 2 col 13:"{% foo "''', text=my_html, template_format="django", ) def test_validate_incomplete_django_tag_2(self) -> None: my_html = """ {% foo % """ self._assert_validate_error( 'Tag missing "%}" at line 2 col 13:"{% foo %\n"', text=my_html, template_format="django", ) def test_validate_incomplete_html_tag_1(self) -> None: my_html = """ " at line 2 col 13:" None: my_html = """ " at line 2 col 13:" None: my_html = """ < > """ self._assert_validate_error("Tag name missing", text=my_html) def test_code_blocks(self) -> None: # This is fine. my_html = """
x = 5
y = x + 1
"""
validate(text=my_html)
# This is also fine.
my_html = "process_widgets()
"
validate(text=my_html)
# This is illegal.
my_html = """
x =
5
"""
self._assert_validate_error("Code tag is split across two lines.", text=my_html)
def test_anchor_blocks(self) -> None:
# This is allowed, although strange.
my_html = """
Click here
for more info.
"""
validate(text=my_html)
# This is fine.
my_html = 'click here'
validate(text=my_html)
# Even this is fine.
my_html = """
@ZulipStatus on Twitter.
"""
validate(text=my_html)
def test_validate_jinja2_whitespace_markers_1(self) -> None:
my_html = """
{% if foo -%}
this is foo
{% endif %}
"""
validate(
text=my_html,
template_format="django",
)
def test_validate_jinja2_whitespace_markers_2(self) -> None:
my_html = """
{% if foo %}
this is foo
{%- endif %}
"""
validate(
text=my_html,
template_format="django",
)
def test_validate_jinja2_whitespace_markers_3(self) -> None:
my_html = """
{% if foo %}
this is foo
{% endif -%}
"""
validate(
text=my_html,
template_format="django",
)
def test_validate_jinja2_whitespace_markers_4(self) -> None:
my_html = """
{%- if foo %}
this is foo
{% endif %}
"""
validate(
text=my_html,
template_format="django",
)
def test_validate_mismatch_jinja2_whitespace_markers_1(self) -> None:
my_html = """
{% if foo %}
this is foo
{%- if bar %}
"""
self._assert_validate_error(
"Missing end tag",
text=my_html,
template_format="django",
)
def test_validate_jinja2_whitespace_type2_markers(self) -> None:
my_html = """
{%- if foo -%}
this is foo
{% endif %}
"""
validate(
text=my_html,
template_format="django",
)
def test_tokenize(self) -> None:
tag = ""
token = tokenize(tag)[0]
self.assertEqual(token.kind, "html_doctype")
tag = "bla"
token = tokenize(tag)[0]
self.assertEqual(token.kind, "html_start")
self.assertEqual(token.tag, "a")
tag = "