[Zope3-checkins] SVN: Zope3/trunk/src/zope/tal/ Added optional source annotations to zope.tal to simplify ZPT debugging.

Marius Gedminas marius at pov.lt
Fri Jun 11 10:28:14 EDT 2004


Log message for revision 25348:
Added optional source annotations to zope.tal to simplify ZPT debugging.

Source annotations are HTML/XML comments inserted into the output stream
whenever a setSourceFile instruction is encountered.  These instructions
are generated in the following locations:

 - at the beginning of a file
 - at the beginning of a macro definition (start tag with metal:define-macro)
 - at the beginning of a slot (start tag with metal:fill-slot)
 - after a macro usage (end tag for an element with metal:use-macro)
 - after a slot definition (end tag for an element with metal:define-slot)

These locations should cover all possible transitions between different source
files and/or locations within the source file.

Other kinds of annotations (e.g. extra attributes on elements that could be
easily accessed from Javascript or processed with standard XML tools) are
planned in the future.

Also added a docstring explaining various keyword arguments of TALInterpreter.




-=-
Modified: Zope3/trunk/src/zope/tal/driver.py
===================================================================
--- Zope3/trunk/src/zope/tal/driver.py	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/driver.py	2004-06-11 14:28:14 UTC (rev 25348)
@@ -34,6 +34,8 @@
         Leave TAL/METAL attributes in output
     -i
         Leave I18N substitution strings un-interpolated.
+    -a
+        Enable source annotations
 """
 
 import os
@@ -113,10 +115,11 @@
     mode = None
     showcode = 0
     showtal = -1
+    sourceAnnotations = 0
     strictinsert = 1
     i18nInterpolate = 1
     try:
-        opts, args = getopt.getopt(sys.argv[1:], "hHxlmsti",
+        opts, args = getopt.getopt(sys.argv[1:], "hHxlmstia",
                                    ['help', 'html', 'xml'])
     except getopt.error, msg:
         usage(2, msg)
@@ -141,6 +144,8 @@
             showtal = 1
         if opt == '-i':
             i18nInterpolate = 0
+        if opt == '-a':
+            sourceAnnotations = 1
     if args:
         file = args[0]
     else:
@@ -157,10 +162,11 @@
         interpretit(it, engine=engine,
                     tal=(not macros), showtal=showtal,
                     strictinsert=strictinsert,
-                    i18nInterpolate=i18nInterpolate)
+                    i18nInterpolate=i18nInterpolate,
+                    sourceAnnotations=sourceAnnotations)
 
 def interpretit(it, engine=None, stream=None, tal=1, showtal=-1,
-                strictinsert=1, i18nInterpolate=1):
+                strictinsert=1, i18nInterpolate=1, sourceAnnotations=0):
     from zope.tal.talinterpreter import TALInterpreter
     program, macros = it
     assert zope.tal.taldefs.isCurrentVersion(program)
@@ -168,7 +174,8 @@
         engine = DummyEngine(macros)
     TALInterpreter(program, macros, engine, stream, wrap=0,
                    tal=tal, showtal=showtal, strictinsert=strictinsert,
-                   i18nInterpolate=i18nInterpolate)()
+                   i18nInterpolate=i18nInterpolate,
+                   sourceAnnotations=sourceAnnotations)()
 
 def compilefile(file, mode=None):
     assert mode in ("html", "xml", None)
@@ -178,12 +185,17 @@
             mode = "html"
         else:
             mode = "xml"
+    from zope.tal.talgenerator import TALGenerator
+    filename = os.path.abspath(file)
+    prefix = os.path.dirname(os.path.abspath(__file__)) + os.path.sep
+    if filename.startswith(prefix):
+        filename = filename[len(prefix):]
     if mode == "html":
         from zope.tal.htmltalparser import HTMLTALParser
-        p = HTMLTALParser()
+        p = HTMLTALParser(gen=TALGenerator(source_file=filename, xml=0))
     else:
         from zope.tal.talparser import TALParser
-        p = TALParser()
+        p = TALParser(gen=TALGenerator(source_file=filename))
     p.parseFile(file)
     return p.getCode()
 

Modified: Zope3/trunk/src/zope/tal/htmltalparser.py
===================================================================
--- Zope3/trunk/src/zope/tal/htmltalparser.py	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/htmltalparser.py	2004-06-11 14:28:14 UTC (rev 25348)
@@ -171,7 +171,7 @@
                     self.getpos())
             self.gen.emitStartElement(tag, attrlist, taldict, metaldict,
                                       i18ndict, self.getpos())
-            self.gen.emitEndElement(tag, implied=-1)
+            self.gen.emitEndElement(tag, implied=-1, position=self.getpos())
         else:
             self.gen.emitStartElement(tag, attrlist, taldict, metaldict,
                                       i18ndict, self.getpos(), isend=1)
@@ -182,7 +182,7 @@
             # </img> etc. in the source is an error
             raise EmptyTagError(tag, self.getpos())
         self.close_enclosed_tags(tag)
-        self.gen.emitEndElement(tag)
+        self.gen.emitEndElement(tag, position=self.getpos())
         self.pop_xmlns()
         self.tagstack.pop()
 
@@ -231,7 +231,8 @@
             white = self.gen.unEmitWhitespace()
         else:
             white = None
-        self.gen.emitEndElement(tag, isend=isend, implied=implied)
+        self.gen.emitEndElement(tag, isend=isend, implied=implied,
+                                position=self.getpos())
         if white:
             self.gen.emitRawText(white)
         self.tagstack.pop()

Modified: Zope3/trunk/src/zope/tal/runtest.py
===================================================================
--- Zope3/trunk/src/zope/tal/runtest.py	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/runtest.py	2004-06-11 14:28:14 UTC (rev 25348)
@@ -79,6 +79,8 @@
         locopts = []
         if arg.find("metal") >= 0 and "-m" not in opts:
             locopts.append("-m")
+        if arg.find("_sa") >= 0 and "-a" not in opts:
+            locopts.append("-a")
         if not unittesting:
             print arg,
             sys.stdout.flush()

Modified: Zope3/trunk/src/zope/tal/talgenerator.py
===================================================================
--- Zope3/trunk/src/zope/tal/talgenerator.py	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/talgenerator.py	2004-06-11 14:28:14 UTC (rev 25348)
@@ -561,7 +561,10 @@
         if self.inMacroUse:
             if fillSlot:
                 self.pushProgram()
+                # generate a source annotation at the beginning of fill-slot
                 if self.source_file is not None:
+                    if position != (None, None):
+                        self.emit("setPosition", position)
                     self.emit("setSourceFile", self.source_file)
                 todo["fillSlot"] = fillSlot
                 self.inMacroUse = 0
@@ -574,7 +577,10 @@
                 self.pushProgram()
                 self.emit("version", TAL_VERSION)
                 self.emit("mode", self.xml and "xml" or "html")
+                # generate a source annotation at the beginning of the macro
                 if self.source_file is not None:
+                    if position != (None, None):
+                        self.emit("setPosition", position)
                     self.emit("setSourceFile", self.source_file)
                 todo["defineMacro"] = defineMacro
                 self.inMacroDef = self.inMacroDef + 1
@@ -710,9 +716,9 @@
             todo["position"] = position
         self.todoPush(todo)
         if isend:
-            self.emitEndElement(name, isend)
+            self.emitEndElement(name, isend, position=position)
 
-    def emitEndElement(self, name, isend=0, implied=0):
+    def emitEndElement(self, name, isend=0, implied=0, position=(None, None)):
         todo = self.todoPop()
         if not todo:
             # Shortcut
@@ -720,7 +726,7 @@
                 self.emitEndTag(name)
             return
 
-        self.position = position = todo.get("position", (None, None))
+        self.position = todo.get("position", (None, None))
         defineMacro = todo.get("defineMacro")
         useMacro = todo.get("useMacro")
         defineSlot = todo.get("defineSlot")
@@ -747,7 +753,7 @@
                 exc = TALError
                 what = "TAL"
             raise exc("%s attributes on <%s> require explicit </%s>" %
-                      (what, name, name), position)
+                      (what, name, name), self.position)
 
         if script:
             self.emitEvaluateCode(script)
@@ -823,6 +829,13 @@
             self.emitUseMacro(useMacro)
         if defineMacro:
             self.emitDefineMacro(defineMacro)
+        if useMacro or defineSlot:
+            # generate a source annotation after define-slot or use-macro
+            # because the source file might have changed
+            if self.source_file is not None:
+                if position != (None, None):
+                    self.emit("setPosition", position)
+                self.emit("setSourceFile", self.source_file)
 
 
 def _parseI18nAttributes(i18nattrs, position, xml):

Modified: Zope3/trunk/src/zope/tal/talinterpreter.py
===================================================================
--- Zope3/trunk/src/zope/tal/talinterpreter.py	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/talinterpreter.py	2004-06-11 14:28:14 UTC (rev 25348)
@@ -89,14 +89,79 @@
 
 
 class TALInterpreter:
+    """TAL interpreter.
 
+    Some notes on source annotations.  They are HTML/XML comments added to the
+    output whenever sourceFile is changed by a setSourceFile bytecode.  Source
+    annotations are disabled by default, but you can turn them on by passing a
+    sourceAnnotations argument to the constructor.  You can change the format
+    of the annotations by overriding formatSourceAnnotation in a subclass.
+
+    The output of the annotation is delayed until some actual text is output
+    for two reasons:
+
+        1. setPosition bytecode follows setSourceFile, and we need position
+           information to output the line number.
+        2. Mozilla does not cope with HTML comments that occur before
+           <!DOCTYPE> (XXX file a bug into bugzilla.mozilla.org as comments
+           are legal there according to HTML4 spec).
+
+    For performance reasons (XXX premature optimization?) instead of checking
+    the value of _pending_source_annotation on every write to the output
+    stream, the _stream_write attribute is changed to point to
+    _annotated_stream_write method whenever _pending_source_annotation is
+    set to True, and to _stream.write when it is False.  The following
+    invariant always holds:
+
+        if self._pending_source_annotation:
+            assert self._stream_write is self._annotated_stream_write
+        else:
+            assert self._stream_write is self.stream.write
+
+    """
+
     def __init__(self, program, macros, engine, stream=None,
                  debug=0, wrap=60, metal=1, tal=1, showtal=-1,
-                 strictinsert=1, stackLimit=100, i18nInterpolate=1):
+                 strictinsert=1, stackLimit=100, i18nInterpolate=1,
+                 sourceAnnotations=0):
+        """Create a TAL interpreter.
+
+        Optional arguments:
+
+            stream -- output stream (defaults to sys.stdout).
+
+            debug -- enable debugging output to sys.stderr (off by default).
+
+            wrap -- try to wrap attributes on opening tags to this number of
+            column (default: 60).
+
+            metal -- enable METAL macro processing (on by default).
+
+            tal -- enable TAL processing (on by default).
+
+            showtal -- do not strip away TAL directives.  A special value of
+            -1 (which is the default setting) enables showtal when TAL
+            processing is disabled, and disables showtal when TAL processing is
+            enabled.  Note that you must use 0, 1, or -1; true boolean values
+            are not supported (XXX why?).
+
+            strictinsert -- enable TAL processing and stricter HTML/XML
+            checking on text produced by structure inserts (on by default).
+            Note that Zope turns this value off by default.
+
+            stackLimit -- set macro nesting limit (default: 100).
+
+            i18nInterpolate -- enable i18n translations (default: on).
+
+            sourceAnnotations -- enable source annotations with HTML comments
+            (default: off).
+
+        """
         self.program = program
         self.macros = macros
         self.engine = engine # Execution engine (aka context)
         self.Default = engine.getDefault()
+        self._pending_source_annotation = False
         self._stream_stack = [stream or sys.stdout]
         self.popStream()
         self.debug = debug
@@ -125,6 +190,7 @@
         self.i18nStack = []
         self.i18nInterpolate = i18nInterpolate
         self.i18nContext = TranslationContext()
+        self.sourceAnnotations = sourceAnnotations
 
     def saveState(self):
         return (self.position, self.col, self.stream, self._stream_stack,
@@ -133,7 +199,10 @@
     def restoreState(self, state):
         (self.position, self.col, self.stream,
          self._stream_stack, scopeLevel, level, i18n) = state
-        self._stream_write = self.stream.write
+        if self._pending_source_annotation:
+            self._stream_write = self._annotated_stream_write
+        else:
+            self._stream_write = self.stream.write
         assert self.level == level
         while self.scopeLevel > scopeLevel:
             self.engine.endScope()
@@ -144,7 +213,10 @@
     def restoreOutputState(self, state):
         (dummy, self.col, self.stream,
          self._stream_stack, scopeLevel, level, i18n) = state
-        self._stream_write = self.stream.write
+        if self._pending_source_annotation:
+            self._stream_write = self._annotated_stream_write
+        else:
+            self._stream_write = self.stream.write
         assert self.level == level
         assert self.scopeLevel == scopeLevel
 
@@ -172,12 +244,48 @@
     def pushStream(self, newstream):
         self._stream_stack.append(self.stream)
         self.stream = newstream
-        self._stream_write = newstream.write
+        if self._pending_source_annotation:
+            self._stream_write = self._annotated_stream_write
+        else:
+            self._stream_write = self.stream.write
 
     def popStream(self):
         self.stream = self._stream_stack.pop()
+        if self._pending_source_annotation:
+            self._stream_write = self._annotated_stream_write
+        else:
+            self._stream_write = self.stream.write
+
+    def _annotated_stream_write(self, s):
+        idx = s.find('<!DOCTYPE')
+        if idx == -1:
+            idx = s.find('<?xml')
+        if idx >= 0 or s.isspace():
+            # Do *not* preprend comments in front of the <!DOCTYPE> or
+            # <?xml?> declaration!  Although that is completely legal according
+            # to w3c.org, Mozilla chokes on such pages.
+            end_of_doctype = s.find('>', idx)
+            if end_of_doctype > idx:
+                self.stream.write(s[:end_of_doctype+1])
+                s = s[end_of_doctype+1:]
+                # continue
+            else:
+                self.stream.write(s)
+                return
+        self._pending_source_annotation = False
         self._stream_write = self.stream.write
+        self._stream_write(self.formatSourceAnnotation())
+        self._stream_write(s)
 
+    def formatSourceAnnotation(self):
+        lineno = self.position[0]
+        if lineno is None:
+            location = self.sourceFile
+        else:
+            location = '%s (line %s)' % (self.sourceFile, lineno)
+        sep = '=' * 78
+        return '<!--\n%s\n%s\n%s\n-->' % (sep, location, sep)
+
     def stream_write(self, s,
                      len=len):
         self._stream_write(s)
@@ -225,6 +333,10 @@
     def do_setSourceFile(self, source_file):
         self.sourceFile = source_file
         self.engine.setSourceFile(source_file)
+        if self.sourceAnnotations:
+            self._pending_source_annotation = True
+            self._stream_write = self._annotated_stream_write
+
     bytecode_handlers["setSourceFile"] = do_setSourceFile
 
     def do_setPosition(self, position):

Added: Zope3/trunk/src/zope/tal/tests/input/test_sa1.html
===================================================================
--- Zope3/trunk/src/zope/tal/tests/input/test_sa1.html	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/tests/input/test_sa1.html	2004-06-11 14:28:14 UTC (rev 25348)
@@ -0,0 +1,6 @@
+<html>
+<title>Simple test of source annotations</title>
+<body>
+<p>Foo!</p>
+</body>
+</html>


Property changes on: Zope3/trunk/src/zope/tal/tests/input/test_sa1.html
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/tal/tests/input/test_sa1.xml
===================================================================
--- Zope3/trunk/src/zope/tal/tests/input/test_sa1.xml	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/tests/input/test_sa1.xml	2004-06-11 14:28:14 UTC (rev 25348)
@@ -0,0 +1,7 @@
+<?xml version="1.0" ?>
+<html>
+<title>Simple test of source annotations</title>
+<body>
+<p>Foo!</p>
+</body>
+</html>


Property changes on: Zope3/trunk/src/zope/tal/tests/input/test_sa1.xml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/tal/tests/input/test_sa2.html
===================================================================
--- Zope3/trunk/src/zope/tal/tests/input/test_sa2.html	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/tests/input/test_sa2.html	2004-06-11 14:28:14 UTC (rev 25348)
@@ -0,0 +1,9 @@
+<!DOCTYPE html 
+  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "DTD/xhtml1-transitional.dtd">
+<html>
+<title>Simple test of source annotations</title>
+<body>
+<p>Foo!</p>
+</body>
+</html>


Property changes on: Zope3/trunk/src/zope/tal/tests/input/test_sa2.html
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/tal/tests/input/test_sa2.xml
===================================================================
--- Zope3/trunk/src/zope/tal/tests/input/test_sa2.xml	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/tests/input/test_sa2.xml	2004-06-11 14:28:14 UTC (rev 25348)
@@ -0,0 +1,10 @@
+<?xml version="1.0" ?>
+<!DOCTYPE html 
+  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "DTD/xhtml1-transitional.dtd">
+<html>
+<title>Simple test of source annotations</title>
+<body>
+<p>Foo!</p>
+</body>
+</html>


Property changes on: Zope3/trunk/src/zope/tal/tests/input/test_sa2.xml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/tal/tests/input/test_sa3.html
===================================================================
--- Zope3/trunk/src/zope/tal/tests/input/test_sa3.html	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/tests/input/test_sa3.html	2004-06-11 14:28:14 UTC (rev 25348)
@@ -0,0 +1,15 @@
+<html>
+<body>
+  <div metal:define-macro="macro1">This is macro1 on sa3 line 3.
+    <span metal:define-slot="slot1">This is slot1 on sa3 line 4.</span>
+    This is the end of macro1 on sa3 line 5.
+  </div>
+  <p>Some text on sa3 line 7.</p>
+  <p metal:use-macro="macro1">
+    This text on sa3 line 9 will disappear.
+    <b metal:fill-slot="slot1">Text from sa3 line 10 is filled into slot1.</b>
+    This text on sa3 line 11 will disappear.
+  </p>
+  <p>This is some text on sa3 line 13.</p>
+</body>
+</html>


Property changes on: Zope3/trunk/src/zope/tal/tests/input/test_sa3.html
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/tal/tests/input/test_sa4.html
===================================================================
--- Zope3/trunk/src/zope/tal/tests/input/test_sa4.html	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/tests/input/test_sa4.html	2004-06-11 14:28:14 UTC (rev 25348)
@@ -0,0 +1,11 @@
+<html>
+<body>
+  <p>Some text on sa4 line 3.</p>
+  <p metal:use-macro="tests/input/test_sa3.html/macro1">
+    This text on sa4 line 5 will disappear.
+    <b metal:fill-slot="slot1">Text from sa4 line 6 is filled into slot1.</b>
+    This text on sa4 line 7 will disappear.
+  </p>
+  <p>This is some text on sa4 line 9.</p>
+</body>
+</html>


Property changes on: Zope3/trunk/src/zope/tal/tests/input/test_sa4.html
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/tal/tests/output/test_sa1.html
===================================================================
--- Zope3/trunk/src/zope/tal/tests/output/test_sa1.html	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/tests/output/test_sa1.html	2004-06-11 14:28:14 UTC (rev 25348)
@@ -0,0 +1,10 @@
+<!--
+==============================================================================
+tests/input/test_sa1.html
+==============================================================================
+--><html>
+<title>Simple test of source annotations</title>
+<body>
+<p>Foo!</p>
+</body>
+</html>


Property changes on: Zope3/trunk/src/zope/tal/tests/output/test_sa1.html
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/tal/tests/output/test_sa1.xml
===================================================================
--- Zope3/trunk/src/zope/tal/tests/output/test_sa1.xml	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/tests/output/test_sa1.xml	2004-06-11 14:28:14 UTC (rev 25348)
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?><!--
+==============================================================================
+tests/input/test_sa1.xml
+==============================================================================
+-->
+<html>
+<title>Simple test of source annotations</title>
+<body>
+<p>Foo!</p>
+</body>
+</html>


Property changes on: Zope3/trunk/src/zope/tal/tests/output/test_sa1.xml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/tal/tests/output/test_sa2.html
===================================================================
--- Zope3/trunk/src/zope/tal/tests/output/test_sa2.html	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/tests/output/test_sa2.html	2004-06-11 14:28:14 UTC (rev 25348)
@@ -0,0 +1,13 @@
+<!DOCTYPE html 
+  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "DTD/xhtml1-transitional.dtd"><!--
+==============================================================================
+tests/input/test_sa2.html
+==============================================================================
+-->
+<html>
+<title>Simple test of source annotations</title>
+<body>
+<p>Foo!</p>
+</body>
+</html>


Property changes on: Zope3/trunk/src/zope/tal/tests/output/test_sa2.html
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/tal/tests/output/test_sa2.xml
===================================================================
--- Zope3/trunk/src/zope/tal/tests/output/test_sa2.xml	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/tests/output/test_sa2.xml	2004-06-11 14:28:14 UTC (rev 25348)
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<!DOCTYPE html 
+  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "DTD/xhtml1-transitional.dtd"><!--
+==============================================================================
+tests/input/test_sa2.xml
+==============================================================================
+-->
+<html>
+<title>Simple test of source annotations</title>
+<body>
+<p>Foo!</p>
+</body>
+</html>


Property changes on: Zope3/trunk/src/zope/tal/tests/output/test_sa2.xml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/tal/tests/output/test_sa3.html
===================================================================
--- Zope3/trunk/src/zope/tal/tests/output/test_sa3.html	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/tests/output/test_sa3.html	2004-06-11 14:28:14 UTC (rev 25348)
@@ -0,0 +1,42 @@
+<!--
+==============================================================================
+tests/input/test_sa3.html
+==============================================================================
+--><html>
+<body>
+  <!--
+==============================================================================
+tests/input/test_sa3.html (line 3)
+==============================================================================
+--><div>This is macro1 on sa3 line 3.
+    <span>This is slot1 on sa3 line 4.</span><!--
+==============================================================================
+tests/input/test_sa3.html (line 4)
+==============================================================================
+-->
+    This is the end of macro1 on sa3 line 5.
+  </div>
+  <p>Some text on sa3 line 7.</p>
+  <!--
+==============================================================================
+tests/input/test_sa3.html (line 3)
+==============================================================================
+--><div>This is macro1 on sa3 line 3.
+    <!--
+==============================================================================
+tests/input/test_sa3.html (line 10)
+==============================================================================
+--><b>Text from sa3 line 10 is filled into slot1.</b><!--
+==============================================================================
+tests/input/test_sa3.html (line 4)
+==============================================================================
+-->
+    This is the end of macro1 on sa3 line 5.
+  </div><!--
+==============================================================================
+tests/input/test_sa3.html (line 12)
+==============================================================================
+-->
+  <p>This is some text on sa3 line 13.</p>
+</body>
+</html>


Property changes on: Zope3/trunk/src/zope/tal/tests/output/test_sa3.html
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/tal/tests/output/test_sa4.html
===================================================================
--- Zope3/trunk/src/zope/tal/tests/output/test_sa4.html	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/tests/output/test_sa4.html	2004-06-11 14:28:14 UTC (rev 25348)
@@ -0,0 +1,30 @@
+<!--
+==============================================================================
+tests/input/test_sa4.html
+==============================================================================
+--><html>
+<body>
+  <p>Some text on sa4 line 3.</p>
+  <!--
+==============================================================================
+tests/input/test_sa3.html (line 3)
+==============================================================================
+--><div>This is macro1 on sa3 line 3.
+    <!--
+==============================================================================
+tests/input/test_sa4.html (line 6)
+==============================================================================
+--><b>Text from sa4 line 6 is filled into slot1.</b><!--
+==============================================================================
+tests/input/test_sa3.html (line 4)
+==============================================================================
+-->
+    This is the end of macro1 on sa3 line 5.
+  </div><!--
+==============================================================================
+tests/input/test_sa4.html (line 8)
+==============================================================================
+-->
+  <p>This is some text on sa4 line 9.</p>
+</body>
+</html>


Property changes on: Zope3/trunk/src/zope/tal/tests/output/test_sa4.html
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope3/trunk/src/zope/tal/tests/test_files.py
===================================================================
--- Zope3/trunk/src/zope/tal/tests/test_files.py	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/tests/test_files.py	2004-06-11 14:28:14 UTC (rev 25348)
@@ -43,7 +43,9 @@
         basename = os.path.basename(self.__file)
         #sys.stdout.write(basename + " ")
         sys.stdout.flush()
-        if basename.startswith('test_metal'):
+        if basename.startswith('test_sa'):
+            sys.argv = ["", "-Q", "-a", self.__file]
+        elif basename.startswith('test_metal'):
             sys.argv = ["", "-Q", "-m", self.__file]
         else:
             sys.argv = ["", "-Q", self.__file]

Modified: Zope3/trunk/src/zope/tal/tests/test_talinterpreter.py
===================================================================
--- Zope3/trunk/src/zope/tal/tests/test_talinterpreter.py	2004-06-11 12:18:20 UTC (rev 25347)
+++ Zope3/trunk/src/zope/tal/tests/test_talinterpreter.py	2004-06-11 14:28:14 UTC (rev 25348)
@@ -369,12 +369,77 @@
         self.assertEqual(sio.getvalue(), EXPECTED)
 
 
+class TestSourceAnnotations(unittest.TestCase):
+
+    # there are additional test files in input/ and output/ subdirs
+    # (test_sa*)
+
+    def setUp(self):
+        program = []
+        macros = {}
+        engine = DummyEngine()
+        self.interpreter = TALInterpreter(program, macros, engine)
+        self.sio = self.interpreter.stream = StringIO()
+        self.interpreter._pending_source_annotation = True
+
+    def testFormatSourceAnnotation(self):
+        interpreter = self.interpreter
+        interpreter.sourceFile = '/path/to/source.pt'
+        interpreter.position = (123, 42)
+        self.assertEquals(interpreter.formatSourceAnnotation(),
+            "<!--\n" +
+            "=" * 78 + "\n" +
+            "/path/to/source.pt (line 123)\n" +
+            "=" * 78 + "\n" +
+            "-->")
+
+    def testFormatSourceAnnotation_no_position(self):
+        interpreter = self.interpreter
+        interpreter.sourceFile = '/path/to/source.pt'
+        interpreter.position = (None, None)
+        self.assertEquals(interpreter.formatSourceAnnotation(),
+            "<!--\n" +
+            "=" * 78 + "\n" +
+            "/path/to/source.pt\n" +
+            "=" * 78 + "\n" +
+            "-->")
+
+    def test_annotated_stream_write(self):
+        interpreter = self.interpreter
+        interpreter.formatSourceAnnotation = lambda: '@'
+        test_cases = [
+            '@some text',
+            '\n',
+            '<!DOCTYPE ...>@some text',
+            ' <!DOCTYPE ...>@some text',
+            '\n<!DOCTYPE ...>@some text',
+            '<!DOCTYPE ...',
+            '<?xml ...>@some text',
+            ' <?xml ...>@some text',
+            '\n<?xml ...>@some text',
+            '<?xml ...',
+            '<?xml ...?>\n<!DOCTYPE ...>@some text',
+        ]
+        for output in test_cases:
+            input = output.replace('@', '')
+            self.sio.seek(0)
+            self.sio.truncate()
+            interpreter._pending_source_annotation = True
+            interpreter._annotated_stream_write(input)
+            self.assertEquals(self.sio.getvalue(), output)
+            if '@' in output:
+                self.assert_(not interpreter._pending_source_annotation)
+            else:
+                self.assert_(interpreter._pending_source_annotation)
+
+
 def test_suite():
     suite = unittest.makeSuite(I18NErrorsTestCase)
     suite.addTest(unittest.makeSuite(MacroErrorsTestCase))
     suite.addTest(unittest.makeSuite(OutputPresentationTestCase))
     suite.addTest(unittest.makeSuite(ScriptTestCase))
     suite.addTest(unittest.makeSuite(I18NCornerTestCase))
+    suite.addTest(unittest.makeSuite(TestSourceAnnotations))
 
     # XXX: Deactivated test, since we have not found a solution for this and
     # it is a deep and undocumented HTML parser issue.




More information about the Zope3-Checkins mailing list