Code

fixes to the new template parser
authorrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Fri, 2 Aug 2002 23:45:41 +0000 (23:45 +0000)
committerrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Fri, 2 Aug 2002 23:45:41 +0000 (23:45 +0000)
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@948 57a73879-2fb5-44c3-a270-3262357dd7e2

roundup/template_parser.py
test/test_template_parser.py [new file with mode: 0644]

index 0e967ae318b46a2ada86914ea3ef97e9ea3a65b8..ba6eb2c7bef00d173857a6eeed8104a7c461e39a 100644 (file)
@@ -17,20 +17,36 @@ class Require:
         self.current.append(data)
     def elseMode(self):
         self.current = self.fail
+    def __repr__(self):
+        return '<Require %r ok:%r fail:%r>'%(self.attributes, self.ok,
+            self.fail)
 
 class Display:
     ''' Encapsulates a parsed <display attributes>
     '''
     def __init__(self, attributes):
         self.attributes = attributes
+    def __repr__(self):
+        return '<Display %r>'%self.attributes
 
 class Property:
     ''' Encapsulates a parsed <property attributes>
     '''
     def __init__(self, attributes):
         self.attributes = attributes
+        self.current = self.structure = []
+    def __len__(self):
+        return len(self.current)
+    def __getitem__(self, n):
+        return self.current[n]
+    def __setitem__(self, n, data):
+        self.current[n] = data
+    def append(self, data):
+        self.current.append(data)
+    def __repr__(self):
+        return '<Property %r %r>'%(self.attributes, self.structure)
 
-class RoundupTemplateParser(htmllib.HTMLParser):
+class RoundupTemplate(htmllib.HTMLParser):
     ''' Parse Roundup's HTML template structure into a list of components:
 
         'string': this is just plain data to be displayed
@@ -68,7 +84,7 @@ class RoundupTemplateParser(htmllib.HTMLParser):
             self.unknown_starttag(tag, attributes)
 
     def unknown_endtag(self, tag):
-        if tag == 'require':
+        if tag in ('require','property'):
             self.current = self.stack.pop()
         else:
             self.append_data('</%s>'%tag)
@@ -83,7 +99,10 @@ class RoundupTemplateParser(htmllib.HTMLParser):
         self.current.append(Display(attributes))
 
     def do_property(self, attributes):
-        self.current.append(Property(attributes))
+        p = Property(attributes)
+        self.current.append(p)
+        self.stack.append(self.current)
+        self.current = p
 
     def do_require(self, attributes):
         r = Require(attributes)
@@ -94,30 +113,33 @@ class RoundupTemplateParser(htmllib.HTMLParser):
     def do_else(self, attributes):
         self.current.elseMode()
 
+    def __repr__(self):
+        return '<RoundupTemplate %r>'%self.structure
+
 def display(structure, indent=''):
     ''' Pretty-print the parsed structure for debugging
     '''
+    l = []
     for entry in structure:
         if isinstance(entry, type('')):
-            print "%s%r"%(indent, entry[:50])
+            l.append("%s%s"%(indent, entry))
         elif isinstance(entry, Require):
-            print '%sTEST: %r'%(indent, entry.attributes)
-            print '%sOK...'%indent
-            display(entry.ok, indent+' ')
+            l.append('%sTEST: %r\n'%(indent, entry.attributes))
+            l.append('%sOK...'%indent)
+            l.append(display(entry.ok, indent+' '))
             if entry.fail:
-                print '%sFAIL...'%indent
-                display(entry.fail, indent+' ')
+                l.append('%sFAIL...'%indent)
+                l.append(display(entry.fail, indent+' '))
         elif isinstance(entry, Display):
-            print '%sDISPLAY: %r'%(indent, entry.attributes)
+            l.append('%sDISPLAY: %r'%(indent, entry.attributes))
+        elif isinstance(entry, Property):
+            l.append('%sPROPERTY: %r'%(indent, entry.attributes))
+            l.append(display(entry.structure, indent+' '))
+    return ''.join(l)
 
 if __name__ == '__main__':
     import sys
-    parser = RoundupTemplateParser()
+    parser = RoundupTemplate()
     parser.feed(open(sys.argv[1], 'r').read())
-    display(parser.structure)
-
-#
-# $Log: not supported by cvs2svn $
-#
-# vim: set filetype=python ts=4 sw=4 et si
+    print display(parser.structure)
 
diff --git a/test/test_template_parser.py b/test/test_template_parser.py
new file mode 100644 (file)
index 0000000..90c79d8
--- /dev/null
@@ -0,0 +1,98 @@
+# $Id: test_template_parser.py,v 1.1 2002-08-02 23:45:41 richard Exp $
+
+import unittest
+from roundup import template_parser
+
+class TemplateParserTestCase(unittest.TestCase):
+   def testParser(self):
+        parser = template_parser.RoundupTemplate()
+        s = '''
+<table border=0 cellspacing=5 cellpadding=0>
+ <tr>
+  <td bgcolor="ffffea">
+   <property name="prop1">
+    <require permission="perm1">
+     <display call="field('prop1')">
+    <else>
+     <display call="plain('prop1')">
+    </require>
+   </property>
+  </td>
+ </tr>
+</table>
+
+<table border=0 cellspacing=5 cellpadding=0>
+ <property name="prop2">
+  <tr>
+   <td class="form-label">Prop2:</td>
+   <td class="form-text">
+    <require permission="perm2">
+     <display call="field('prop2')">
+    <else>
+     <display call="plain('prop2')">
+    </require>
+   </td>
+  </tr>
+ </property>
+</table>'''
+        parser.feed(s)
+        self.assertEqual(template_parser.display(parser.structure),
+'\n<table border="0" cellspacing="5" cellpadding="0">\n <tr>\n  <td bgcolor="ffffea">\n   PROPERTY: [(\'name\', \'prop1\')] \n     TEST: [(\'permission\', \'perm1\')]\n OK...  \n       DISPLAY: [(\'call\', "field(\'prop1\')")]  \n     FAIL...  \n       DISPLAY: [(\'call\', "plain(\'prop1\')")]  \n     \n   \n  </td>\n </tr>\n</table>\n\n<table border="0" cellspacing="5" cellpadding="0">\n PROPERTY: [(\'name\', \'prop2\')] \n  <tr>\n   <td class="form-label">Prop2:</td>\n   <td class="form-text">\n     TEST: [(\'permission\', \'perm2\')]\n OK...  \n       DISPLAY: [(\'call\', "field(\'prop2\')")]  \n     FAIL...  \n       DISPLAY: [(\'call\', "plain(\'prop2\')")]  \n     \n   </td>\n  </tr>\n \n</table>')
+
+def suite():
+   return unittest.makeSuite(TemplateParserTestCase, 'test')
+
+
+#
+# $Log: not supported by cvs2svn $
+# Revision 1.12  2002/07/14 06:05:50  richard
+#  . fixed the date module so that Date(". - 2d") works
+#
+# Revision 1.11  2002/02/21 23:34:52  richard
+# Oops, there's 24 hours in a day, and subtraction of intervals now works
+# properly.
+#
+# Revision 1.10  2002/02/21 23:11:45  richard
+#  . fixed some problems in date calculations (calendar.py doesn't handle over-
+#    and under-flow). Also, hour/minute/second intervals may now be more than
+#    99 each.
+#
+# Revision 1.9  2002/02/21 06:57:39  richard
+#  . Added popup help for classes using the classhelp html template function.
+#    - add <display call="classhelp('priority', 'id,name,description')">
+#      to an item page, and it generates a link to a popup window which displays
+#      the id, name and description for the priority class. The description
+#      field won't exist in most installations, but it will be added to the
+#      default templates.
+#
+# Revision 1.8  2002/01/16 07:02:57  richard
+#  . lots of date/interval related changes:
+#    - more relaxed date format for input
+#
+# Revision 1.7  2001/08/13 23:01:53  richard
+# fixed a 2.1-ism
+#
+# Revision 1.6  2001/08/07 00:24:43  richard
+# stupid typo
+#
+# Revision 1.5  2001/08/07 00:15:51  richard
+# Added the copyright/license notice to (nearly) all files at request of
+# Bizar Software.
+#
+# Revision 1.4  2001/07/29 23:32:13  richard
+# Fixed bug in unit test ;)
+#
+# Revision 1.3  2001/07/29 07:01:39  richard
+# Added vim command to all source so that we don't get no steenkin' tabs :)
+#
+# Revision 1.2  2001/07/29 06:42:20  richard
+# Added Interval tests.
+#
+# Revision 1.1  2001/07/27 06:55:07  richard
+# moving tests -> test
+#
+# Revision 1.2  2001/07/25 04:34:31  richard
+# Added id and log to tests files...
+#
+#
+# vim: set filetype=python ts=4 sw=4 et si