zulip/tools/tests/test_template_parser.py

254 lines
7.3 KiB
Python
Raw Normal View History

from __future__ import absolute_import
from __future__ import print_function
from typing import Optional, Any
import sys
import unittest
try:
from tools.lib.template_parser import (
TemplateParserException,
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 __init__(self, *args, **kwargs):
# type: (*Any, **Any) -> None
# This method should be removed when we migrate to version 3 of Python
import six
if six.PY2:
self.assertRaisesRegex = self.assertRaisesRegexp # type: ignore
super(ParserTest, self).__init__(*args, **kwargs)
def _assert_validate_error(self, error, fn=None, text=None, check_indent=True):
# type: (str, Optional[str], Optional[str], bool) -> None
with self.assertRaisesRegex(TemplateParserException, error): # type: ignore # See https://github.com/python/typeshed/issues/372
validate(fn=fn, text=text, check_indent=check_indent)
def test_is_django_block_tag(self):
# type: () -> None
self.assertTrue(is_django_block_tag('block'))
self.assertFalse(is_django_block_tag('not a django tag'))
def test_validate_vanilla_html(self):
# type: () -> None
'''
Verify that validate() does not raise errors for
well-formed HTML.
'''
my_html = '''
<table>
<tr>
<td>foo</td>
</tr>
</table>'''
validate(text=my_html)
2016-08-08 16:26:33 +02:00
def test_validate_handlebars(self):
# type: () -> None
my_html = '''
{{#with stream}}
<p>{{stream}}</p>
{{/with}}
'''
validate(text=my_html)
def test_validate_comment(self):
# type: () -> None
my_html = '''
<!---
<h1>foo</h1>
-->'''
validate(text=my_html)
2016-08-08 16:30:07 +02:00
def test_validate_django(self):
# type: () -> None
my_html = '''
{% include "some_other.html" %}
{% if foo %}
<p>bar</p>
{% endif %}
'''
validate(text=my_html)
def test_validate_no_start_tag(self):
# type: () -> None
my_html = '''
foo</p>
'''
self._assert_validate_error('No start tag', text=my_html)
def test_validate_mismatched_tag(self):
# type: () -> None
my_html = '''
<b>foo</i>
'''
self._assert_validate_error('Mismatched tag.', text=my_html)
def test_validate_bad_indentation(self):
# type: () -> None
my_html = '''
<p>
foo
</p>
'''
self._assert_validate_error('Bad indentation.', text=my_html, check_indent=True)
def test_validate_state_depth(self):
# type: () -> None
my_html = '''
<b>
'''
self._assert_validate_error('Missing end tag', text=my_html)
def test_validate_incomplete_handlebars_tag_1(self):
# type: () -> None
my_html = '''
{{# foo
'''
self._assert_validate_error('''Tag missing "}}" at Line 2 Col 13:"{{# foo
"''', text=my_html)
def test_validate_incomplete_handlebars_tag_2(self):
# type: () -> None
my_html = '''
{{# foo }
'''
self._assert_validate_error('Tag missing "}}" at Line 2 Col 13:"{{# foo }\n"', text=my_html)
def test_validate_incomplete_django_tag_1(self):
# type: () -> None
my_html = '''
{% foo
'''
self._assert_validate_error('''Tag missing "%}" at Line 2 Col 13:"{% foo
"''', text=my_html)
def test_validate_incomplete_django_tag_2(self):
# type: () -> None
my_html = '''
{% foo %
'''
self._assert_validate_error('Tag missing "%}" at Line 2 Col 13:"{% foo %\n"', text=my_html)
def test_validate_incomplete_html_tag_1(self):
# type: () -> None
my_html = '''
<b
'''
self._assert_validate_error('''Tag missing ">" at Line 2 Col 13:"<b
"''', text=my_html)
def test_validate_incomplete_html_tag_2(self):
# type: () -> None
my_html = '''
<a href="
'''
my_html1 = '''
<a href=""
'''
self._assert_validate_error('''Tag missing ">" at Line 2 Col 13:"<a href=""
"''', text=my_html1)
self._assert_validate_error('''Unbalanced Quotes at Line 2 Col 13:"<a href="
"''', text=my_html)
def test_validate_empty_html_tag(self):
# type: () -> None
my_html = '''
< >
'''
self._assert_validate_error('Tag name missing', text=my_html)
def test_code_blocks(self):
# type: () -> None
# This is fine.
my_html = '''
<code>
x = 5
y = x + 1
</code>'''
validate(text=my_html)
# This is also fine.
my_html = "<code>process_widgets()</code>"
validate(text=my_html)
# This is illegal.
my_html = '''
<code>x =
5</code>
'''
self._assert_validate_error('Code tag is split across two lines.', text=my_html)
def test_anchor_blocks(self):
# type: () -> None
# This is allowed, although strange.
my_html = '''
<a hef="/some/url">
Click here
for more info.
</a>'''
validate(text=my_html)
# This is fine.
my_html = '<a href="/some/url">click here</a>'
validate(text=my_html)
# Even this is fine.
my_html = '''
<a class="twitter-timeline" href="https://twitter.com/ZulipStatus"
data-widget-id="443457763394334720"
data-screen-name="ZulipStatus"
>@ZulipStatus on Twitter</a>.
'''
validate(text=my_html)
def test_tokenize(self):
# type: () -> None
tag = '<meta whatever>bla'
token = tokenize(tag)[0]
self.assertEqual(token.kind, 'html_special')
tag = '<a>bla'
token = tokenize(tag)[0]
self.assertEqual(token.kind, 'html_start')
self.assertEqual(token.tag, 'a')
tag = '<br />bla'
token = tokenize(tag)[0]
self.assertEqual(token.kind, 'html_singleton')
self.assertEqual(token.tag, 'br')
tag = '</a>bla'
token = tokenize(tag)[0]
self.assertEqual(token.kind, 'html_end')
self.assertEqual(token.tag, 'a')
tag = '{{#with foo}}bla'
token = tokenize(tag)[0]
self.assertEqual(token.kind, 'handlebars_start')
self.assertEqual(token.tag, 'with')
tag = '{{/with}}bla'
token = tokenize(tag)[0]
self.assertEqual(token.kind, 'handlebars_end')
self.assertEqual(token.tag, 'with')
tag = '{% if foo %}bla'
token = tokenize(tag)[0]
self.assertEqual(token.kind, 'django_start')
self.assertEqual(token.tag, 'if')
tag = '{% endif %}bla'
token = tokenize(tag)[0]
self.assertEqual(token.kind, 'django_end')
self.assertEqual(token.tag, 'if')