from django.template import Context from django.template.base import Template, Token, TokenType from pytest_django.asserts import assertHTMLEqual from django_components import Component, register, types from django_components.util.template_parser import parse_template from django_components.testing import djc_test from .testutils import setup_test_config setup_test_config({"autodiscover": False}) def token2tuple(token: Token): return ( token.token_type, token.contents, (token.position[0], token.position[1]), token.lineno, ) @djc_test class TestTemplateParser: def test_template_text(self): tokens = parse_template("Hello world") token_tuples = [token2tuple(token) for token in tokens] expected_tokens = [ (TokenType.TEXT, "Hello world", (0, 11), 1), ] assert token_tuples == expected_tokens def test_template_variable(self): tokens = parse_template("Hello {{ name }}") token_tuples = [token2tuple(token) for token in tokens] expected_tokens = [ (TokenType.TEXT, "Hello ", (0, 6), 1), (TokenType.VAR, "name", (6, 16), 1), ] assert token_tuples == expected_tokens # NOTE(Juro): IMO this should be a TemplateSyntaxError, but Django doesn't raise it def test_template_variable_unterminated(self): tokens = parse_template("Hello {{ name") token_tuples = [token2tuple(token) for token in tokens] expected_tokens = [ (TokenType.TEXT, "Hello {{ name", (0, 13), 1), ] assert token_tuples == expected_tokens def test_template_tag(self): tokens = parse_template("{% component 'my_comp' key=val %}") token_tuples = [token2tuple(token) for token in tokens] expected_tokens = [ (TokenType.BLOCK, "component 'my_comp' key=val", (0, 33), 1), ] assert token_tuples == expected_tokens # NOTE(Juro): IMO this should be a TemplateSyntaxError, but Django doesn't raise it def test_template_tag_unterminated(self): tokens = parse_template("{% if true") token_tuples = [token2tuple(token) for token in tokens] expected_tokens = [ (TokenType.TEXT, "{% if true", (0, 10), 1), ] assert token_tuples == expected_tokens def test_template_comment(self): tokens = parse_template("Hello{# this is a comment #}World") token_tuples = [token2tuple(token) for token in tokens] expected_tokens = [ (TokenType.TEXT, "Hello", (0, 5), 1), (TokenType.COMMENT, "this is a comment", (5, 28), 1), (TokenType.TEXT, "World", (28, 33), 1), ] assert token_tuples == expected_tokens # NOTE(Juro): IMO this should be a TemplateSyntaxError, but Django doesn't raise it def test_template_comment_unterminated(self): tokens = parse_template("{# comment") token_tuples = [token2tuple(token) for token in tokens] expected_tokens = [ (TokenType.TEXT, "{# comment", (0, 10), 1), ] assert token_tuples == expected_tokens def test_template_verbatim(self): tokens = parse_template( """{% verbatim %} {{ this_is_not_a_var }} {% this_is_not_a_tag %} {% endverbatim %}""" ) token_tuples = [token2tuple(token) for token in tokens] expected_tokens = [ (TokenType.BLOCK, "verbatim", (0, 14), 1), (TokenType.TEXT, "\n ", (14, 31), 1), (TokenType.TEXT, "{{ this_is_not_a_var }}", (31, 54), 2), (TokenType.TEXT, "\n ", (54, 71), 2), (TokenType.TEXT, "{% this_is_not_a_tag %}", (71, 94), 3), (TokenType.TEXT, "\n ", (94, 107), 3), (TokenType.BLOCK, "endverbatim", (107, 124), 4), ] assert token_tuples == expected_tokens def test_template_verbatim_with_name(self): tokens = parse_template( """{% verbatim myblock %} {{ this_is_not_a_var }} {% verbatim %} {% endverbatim %} {% endverbatim blockname %} {% endverbatim myblock %}""" ) token_tuples = [token2tuple(token) for token in tokens] expected_tokens = [ (TokenType.BLOCK, "verbatim myblock", (0, 22), 1), (TokenType.TEXT, "\n ", (22, 39), 1), (TokenType.TEXT, "{{ this_is_not_a_var }}", (39, 62), 2), (TokenType.TEXT, "\n ", (62, 79), 2), (TokenType.TEXT, "{% verbatim %}", (79, 93), 3), (TokenType.TEXT, "\n ", (93, 110), 3), (TokenType.TEXT, "{% endverbatim %}", (110, 127), 4), (TokenType.TEXT, "\n ", (127, 144), 4), (TokenType.TEXT, "{% endverbatim blockname %}", (144, 171), 5), (TokenType.TEXT, "\n ", (171, 184), 5), (TokenType.BLOCK, "endverbatim myblock", (184, 209), 6), ] assert token_tuples == expected_tokens def test_template_nested_tags(self): tokens = parse_template("""{% component 'test' "{% lorem var_a w %}" %}""") token_tuples = [token2tuple(token) for token in tokens] expected_tokens = [ (TokenType.BLOCK, "component 'test' \"{% lorem var_a w %}\"", (0, 44), 1), ] assert token_tuples == expected_tokens def test_brackets_and_percent_in_text(self): tokens = parse_template('{% component \'test\' \'"\' "{%}" bool_var="{% noop is_active %}" / %}') token_tuples = [token2tuple(token) for token in tokens] expected_tokens = [ (TokenType.BLOCK, 'component \'test\' \'"\' "{%}" bool_var="{% noop is_active %}" /', (0, 66), 1), ] assert token_tuples == expected_tokens def test_template_mixed(self): tokens = parse_template( """Hello {{ name }} {# greeting #} {% if show_greeting %}