[Checkins] SVN: zope.etree/trunk/src/zope/etree/ zope.etree is a module to enable developers to use the ElementTree

Michael Kerrin michael.kerrin at openapp.biz
Fri Aug 25 06:46:19 EDT 2006


Log message for revision 69779:
  zope.etree is a module to enable developers to use the ElementTree
  API to process XML while not enforcing a particular implementation
  of ElementTree on site admins.
  

Changed:
  A   zope.etree/trunk/src/zope/etree/README.txt
  A   zope.etree/trunk/src/zope/etree/SETUP.cfg
  A   zope.etree/trunk/src/zope/etree/TODO.txt
  A   zope.etree/trunk/src/zope/etree/__init__.py
  A   zope.etree/trunk/src/zope/etree/etree.py
  A   zope.etree/trunk/src/zope/etree/interfaces.py
  A   zope.etree/trunk/src/zope/etree/testing.py
  A   zope.etree/trunk/src/zope/etree/tests.py
  A   zope.etree/trunk/src/zope/etree/zope.etree-configure.zcml

-=-
Added: zope.etree/trunk/src/zope/etree/README.txt
===================================================================
--- zope.etree/trunk/src/zope/etree/README.txt	2006-08-25 10:35:09 UTC (rev 69778)
+++ zope.etree/trunk/src/zope/etree/README.txt	2006-08-25 10:46:18 UTC (rev 69779)
@@ -0,0 +1,107 @@
+=========================
+Zope Element Tree Support
+=========================
+
+This package does not implement the ElementTree API but instead provides
+proxy objects that wrap some of the more common ElementTree implementations.
+Then one of these proxy objects is registered as a utility, providing the
+*zope.etree.interfaces.IEtree* interface, which can be looked up through
+the Zope component architecture. Thus removing the hard dependency a Python
+import statement introduces on any one ElementTree implementation.
+
+This will allow anyone interested in just trying out a module developed using
+*zope.etree* to use a pure Python implementation of ElementTree (which is really
+easy to install, but slow). While a developer who is in the final stages of
+going live with a new site might want to configure the same module to use lxml
+(which is *not* easy to install as it depends on libxml2 and libxslt but is
+really, really, really fast).
+
+If there is any ElementTree implementation that I have missed, or any bugs,
+improvements, then please contact me at
+michael.kerrin at openapp.ie and I will do my best to fix the situation.
+
+Installation and Configuration
+==============================
+
+*zope.etree* is installed like any other Zope3 module. That is it should be
+copied verbatim into your Python path and the zope.etree-configure.zcml file
+should be copied to the package-includes directory for each instance of Zope
+that requires this package. (Once I figure out how to, I will use Python eggs
+for the installation process.)
+
+Now each of the zope.etree-configure.zcml files that exist in a instances
+package-includes directory can be edited to configure which ElementTree
+implementation to use within that instance.
+
+To configure a particular ElementTree implementation for an instance the
+zope.etree-configure.zcml file should contain only one ZCML utility
+declaration. For example to configure an instance use lxml
+zope.etree-configure.zcml should contain the the following::
+
+  <utility
+     factory="zope.etree.etree.LxmlEtree"
+     />
+
+Where *zope.etree.etree.LxmlEtree* is the proxy object that wraps the lxml
+implementation. Currently the other implementations include:
+
++ *zope.etree.etree.EtreeEtree* - proxy for the pure python *elementtree*
+  module.
+
++ *zope.etree.etree.EtreePy25* - proxy for the ElementTree implementation
+  included in Python 2.5's standard library.
+
+Tests setup
+===========
+
+Some setup for the developers tests.
+
+  >>> from zope import component
+  >>> import zope.etree.interfaces
+
+This happens automatically during Zope startup.
+
+  >>> from zope.etree.testing import etreeSetup, etreeTearDown
+  >>> from zope.etree.testing import assertXMLEqual
+  >>> dummy = etreeSetup()
+
+Developers
+==========
+
+Here are some examples for how to use *zope.etree* with your own code.
+
+To generate a Element object with the tag *DAV:getcontenttype* all we have
+to do is:
+
+  >>> etree = component.getUtility(zope.etree.interfaces.IEtree)
+  >>> elem = etree.Element("{DAV:}getcontenttype")
+  >>> assertXMLEqual(etree.tostring(elem), """
+  ...    <ns0:getcontenttype xmlns:ns0="DAV:"/>""")
+
+Now to add a value this element use just use the *elem* variable has the API
+suggests.
+
+  >>> elem.text = "text/plain"
+  >>> assertXMLEqual(etree.tostring(elem), """
+  ...    <ns0:getcontenttype xmlns:ns0="DAV:">text/plain</ns0:getcontenttype>""")
+
+Testing
+=======
+
+For developers who are writing unit tests for their code that uses
+*zope.etree*. They should call the method *zope.etree.testing.etreeSetup* in
+there tests setup code, in order to correctly register a ElementTree utility
+for use within their tests. And similar, call the method
+*zope.etree.testing.etreeTearDown* in their teardown code. See the Setup
+and Teardown sections of this file.
+
+The *etreeSetup* method will load and parse the *zope.etree-configure.zcml*
+file from within the *zope.etree* module (NOT the file from the instance). So
+if the default utility defined in this file, which is
+*zope.etree.etree.EtreeEtree*, doesn't apply to your system due to a missing
+module for example, then this file should be edited to reflect this.
+
+Teardown
+========
+
+  >>> etreeTearDown()


Property changes on: zope.etree/trunk/src/zope/etree/README.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: zope.etree/trunk/src/zope/etree/SETUP.cfg
===================================================================
--- zope.etree/trunk/src/zope/etree/SETUP.cfg	2006-08-25 10:35:09 UTC (rev 69778)
+++ zope.etree/trunk/src/zope/etree/SETUP.cfg	2006-08-25 10:46:18 UTC (rev 69779)
@@ -0,0 +1,5 @@
+# Tell zpkg how to install the ZCML slugs.
+
+<data-files zopeskel/etc/package-includes>
+  zope.etree-configure.zcml
+</data-files>

Added: zope.etree/trunk/src/zope/etree/TODO.txt
===================================================================
--- zope.etree/trunk/src/zope/etree/TODO.txt	2006-08-25 10:35:09 UTC (rev 69778)
+++ zope.etree/trunk/src/zope/etree/TODO.txt	2006-08-25 10:46:18 UTC (rev 69779)
@@ -0,0 +1,18 @@
++ add comments into this interface.
+
++ extend this interface to each of the different element tree engines. So
+  some example lxml supports things that the original elementtree
+  implementation did and vice versa. This way developers can say give me
+  an elementtree implementation support feature X. But we still need to be
+  carefull that we still have a common base interface from which to work
+  off.
+
++ Figure out how to use Python eggs for installation.
+
++ Is it possible to configure which zope.etree-configure.zcml to use when
+  running the unit tests, as otherwise people will need to make local
+  modifications to their zope.etree checkout.
+
++ Figure if there is some ZCML magic we can use in order to register
+  a module directly has a uiltity so that there can be no bugs in my proxy
+  objects.


Property changes on: zope.etree/trunk/src/zope/etree/TODO.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: zope.etree/trunk/src/zope/etree/__init__.py
===================================================================
--- zope.etree/trunk/src/zope/etree/__init__.py	2006-08-25 10:35:09 UTC (rev 69778)
+++ zope.etree/trunk/src/zope/etree/__init__.py	2006-08-25 10:46:18 UTC (rev 69779)
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+Zope Element Tree Support
+
+$Id$
+"""


Property changes on: zope.etree/trunk/src/zope/etree/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.etree/trunk/src/zope/etree/etree.py
===================================================================
--- zope.etree/trunk/src/zope/etree/etree.py	2006-08-25 10:35:09 UTC (rev 69778)
+++ zope.etree/trunk/src/zope/etree/etree.py	2006-08-25 10:46:18 UTC (rev 69779)
@@ -0,0 +1,305 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Zope Element Tree Support
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import copy
+from zope.interface import implements
+
+from interfaces import IEtree
+
+class BaseEtree(object):
+    def Comment(self, text = None):
+        return self.etree.Comment(text)
+
+    # XXX - not tested
+    def dump(self, elem):
+        return self.etree.dump(elem)
+
+    def Element(self, tag, attrib = {}, **extra):
+        return self.etree.Element(tag, attrib, **extra)
+
+    def ElementTree(self, element = None, file = None):
+        return self.etree.ElementTree(element, file)
+
+    def XML(self, text):
+        return self.etree.fromstring(text)
+
+    fromstring = XML
+
+    def iselement(self, element):
+        return self.etree.iselement(element)
+
+    # XXX - not tested
+    def iterparse(self, source, events = None):
+        return self.etree.iterparse(source, events)
+
+    def parse(self, source, parser = None):
+        return self.etree.parse(source, parser)
+
+    def PI(self, target, text = None):
+        raise NotImplementedError, "lxml doesn't implement PI"
+
+    ProcessingInstruction = PI
+
+    def QName(self, text_or_uri, tag = None):
+        return self.etree.QName(text_or_uri, tag)
+
+    def SubElement(self, parent, tag, attrib = {}, **extra):
+        return self.etree.SubElement(parent, tag, attrib, **extra)
+
+    def tostring(self, element, encoding = None):
+        return self.etree.tostring(element, encoding)
+
+    def TreeBuilder(self, element_factory = None):
+        raise NotImplementedError, "lxml doesn't implement TreeBuilder"
+
+    def XMLTreeBuilder(self, html = 0, target = None):
+        raise NotImplementedError, "lxml doesn't implement XMLTreeBuilder"
+
+
+class EtreeEtree(BaseEtree):
+    """
+    Support for ElementTree
+
+      >>> from cStringIO import StringIO
+      >>> from zope.interface.verify import verifyObject
+      >>> letree = EtreeEtree()
+      >>> verifyObject(IEtree, letree)
+      True
+
+      >>> letree.Comment(u'some text') #doctest:+ELLIPSIS
+      <Element <function Comment at ...
+
+      >>> letree.Element(u'testtag')
+      <Element...
+
+      >>> letree.ElementTree() #doctest:+ELLIPSIS
+      <elementtree.ElementTree.ElementTree instance at ...
+
+      >>> letree.XML(u'<p>some text</p>')
+      <Element p ...
+
+      >>> letree.fromstring(u'<p>some text</p>')
+      <Element p ...
+
+      >>> elem = letree.Element(u'testtag')
+      >>> letree.iselement(elem)
+      1
+
+      >>> f = StringIO('<b>Test Source String</b>')
+      >>> letree.parse(f) #doctest:+ELLIPSIS
+      <elementtree.ElementTree.ElementTree instance at ...
+
+      >>> letree.QName('http://example.namespace.org', 'test')#doctest:+ELLIPSIS
+      <elementtree.ElementTree.QName instance at...
+
+      >>> print letree.tostring(elem, 'ascii')
+      <?xml version='1.0' encoding='ascii'?>
+      <testtag />
+
+      >>> letree.TreeBuilder()
+      Traceback (most recent call last):
+      ...
+      NotImplementedError: lxml doesn't implement TreeBuilder
+
+      >>> subel = letree.SubElement(elem, 'foo')
+      >>> letree.tostring(elem)
+      '<testtag><foo /></testtag>'
+
+      >>> letree.PI('sometarget')  #doctest:+ELLIPSIS
+      <Element <function ProcessingInstruction at ...
+
+      >>> letree.ProcessingInstruction('sometarget') #doctest:+ELLIPSIS
+      <Element <function ProcessingInstruction at ...
+
+      >>> letree.XMLTreeBuilder()
+      <elementtree.ElementTree.XMLTreeBuilder instance at ...
+
+    """
+    implements(IEtree)
+
+    def __init__(self):
+        from elementtree import ElementTree
+        self.etree = ElementTree
+
+    def XMLTreeBuilder(self, html = 0, target = None):
+        return self.etree.XMLTreeBuilder(html, target)
+
+    def PI(self, target, text = None):
+        return self.etree.PI(target, text)
+
+    ProcessingInstruction = PI
+
+
+class EtreePy25(BaseEtree):
+    """
+    Support for ElementTree
+
+      >>> from cStringIO import StringIO
+      >>> from zope.interface.verify import verifyObject
+      >>> letree = EtreePy25()
+      >>> verifyObject(IEtree, letree)
+      True
+
+      >>> letree.Comment(u'some text') #doctest:+ELLIPSIS
+      <Element <function Comment at ...
+
+      >>> letree.Element(u'testtag')
+      <Element...
+
+      >>> letree.ElementTree() #doctest:+ELLIPSIS
+      <xml.etree.ElementTree.ElementTree instance at ...
+
+      >>> letree.XML(u'<p>some text</p>')
+      <Element p ...
+
+      >>> letree.fromstring(u'<p>some text</p>')
+      <Element p ...
+
+      >>> elem = letree.Element(u'testtag')
+      >>> letree.iselement(elem)
+      1
+
+      >>> f = StringIO('<b>Test Source String</b>')
+      >>> letree.parse(f) #doctest:+ELLIPSIS
+      <xml.etree.ElementTree.ElementTree instance at ...
+
+      >>> letree.QName('http://example.namespace.org', 'test')#doctest:+ELLIPSIS
+      <xml.etree.ElementTree.QName instance at...
+
+      >>> print letree.tostring(elem, 'ascii')
+      <?xml version='1.0' encoding='ascii'?>
+      <testtag />
+
+      >>> letree.TreeBuilder()
+      Traceback (most recent call last):
+      ...
+      NotImplementedError: lxml doesn't implement TreeBuilder
+
+      >>> subel = letree.SubElement(elem, 'foo')
+      >>> letree.tostring(elem)
+      '<testtag><foo /></testtag>'
+
+      >>> letree.PI('sometarget')  #doctest:+ELLIPSIS
+      <Element <function ProcessingInstruction at ...
+
+      >>> letree.ProcessingInstruction('sometarget') #doctest:+ELLIPSIS
+      <Element <function ProcessingInstruction at ...
+
+      >>> letree.XMLTreeBuilder()
+      <xml.etree.ElementTree.XMLTreeBuilder instance at ...
+
+    """
+    implements(IEtree)
+
+    def __init__(self):
+        from xml.etree import ElementTree
+        self.etree = ElementTree
+
+    def XMLTreeBuilder(self, html = 0, target = None):
+        return self.etree.XMLTreeBuilder(html, target)
+
+    def PI(self, target, text = None):
+        return self.etree.PI(target, text)
+
+    ProcessingInstruction = PI
+
+
+class LxmlEtree(BaseEtree):
+    """
+    Support for lxml.
+
+      >>> from cStringIO import StringIO
+      >>> from zope.interface.verify import verifyObject
+      >>> letree = LxmlEtree()
+      >>> verifyObject(IEtree, letree)
+      True
+
+      >>> letree.Comment(u'some text')
+      <Comment[some text]>
+
+      >>> letree.Element(u'testtag')
+      <Element...
+
+      >>> letree.ElementTree()
+      <etree._ElementTree...
+
+      >>> letree.XML(u'<p>some text</p>')
+      <Element p ...
+
+      >>> letree.fromstring(u'<p>some text</p>')
+      <Element p ...
+
+    When we have a element whoes namespace declaration is declared in a parent
+    element lxml doesn't print out the namespace declaration by default.
+
+      >>> multinselemstr = '<D:prop xmlns:D="DAV:"><D:owner><H:href xmlns:H="examplens">http://example.org</H:href></D:owner></D:prop>'
+      >>> multinselem = letree.fromstring(multinselemstr)
+      >>> letree.tostring(multinselem[0])
+      '<D:owner xmlns:D="DAV:"><H:href xmlns:H="examplens">http://example.org</H:href></D:owner>'
+
+      >>> elem = letree.Element(u'testtag')
+      >>> letree.iselement(elem)
+      1
+
+      >>> f = StringIO('<b>Test Source String</b>')
+      >>> letree.parse(f)
+      <etree._ElementTree object at ...
+
+      >>> letree.QName('http://example.namespace.org', 'test')
+      <etree.QName object at...
+
+      >>> letree.tostring(elem, 'ascii')
+      '<testtag/>'
+
+      >>> letree.TreeBuilder()
+      Traceback (most recent call last):
+      ...
+      NotImplementedError: lxml doesn't implement TreeBuilder
+
+      >>> subel = letree.SubElement(elem, 'foo')
+      >>> subel.getparent() is elem
+      True
+
+      >>> letree.PI('sometarget')
+      Traceback (most recent call last):
+      ...
+      NotImplementedError: lxml doesn't implement PI
+
+      >>> letree.ProcessingInstruction('sometarget')
+      Traceback (most recent call last):
+      ...
+      NotImplementedError: lxml doesn't implement PI
+
+      >>> letree.XMLTreeBuilder()
+      Traceback (most recent call last):
+      ...
+      NotImplementedError: lxml doesn't implement XMLTreeBuilder
+
+    """
+    implements(IEtree)
+
+    def __init__(self):
+        from lxml import etree
+        self.etree = etree
+
+    def tostring(self, element, encoding = None):
+        """LXML loses the namespace information whenever we print out an
+        element who namespace was defined in 
+        """
+        return self.etree.tostring(copy.copy(element), encoding)


Property changes on: zope.etree/trunk/src/zope/etree/etree.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.etree/trunk/src/zope/etree/interfaces.py
===================================================================
--- zope.etree/trunk/src/zope/etree/interfaces.py	2006-08-25 10:35:09 UTC (rev 69778)
+++ zope.etree/trunk/src/zope/etree/interfaces.py	2006-08-25 10:46:18 UTC (rev 69779)
@@ -0,0 +1,87 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+Zope Element Tree Support
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from zope import interface
+
+class IEtree(interface.Interface):
+
+    def Comment(text = None):
+        """
+        """
+
+    def dump(elem):
+        """
+        """
+
+    def Element(tag, attrib = {}, **extra):
+        """
+        """
+
+    def ElementTree(element = None, file = None):
+        """
+        """
+
+    def XML(text):
+        """
+        """
+
+    def fromstring(text):
+        """
+        """
+
+    def iselement(element):
+        """
+        """
+
+    def iterparse(source, events = None):
+        """
+        """
+
+    def parse(source, parser = None):
+        """
+        """
+
+    def PI(target, text = None):
+        """
+        """
+
+    def ProcessingInstruction(target, text = None):
+        """
+        """
+
+    def QName(text_or_uri, tag = None):
+        """
+        """
+
+    def SubElement(parent, tag, attrib = {}, **extra):
+        """
+        """
+
+    def tostring(element, encoding = None):
+        """
+        """
+
+    def TreeBuilder(element_factory = None):
+        """
+        """
+
+    def XMLTreeBuilder(html = 0, target = None):
+        """
+        """


Property changes on: zope.etree/trunk/src/zope/etree/interfaces.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.etree/trunk/src/zope/etree/testing.py
===================================================================
--- zope.etree/trunk/src/zope/etree/testing.py	2006-08-25 10:35:09 UTC (rev 69778)
+++ zope.etree/trunk/src/zope/etree/testing.py	2006-08-25 10:46:18 UTC (rev 69779)
@@ -0,0 +1,142 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Zope Element Tree Support
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import zope.component
+import zope.app.component
+from zope.configuration import xmlconfig
+from zope.app.testing import setup
+
+from interfaces import IEtree
+import zope.etree
+
+#
+# Setup for Zope etree. 
+#
+
+def etreeSetup(test = None):
+    setup.placelessSetUp()
+    context = xmlconfig.file("meta.zcml", package = zope.app.component)
+    xmlconfig.file("zope.etree-configure.zcml", package = zope.etree,
+                   context = context)
+
+    etreeEtree = zope.component.getUtility(IEtree)
+
+    if test is not None:
+        test.globs["etree"] = etreeEtree
+        test.globs["assertXMLEqual"] = assertXMLEqual
+    return etreeEtree
+
+def etreeTearDown(test = None):
+    if test is not None:
+        del test.globs["etree"]
+        del test.globs["assertXMLEqual"]
+    etreeEtree = zope.component.getUtility(IEtree)
+    zope.component.getGlobalSiteManager().unregisterUtility(etreeEtree)
+
+    setup.placelessTearDown()
+
+#
+# Handy methods for testing if two xml fragmenets are equal.
+#
+
+def _assertTextEqual(got, expected):
+    """
+      >>> _assertTextEqual(None, "\\n")
+      True
+
+      >>> _assertTextEqual("\\n", "\\n")
+      True
+
+      >>> _assertTextEqual("test", "test")
+      True
+
+    """
+    tgot = got and got.strip()
+    texpected = expected and expected.strip()
+
+    error_msg = "'%r != %r' have different element content." %(
+        got, expected)
+
+    if not tgot:
+        assert not texpected, error_msg
+        return True
+
+    if not texpected:
+        assert not tgot, error_msg
+        return True
+
+    assert isinstance(tgot, (str, unicode)), error_msg
+    assert isinstance(texpected, (str, unicode)), error_msg
+
+    assert tgot == texpected, error_msg
+
+    return True
+
+def _assertXMLElementEqual(got, expected):
+    etree = zope.component.getUtility(IEtree)
+
+    assert got.tag == expected.tag, \
+           "'%r != %r' different tag name." %(got.tag, expected.tag)
+    assert len(got) == len(expected), \
+           "'%d != %d' different number of subchildren on %r." %(
+               len(got), len(expected), got.tag)
+    _assertTextEqual(got.text, expected.text)
+
+    for index in range(0, len(got)):
+        _assertXMLElementEqual(got[index], expected[index])
+
+
+def assertXMLEqual(got, expected):
+    """
+      >>> assertXMLEqual('<test>xml</test>', '<test>xml</test>')
+
+      >>> assertXMLEqual('<test>xml</test>', '<test>xml1</test>')
+      Traceback (most recent call last):
+      ...
+      AssertionError: ''xml' != 'xml1'' have different element content.
+
+      >>> assertXMLEqual('<test><subtest>Test</subtest></test>',
+      ...                '<test>Test</test>')
+      Traceback (most recent call last):
+      ...
+      AssertionError: '1 != 0' different number of subchildren on 'test'.
+
+      >>> assertXMLEqual('<test1/>', '<test2/>')
+      Traceback (most recent call last):
+      ...
+      AssertionError: ''test1' != 'test2'' different tag name.
+
+      >>> assertXMLEqual('<a><b><c /></b></a>', '<a><b><c/></b></a>')
+
+    """
+    etree = zope.component.getUtility(IEtree)
+
+    if isinstance(got, (str, unicode)):
+        got = etree.fromstring(got)
+    if isinstance(expected, (str, unicode)):
+        expected = etree.fromstring(expected)
+
+    if getattr(got, "getroot", None) is not None:
+        # XXX - is this all neccessary.
+        got = got.getroot()
+
+        assert getattr(expected, "getroot", None) is not None
+        expected = expected.getroot()
+
+    _assertXMLElementEqual(got, expected)


Property changes on: zope.etree/trunk/src/zope/etree/testing.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.etree/trunk/src/zope/etree/tests.py
===================================================================
--- zope.etree/trunk/src/zope/etree/tests.py	2006-08-25 10:35:09 UTC (rev 69778)
+++ zope.etree/trunk/src/zope/etree/tests.py	2006-08-25 10:46:18 UTC (rev 69779)
@@ -0,0 +1,218 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+Test the ElementTree support within WebDAV. These aren't really tests but
+more of an assertion that I spelt things, like variable names correctly. By
+ust calling the methods here I have managed to find a bunch of bugs :-)
+
+Otherwise I just assume that underlying engine does its job correctly.
+
+$Id$
+"""
+
+import unittest
+import doctest
+from cStringIO import StringIO
+
+from zope.interface.verify import verifyObject
+from zope import component
+from zope.etree import etree
+from interfaces import IEtree
+from testing import etreeSetup, etreeTearDown
+
+
+class BaseEtreeTestCase(unittest.TestCase):
+
+    def test_interface(self):
+        self.assertEqual(verifyObject(IEtree, self.etree), True)
+
+    def test_comment(self):
+        comment = self.etree.Comment(u"some text")
+
+    def test_etree(self):
+        etree = self.etree.ElementTree()
+
+    def test_XML(self):
+        xml = self.etree.XML(u"<p>some text</p>")
+
+    def test_fromstring(self):
+        xml = self.etree.fromstring(u"<p>some text</p>")
+
+    def test_element(self):
+        elem = self.etree.Element(u"testtag")
+
+    def test_iselement(self):
+        elem = self.etree.Element(u"testtag")
+        iselem = self.etree.iselement(elem)
+        self.assert_(iselem, "Not an element")
+
+    def test_parse(self):
+        f = StringIO("<b>Test Source String</b>")
+        self.etree.parse(f)
+
+    def test_qname(self):
+        qname = self.etree.QName("http://example.namespace.org", "test")
+
+    def test_tostring(self):
+        elem = self.etree.Element(u"testtag")
+        string = self.etree.tostring(elem, "ascii")
+        self.assert_(isinstance(string, str), "Not a string")
+
+    def test_treeBuilder(self):
+        self.assertRaises(NotImplementedError, self.etree.TreeBuilder)
+
+    def test_subelement(self):
+        elem = self.etree.Element(u"testtag")
+        subel = self.etree.SubElement(elem, "foo")
+
+    def test_PI(self):
+        pi = self.etree.PI("sometarget")
+
+    def test_processinginstructions(self):
+        pi = self.etree.ProcessingInstruction("sometarget")
+
+    def test_xmltreebulider(self):
+        builder = self.etree.XMLTreeBuilder()
+
+
+class OrigElementTreeTestCase(BaseEtreeTestCase):
+
+    def setUp(self):
+        from zope.etree.etree import EtreeEtree
+        self.etree = EtreeEtree()
+
+    def tearDown(self):
+        del self.etree
+
+
+class LXMLElementTreeTestCase(BaseEtreeTestCase):
+
+    def setUp(self):
+        from zope.etree.etree import LxmlEtree
+        self.etree = LxmlEtree()
+
+    def tearDown(self):
+        del self.etree
+
+    def test_PI(self):
+        self.assertRaises(NotImplementedError, self.etree.PI, "sometarget")
+
+    def test_processinginstructions(self):
+        self.assertRaises(NotImplementedError,
+                          self.etree.ProcessingInstruction, "sometarget")
+
+    def test_xmltreebulider(self):
+        self.assertRaises(NotImplementedError, self.etree.XMLTreeBuilder)
+
+    def test_namespaces(self):
+        # When we have a element whoes namespace declaration is declared
+        # in a parent element lxml doesn't print out the namespace
+        # declaration by default.
+        multinselemstr = """<D:prop xmlns:D="DAV:"><D:owner><H:href xmlns:H="examplens">http://example.org</H:href></D:owner></D:prop>"""
+        multinselem = self.etree.fromstring(multinselemstr)
+        self.assertEqual(self.etree.tostring(multinselem[0]),
+                         """<D:owner xmlns:D="DAV:"><H:href xmlns:H="examplens">http://example.org</H:href></D:owner>""")
+
+
+class Python25ElementTreeTestCase(BaseEtreeTestCase):
+
+    def setUp(self):
+        from zope.etree.etree import EtreePy25
+        self.etree = EtreePy25()
+
+    def tearDown(self):
+        del self.etree
+
+
+class NoElementTreePresentTestCase(unittest.TestCase):
+    # If no element tree engine exists then run this test case. Which will
+    # mark the current instance has broken.
+
+    def test_warn(self):
+        self.fail("""
+        WARNING: zope.etree needs ElementTree installed in order to run.
+        """)
+
+
+class doctestSetup(object):
+
+    def __init__(self, etree):
+        self.etree = etree
+
+    def __call__(self, test):
+        component.getGlobalSiteManager().registerUtility(self.etree)
+        test.globs["etree"] = self.etree
+
+
+def doctestTeardown(test):
+    component.getGlobalSiteManager().unregisterUtility(test.globs["etree"])
+    del test.globs["etree"]
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+
+    # Only run the tests for each elementtree that is installed.
+    foundetree = False
+    try:
+        import elementtree
+        suite.addTest(unittest.makeSuite(OrigElementTreeTestCase))
+        suite.addTest(doctest.DocTestSuite(
+            "zope.etree.testing",
+            optionflags = doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE,
+            setUp = doctestSetup(etree.EtreeEtree()),
+            tearDown = doctestTeardown))
+        foundetree = True
+    except ImportError:
+        pass
+
+    try:
+        import lxml.etree
+        suite.addTest(unittest.makeSuite(LXMLElementTreeTestCase))
+        suite.addTest(doctest.DocTestSuite(
+            "zope.etree.testing",
+            optionflags = doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE,
+            setUp = doctestSetup(etree.LxmlEtree()),
+            tearDown = doctestTeardown))
+        foundetree = True
+    except ImportError:
+        pass
+
+    try:
+        import xml.etree
+        suite.addTest(unittest.makeSuite(Python25ElementTreeTestCase))
+        suite.addTest(doctest.DocTestSuite(
+            "zope.etree.testing",
+            optionflags = doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE,
+            setUp = doctestSetup(etree.EtreePy25()),
+            tearDown = doctestTeardown))
+        foundetree = True
+    except ImportError:
+        pass
+
+    if not foundetree:
+        suite.addTest(unittest.makeSuite(NoElementTreePresentTestCase))
+    else:
+        # rerun the current testing doctest using the default setUp
+        suite.addTest(doctest.DocTestSuite(
+            "zope.etree.testing",
+            optionflags = doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE,
+            setUp = etreeSetup,
+            tearDown = etreeTearDown))
+
+        # run the README tests to make the documentation does something
+        suite.addTest(doctest.DocFileSuite(
+            "README.txt", package = "zope.etree"))
+
+    return suite


Property changes on: zope.etree/trunk/src/zope/etree/tests.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.etree/trunk/src/zope/etree/zope.etree-configure.zcml
===================================================================
--- zope.etree/trunk/src/zope/etree/zope.etree-configure.zcml	2006-08-25 10:35:09 UTC (rev 69778)
+++ zope.etree/trunk/src/zope/etree/zope.etree-configure.zcml	2006-08-25 10:46:18 UTC (rev 69779)
@@ -0,0 +1,35 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <!--
+      ElementTree support for Zope (you probable what to edit this)
+
+      This file also configures which ElementTree engine to use for all the
+      zope.etree unit tests also. See the README.txt file.
+    -->
+
+  <!--
+      uses the *elementtree* module.
+    -->
+  <utility
+     factory="zope.etree.etree.EtreeEtree"
+     />
+
+  <!--
+      uses the *lxml* module.
+    -->
+<!--
+  <utility
+     factory="zope.etree.etree.LxmlEtree"
+     />
+-->
+
+  <!--
+      uses the ElementTree module from Python 2.5 standard library.
+    -->
+<!--
+  <utility
+     factory="zope.etree.etree.EtreePy25"
+     />
+-->
+
+</configure>


Property changes on: zope.etree/trunk/src/zope/etree/zope.etree-configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the Checkins mailing list