1. Álvaro Justen - Turicas
  2. web2py-template

Commits

Álvaro Justen - Turicas  committed c3001fc

Almost all corner cases on {{ and }} are tested and passing; need better test names

  • Participants
  • Parent commits b247af2
  • Branches default

Comments (0)

Files changed (3)

File .hgignore

View file
+syntax: glob
+*.swp
+*.pyc

File new_template.py

View file
 # coding: utf-8
 
 quotes = ("'", '"')
+string_on_html = 'response.write("%s", escape=False)'
 
 def parse_line(line):
+    if not line:
+        return ''
     if line[0] == '=':
         return 'response.write(%s)' % line[1:]
     else:
             if not in_string:
                 last_quote = ''
         if character == '\n' and not in_string:
-            response.append(parse_line(''.join(line[:-1])))
+            parsed_line = parse_line(''.join(line[:-1]))
+            if parsed_line:
+                response.append(parsed_line)
             line = []
     if line:
-        response.append(parse_line(''.join(line)))
+        parsed_line = parse_line(''.join(line))
+        if parsed_line:
+            response.append(parsed_line)
 
     return response
 
     in_string = False
     last_quote = ''
     in_comment = False
+    dict_count = 0
+    counter_slash = False
 
     for character in template_code:
+
         if in_python_code and not in_string:
             if character == '\n' and in_comment:
                 in_comment = False
             elif character == '#' or in_comment:
                 in_comment = True
                 continue
+        
+        if not in_python_code and character != '{':
+            open_tag_count = 0
+        elif in_python_code and character != '}':
+            close_tag_count = 0
 
         line.append(character)
-        if character in quotes and (not last_quote or character == last_quote):
+
+        if character in quotes and not counter_slash and (not last_quote or character == last_quote):
             last_quote = character
             in_string = not in_string
             if not in_string:
                 last_quote = ''
         elif character == '{':
-            open_tag_count += 1
+            if in_python_code and open_tag_count == 0 and not in_string:
+                dict_count += 1
+                continue
+            if not in_string:
+                open_tag_count += 1
             if open_tag_count == 2 and not in_python_code and not in_string:
                 open_tag_count = 0
                 in_python_code = True
                 line = line[:-2]
                 if line:
-                    response.append('response.write("%s", escape=False)' % \
-                                    ''.join(line))
+                    response.append(string_on_html % ''.join(line))
                     line = []
-            if in_string:
-                open_tag_count -= 1
         elif character == '}':
-            close_tag_count += 1
+            if in_python_code and dict_count > 0 and not in_string:
+                dict_count -= 1
+                continue
+            if not in_string:
+                close_tag_count += 1
             if close_tag_count == 2 and in_python_code and not in_string:
                 in_python_code = False
                 close_tag_count = 0
                 python_code = ''.join(line[:-2]).strip()
                 response.extend(parse_python_code(python_code))
                 line = []
-            if in_string:
-                close_tag_count -= 1
+        if character == '\\':
+            counter_slash = True
+        else:
+            counter_slash = False
+
     if line:
-        response.append('response.write("%s", escape=False)' % ''.join(line))
+        if in_python_code:
+            response.extend(parse_python_code(''.join(line)))
+        else:
+            response.append(string_on_html % ''.join(line))
                         
     return '\n'.join(response)

File test_new_template.py

View file
 sys.argv = ['test']
 import unittest
 
+DEBUG = False
+
 class TestRender(unittest.TestCase):
     def do_it(self):
         parsed_template = parse_template(self.input_)
-        print self.input_
-        print '***'
-        print self.expected_output
-        print '***'
-        print parsed_template
+        if DEBUG:
+            print self.input_
+            print '***'
+            print self.expected_output
+            print '***'
+            print parsed_template
+            print '--------'
         self.assertEquals(self.expected_output, parsed_template)
-        print '--------'
 
 
-    def test_000_parse_a_plain_text_template_should_return_one_response_write(self):
+    def test_parse_plain_text_should_return_one_response_write_with_the_text(self):
         self.input_ = 'just plain text'
         self.expected_output = 'response.write("' + self.input_  + '", escape=False)'
         self.do_it()
 
-    def test_010_render_only_one_python_command_as_response_write(self):
+    def test_parse_plain_text_and_one_python_command_as_response_write_with_single_quote(self):
         self.input_ = "some plain text {{='hi'}}"
         self.expected_output = '''response.write("some plain text ", escape=False)
 response.write('hi')'''
         self.do_it()
 
 
-    def test_020_render_only_one_python_command_as_response_write2(self):
+    def test_parse_plain_text_and_one_python_command_as_response_write_with_double_quote(self):
         self.input_ = 'some plain text {{="hi"}}'
         self.expected_output = '''response.write("some plain text ", escape=False)
 response.write("hi")'''
         self.do_it()
 
 
-    def test_030_render_only_one_python_command_as_response_write3(self):
+    def test_parse_plain_text_and_one_python_command_in_the_middle_as_response_write_with_single_quote(self):
         self.input_ = 'some plain text {{="hi"}} bla bla bla'
         self.expected_output = '''response.write("some plain text ", escape=False)
 response.write("hi")
         self.do_it()
 
 
-    def test_170_do_not_render_comments(self):
+    def test_do_not_return_comments(self):
         self.input_ = """some plain text {{='hi' #}}
 ='hello'}}"""
         self.expected_output = """response.write("some plain text ", escape=False)
 response.write('hello')"""
         self.do_it()
 
-    def test_create_a_lot_of_dictionaries(self):
-        self.input_ = """A{{a={'a': 1}}}B{{=a['a']}}"""
-        self.expected_output = 'AB1'
+
+    def test_do_not_return_blank_lines_if_comments_on_the_beginning(self):
+        self.input_ = """some plain text {{='hi'
+#bla bla bla
+='hello'}}{{
+#some comment
+a = 2
+}}"""
+        self.expected_output = """response.write("some plain text ", escape=False)
+response.write('hi')
+response.write('hello')
+a = 2"""
         self.do_it()
 
-#test \
+
+    def test_create_a_lot_of_dictionaries(self):
+        self.input_ = """A{{a = {'a': 1}}}B{{=a['a']}}"""
+        self.expected_output = """response.write("A", escape=False)
+a = {'a': 1}
+response.write("B", escape=False)
+response.write(a['a'])"""
+        self.do_it()
+
+
+    def test_dict_symbols_on_HTML_with_space_in_the_midlle(self):
+        self.input_ = '{ { bla bla bla } }'
+        self.expected_output = 'response.write("{ { bla bla bla } }", escape=False)'
+        self.do_it()
+
+
+    def test_dict_symbols_on_HTML_with_other_character_in_the_midlle(self):
+        self.input_ = '{a{ bla bla bla }a}'
+        self.expected_output = 'response.write("{a{ bla bla bla }a}", escape=False)'
+        self.do_it()
+
+
+    def test_dict_symbols_on_HTML_with_comment_symbol_in_the_midlle(self):
+        self.input_ = '{#{ bla bla bla }#}'
+        self.expected_output = 'response.write("{#{ bla bla bla }#}", escape=False)'
+        self.do_it()
+
+
+    def test_dict_symbols_on_HTML_with_blank_line_in_the_midlle(self):
+        self.input_ = '''{
+{ bla bla bla }
+}'''
+        self.expected_output = '''response.write("{
+{ bla bla bla }
+}", escape=False)'''
+        self.do_it()
+
+
+    def test_create_wrong_python_code_with_dictionary_symbol(self):
+        self.input_ = """A{{ a = {} } }}B"""
+        self.expected_output = """response.write("A", escape=False)
+a = {} }
+response.write("B", escape=False)"""
+        self.do_it()
+
+
+    def test_create_a_string_with_spaces(self):
+        self.input_ = """A{{a = '''   
+bla bla bla'''
+}}B"""
+        self.expected_output = """response.write("A", escape=False)
+a = '''   
+bla bla bla'''
+response.write("B", escape=False)"""
+        self.do_it()
+
+
+    def test_create_a_lot_of_dictionaries_in_python_code(self):
+        self.input_ = 'A{{{{{}}}}}B'
+        self.expected_output = """response.write("A", escape=False)
+{{{}}}
+response.write("B", escape=False)"""
+        self.do_it()
+
+
+    def test_python_code_in_the_last_line_dont_need_to_close_brackets(self):
+        self.input_ = '''A{{
+a = 1
+b = 2'''
+        self.expected_output = """response.write("A", escape=False)
+a = 1
+b = 2"""
+        self.do_it()
+
+
+    def test_create_a_lot_of_dictionaries_in_python_code_with_unmatching_brackets(self):
+        self.input_ = 'A{{ {{{}} }}B{{=a}}'
+        self.expected_output = """response.write("A", escape=False)
+ {{{}} }}B{{=a}}"""
+        self.do_it()
+
+
+    def test_counterslash_on_python_strings(self):
+        self.input_ = '''{{
+a = 'some \\
+multiline \\
+string'
+}}'''
+        self.expected_output = """a = 'some \\
+multiline \\
+string'"""
+        self.do_it()
+
+
+    def test_counterslash_and_quote_on_python_strings(self):
+        self.input_ = """{{
+a = 'some \\' }}\\
+string'
+b = '\\\\\'}}'
+}}"""
+        self.expected_output = """a = 'some \\' }}\\
+string'
+b = '\\\\\'}}'"""
+        self.do_it()
+
 
 if __name__ == '__main__':
     if len(argv) == 1:
         import new_template
         parse_template = new_template.parse_template
+        if DEBUG:
+            print '********** Using new template engine'
     else:
         import template
         parse_template = template.parse
+        if DEBUG:
+            print '********** Using *old* template engine'
 
-    print parse_template
+
     unittest.main()