[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