[zopeorg-checkins] CVS: Products/ParsedXML/tests - README:1.1 __init__.py:1.1 domloader.py:1.1 domtester.py:1.1 profParse.py:1.1 profPrinter.py:1.1 profPyXMLParse.py:1.1 profPyXMLPrinter.py:1.1 test_ODB.py:1.1 test_acquisition.py:1.1 test_all.py:1.1 test_aqpain.py:1.1 test_collection.py:1.1 test_dom.py:1.1 test_elementid.py:1.1 test_parser.py:1.1 test_persistence.py:1.1 test_prettyprinter.py:1.1 test_printer.py:1.1 test_pyxmldom.py:1.1 test_truthable.py:1.1 test_wrappeddom.py:1.1 test_zopeinterface.py:1.1

Sidnei da Silva sidnei at x3ng.com.br
Fri May 30 11:17:34 EDT 2003


Update of /cvs-zopeorg/Products/ParsedXML/tests
In directory cvs.zope.org:/tmp/cvs-serv19195/ParsedXML/tests

Added Files:
	README __init__.py domloader.py domtester.py profParse.py 
	profPrinter.py profPyXMLParse.py profPyXMLPrinter.py 
	test_ODB.py test_acquisition.py test_all.py test_aqpain.py 
	test_collection.py test_dom.py test_elementid.py 
	test_parser.py test_persistence.py test_prettyprinter.py 
	test_printer.py test_pyxmldom.py test_truthable.py 
	test_wrappeddom.py test_zopeinterface.py 
Log Message:
Adding products needed for migration of NZO

=== Added File Products/ParsedXML/tests/README ===
Parsed XML test README

Using the test suite

 This directory holds our test suite.  Usually, it can be invoked with
 "python domtester.py".  Appending an -h argument will return a usage
 string. 

 To run the domtester, you need to be able to find Zope's unit testing
 framework and mount the ZODB, so you need to make sure Zope's lib/python
 can be found. Adding Zope's lib/python to your python path, either
 going through sys.path or adding it to the PYTHONPATH environment variable.
 For instance, if you're running bash, all you have to type is this::

   export PYTHONPATH=/path/to/Zope/lib/python

 The ZODB must also be mountable, so if you're not running ZEO, the
 server must be stopped while the tests run.

 Upon completion, the tester will report how many tests failed, and
 put more detailed output in out.txt.

Running tests individually

 You can also run each test individually, for instance::

   python test_dom.py

 Again you have to make sure Zope's lib/python can be found.

 There's also a very simple test_all.py that runs all the individual
 tests in a row; doing the same thing as domtester.py does but without
 some of the conveniences.

Debugging with the test suite

 If you want to contribute changes to ParsedXML, please run the test
 suite to make sure that your changes don't break anything.

 The tests themselves are in test_domapi.py.

 The test suite checks for compliance with the Python IDL mapping with
 the DOM specification.  As of this writing nearly all of DOM level 2
 is tested, along with a few level 3 interfaces.

 Some Parsed XML specific tests are run as well, if the implementation
 supports those features, such as persistence, parsing, and printing.

 The suite is very useful for testing extensions to Parsed XML that
 provide full DOM capabilities.  We run the tests on both our
 ManageableDOM and DOM layers - if it works for DOM, it should work
 for ManageableDOM, which proxies the entire DOM interface.


=== Added File Products/ParsedXML/tests/__init__.py ===
# make this a package 



=== Added File Products/ParsedXML/tests/domloader.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################


from Products.ParsedXML.DOM import ExpatBuilder

def main():
    import getopt
    import sys

    namespaces = 0
    opts, args = getopt.getopt(sys.argv[1:], "n")
    if opts:
        namespaces = 1
    if args:
        file = args[0]
    else:
        file = sys.stdin
    doc = ExpatBuilder.parse(file, namespaces=namespaces)
    print doc
    for node in doc.documentElement.childNodes:
        print (node.nodeType, node.nodeName,
               (node.namespaceURI, node.localName), node.nodeValue)

if __name__ == "__main__":
    main()


=== Added File Products/ParsedXML/tests/domtester.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################

USAGE = '''\
%(program)s -- Test script for DOM implementations.

usage: %(program)s [-h] [implementations...]

Parameters:
    -g      Use the Tkinter GUI from unittestgui, if available.

    -h      Print this help text.

    -x      Treat the list of tests as tests to exclude rather than include.

    tests   List of tests to execute.  By default, all known testcases are run.
            Known tests include:

            - DOM          the basic DOM
            - ParsedXML    the persistent/wrapped Zope DOM
            - Printer      the DOM-to-XML Printer
            - Parser       the Expat parser and DOM builder
            - Persistence  persistence of the managed DOM
            - Truthable    checks for truth tests
            - Acquisition  checks for acquisition-related integrity failure
'''

import getopt
import os
import sys
import imp
import unittest
import Products.ParsedXML

impls = (
    ('DOM',             'test_dom'),
    ('ParsedXML',       'test_wrappeddom'),
    ('Printer',         'test_printer'),
    ('Parser',          'test_parser'),
    ('Persistence',     'test_persistence'),
    ('Truthable',       'test_truthable'),
    ('UserAcquisition', 'test_acquisition'),
    # known parenting bug, also causes errors in DOM tests
    ('Acquisition',     'test_aqpain'),
    ('ZopeInterface',   'test_zopeinterface'),
# FIXME: this is causing a segfault with debian's python 2.1, though
# not with a manually compiled python.. need to look into this 
#    ('Refcounts',       'test_collection'),
    ('ODB',             'test_ODB'),
    ('elementId',       'test_elementid'),
    )

def main():
    program = os.path.basename(sys.argv[0])
    impls_to_exclude = None
    gui = 0
    try:
        opts, impls_to_test = getopt.getopt(
            sys.argv[1:], "dghx", ["disable-gc", "gui", "help", "exclude"])
    except getopt.error:
        sys.stdout = sys.stderr
        print USAGE % {"program": program}
        sys.exit(2)
    for opt, arg in opts:
        if opt in ("-x", "--exclude"):
            impls_to_exclude = impls_to_test
            impls_to_test = []
        elif opt in ("-d", "--disable-gc"):
            try:
                import gc
            except ImportError:
                # nothing to disable
                pass
            else:
                gc.disable()
        elif opt in ("-g", "--gui"):
            gui = 1
        elif opt in ("-h", "--help"):
            print USAGE % {"program": program}
            sys.exit()

    # Make a backup, so you can see differences between runs.
    if os.path.exists('out.txt'):
        if os.path.exists('out.txt.bak'):
            os.unlink('out.txt.bak')
        os.rename('out.txt', 'out.txt.bak')
    
    if gui:
        run_tests = run_tests_gui
    else:
        run_tests = run_tests_text

    if run_tests(impls_to_test, impls_to_exclude):
        sys.exit(1)


def run_tests_gui(include, exclude):
    try:
        import unittestgui
    except ImportError:
        sys.stderr.write(
            "unittestgui module not installed; install that module from\n"
            "PyUNIT and try again.\n")
        return 1
    else:
        unittestgui.main("__main__.all_suites")
        return 0


def run_tests_text(include, exclude):
    errs = 0
    outf = open("out.txt", "w")
    stdout = sys.stdout

    for implname, filename in impls:
        if include and implname not in include:
            continue
        elif exclude and implname in exclude:
            continue

        sys.stdout = outf
        print "===== %s =====\n" % implname

        try:
            # Import test file and retrieve test suite.
            testSuite = load_suite(filename)
            errs = errs + run_suite(testSuite, implname, outf)
        finally:
            sys.stdout = stdout

    outf.close()
    return errs


def load_suite(filename):
    path = os.path.join(sys.modules['Products.ParsedXML'].__path__[0],
                        'tests')
    file, pathname, desc = imp.find_module(filename, [path])
    module = imp.load_module(filename, file, pathname, desc)
    file.close()
    return module.test_suite()


def all_suites():
    suite = unittest.TestSuite()
    for name, module in impls:
        suite.addTest(load_suite(module))
    return suite


def run_suite(testSuite, implname, outf=None):
    if outf is None:
        outf = sys.stdout
    if hasattr(unittest, 'JUnitTextTestRunner'):
        # Prefer the non-verbose version.
        runner = unittest.JUnitTextTestRunner(outf)
    else:
        runner = unittest.TextTestRunner(outf)

    result = runner.run(testSuite)

    print "\n\n"
    if result.errors:
        print "Errors:"
        map(print_error, result.errors)
        print
    if result.failures:
        print "Failures:"
        map(print_error, result.failures)
        print
    newerrs = len(result.errors) + len(result.failures)
    if newerrs:
        sys.stderr.write("%s: %d errors, %d failures\n"
                         % (implname, len(result.errors),
                            len(result.failures)))
    return newerrs


def print_error(info):
    testcase, (type, e, tb) = info
    print "  %s.%s.%s" % (testcase.__class__.__module__,
                          testcase.__class__.__name__,
                          tb.tb_frame.f_code.co_name)


if __name__ == "__main__":
    main()


=== Added File Products/ParsedXML/tests/profParse.py ===
#! /usr/bin/env python1.5

import getopt
import os
import profile
import pstats
import sys

from Products.ParsedXML.DOM import Core, ExpatBuilder

FILE = os.path.join(sys.modules['Products.ParsedXML'].__path__[0],
    'tests', 'xml', '4ohn4ktj.xml')
PROFILEDATA = "@parsefile.prof"


def parsefile(filename, namespaces):
    ExpatBuilder.parse(filename, namespaces=namespaces)

_getattr_counts = {}

def main():
    namespaces = 1
    profiledata = None
    proflines = 20
    filename = FILE
    opts, args = getopt.getopt(sys.argv[1:], "nd:p:")
    for opt, arg in opts:
        if opt == "-n":
            namespaces = not namespaces
        elif opt == "-p":
            proflines = int(arg)
        elif opt == "-d":
            profiledata = arg
    if len(args) >= 2:
        print "One file at a time, please!"
        sys.exit(2)
    elif args:
        filename = args[0]

    profile.run('parsefile(%s, %s)' % (`filename`, namespaces),
                profiledata or PROFILEDATA)
    p = pstats.Stats(profiledata or PROFILEDATA)
    p.strip_dirs().sort_stats('time').print_stats(proflines)
    #p.print_callers(proflines)
    #p.strip_dirs().sort_stats('cum').print_stats(proflines)
    if not profiledata:
        os.unlink(PROFILEDATA)


if __name__ == "__main__":
    main()


=== Added File Products/ParsedXML/tests/profPrinter.py ===
import getopt
import os
import profile
import pstats
import sys

from Products.ParsedXML.DOM import Core, ExpatBuilder
from Products.ParsedXML.ExtraDOM import writeStream


FILE = os.path.join(sys.modules['Products.ParsedXML'].__path__[0],
    'tests', 'xml', '4ohn4ktj.xml')
PROFILEDATA = "@parsefile.prof"


def parsefile(filename, namespaces):
    return ExpatBuilder.parse(filename, namespaces=namespaces)

def printDOM(document):
    writeStream(document)


_getattr_counts = {}

def main():
    namespaces = 1
    profiledata = None
    proflines = 20
    filename = FILE
    opts, args = getopt.getopt(sys.argv[1:], "nd:p:")
    for opt, arg in opts:
        if opt == "-n":
            namespaces = not namespaces
        elif opt == "-p":
            proflines = int(arg)
        elif opt == "-d":
            profiledata = arg
    if len(args) >= 2:
        print "One file at a time, please!"
        sys.exit(2)
    elif args:
        filename = args[0]

    doc = parsefile(filename, namespaces)
    profiler = profile.Profile()
    profiler.runctx('printDOM(doc)', locals(), globals())
    profiler.dump_stats(profiledata or PROFILEDATA)
    p = pstats.Stats(profiledata or PROFILEDATA)
    p.strip_dirs().sort_stats('time').print_stats(proflines)
    #p.print_callers(proflines)
    #p.strip_dirs().sort_stats('cum').print_stats(proflines)
    if not profiledata:
        os.unlink(PROFILEDATA)


if __name__ == "__main__":
    main()


=== Added File Products/ParsedXML/tests/profPyXMLParse.py ===
import getopt
import os
import profile
import pstats
import sys
import Products.ParsedXML
from xml.dom.ext.reader import PyExpat

FILE = os.path.join(sys.modules['Products.ParsedXML'].__path__[0],
    'tests', 'xml', '4ohn4ktj.xml')
PROFILEDATA = "@parsefile.prof"

def parsefile(filename, namespaces):
    if not namespaces:
        print "PyXML reader only parses with namespaces"
        sys.exit(2)
    reader = PyExpat.Reader()
    return reader.fromUri(filename)

_getattr_counts = {}

def main():
    namespaces = 1
    profiledata = None
    proflines = 20
    filename = FILE
    opts, args = getopt.getopt(sys.argv[1:], "nd:p:")
    for opt, arg in opts:
        if opt == "-n":
            namespaces = not namespaces
        elif opt == "-p":
            proflines = int(arg)
        elif opt == "-d":
            profiledata = arg
    if len(args) >= 2:
        print "One file at a time, please!"
        sys.exit(2)
    elif args:
        filename = args[0]

    profile.run('parsefile(%s, %s)' % (`filename`, namespaces),
                profiledata or PROFILEDATA)
    p = pstats.Stats(profiledata or PROFILEDATA)
    p.strip_dirs().sort_stats('time').print_stats(proflines)
    #p.print_callers(proflines)
    #p.strip_dirs().sort_stats('cum').print_stats(proflines)
    if not profiledata:
        os.unlink(PROFILEDATA)


if __name__ == "__main__":
    main()


=== Added File Products/ParsedXML/tests/profPyXMLPrinter.py ===
import getopt
import os
import profile
import pstats
import sys

from Products.ParsedXML.ExtraDOM import writeStream

FILE = os.path.join(sys.modules['Products.ParsedXML'].__path__[0],
    'tests', 'xml', '4ohn4ktj.xml')
PROFILEDATA = "@parsefile.prof"


def parsefile(filename, namespaces):
    from xml.dom.ext.reader import PyExpat    
    reader = PyExpat.Reader()
    return reader.fromUri(filename)
    

def printDOM(document):
    writeStream(document)


_getattr_counts = {}

def main():
    namespaces = 1
    profiledata = None
    proflines = 20
    filename = FILE
    opts, args = getopt.getopt(sys.argv[1:], "nd:p:")
    for opt, arg in opts:
        if opt == "-n":
            namespaces = not namespaces
        elif opt == "-p":
            proflines = int(arg)
        elif opt == "-d":
            profiledata = arg
    if len(args) >= 2:
        print "One file at a time, please!"
        sys.exit(2)
    elif args:
        filename = args[0]

    doc = parsefile(filename, namespaces)
    profiler = profile.Profile()
    profiler.runctx('printDOM(doc)', locals(), globals())
    profiler.dump_stats(profiledata or PROFILEDATA)
    p = pstats.Stats(profiledata or PROFILEDATA)
    p.strip_dirs().sort_stats('time').print_stats(proflines)
    #p.print_callers(proflines)
    #p.strip_dirs().sort_stats('cum').print_stats(proflines)
    if not profiledata:
        os.unlink(PROFILEDATA)


if __name__ == "__main__":
    main()


=== Added File Products/ParsedXML/tests/test_ODB.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################
"Test some ODB interactions."

import unittest
import ZODB # for Persistent
from Products.ParsedXML import ParsedXML

class ODBTestCase(unittest.TestCase):

    def setUp(self):
        self.document = ParsedXML.ParsedXML('foo')

    def shotgunTpStuff(self, node):
        "assert that the Tp* functions work"
        children = node.childNodes
        tpVals = node.tpValues()

        for i in range(children.length):
            assert children.item(i).isSameNode(tpVals[i])
            
        for i in range(children.length):
            assert children.item(i).tpURL() == str(i)
            assert children.item(i).tpId() == str(i)

        for node in tpVals:
            self.shotgunTpStuff(node)
        
    def checkTpStuff(self):
        "check that the Tp* functions work"
        self.document.documentElement.appendChild(
            self.document.createElement('zero'))
        self.document.documentElement.appendChild(
            self.document.createElement('one'))
        self.document.documentElement.firstChild.appendChild(
            self.document.createElement('zero-zero'))
        self.document.documentElement.firstChild.appendChild(
            self.document.createElement('zero-one'))

        self.shotgunTpStuff(self.document.documentElement)        

def test_suite():
    """Return a test suite for the Zope testing framework."""
    
    return unittest.makeSuite(ODBTestCase, 'check')

def main():
    unittest.TextTestRunner().run(test_suite())
    
if __name__ == '__main__':
    main()


=== Added File Products/ParsedXML/tests/test_acquisition.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################
"test that the ParsedXML DOM object acquire implicitly"

# this suite isn't done that well.  We could probably just mount a db.

# We currently have to have a Zope instance
# to mount; we need a persistent container & Zope traversal to acquire
# properly, because we don't want to acquire through the transient
# proxy objects.

import unittest
import ZODB # for Persistent
from Products.ParsedXML import ParsedXML

def checkAcquire(aqer, aqee, name):
    "check that acquisition of name from aqee to aqer happens"
    assert hasattr(aqer, name)
    assert getattr(aqer, name) == getattr(aqee, name)
    assert getattr(aqer, name) is getattr(aqee, name)

def checkAcquireNot(aqer, aqee, name):
    "check that acquisition of name from aqee to aqer doesn't happen"
    assert getattr(aqer, name) != getattr(aqee, name)
    assert getattr(aqer, name) is not getattr(aqee, name)


class WrappedAcquisitionTestCase(unittest.TestCase):

    def setUp(self):
        # we need a doc in a container that supports
        # restrictedTraverse and getPhysicalPath to have a proper
        # acquisition chain.
        import OFS.Application
        self.app = OFS.Application.Application()
        self.tmpId = 'TempParsedXMLUnitTestInstance'
        self.app._setObject(self.tmpId, ParsedXML.ParsedXML(self.tmpId))
        self.doc = getattr(self.app, self.tmpId)
        
        self.app.string = 'a string'
        self.app.firstChild = "a string that shouldn't be acquired"

        elt1 = self.doc.createElement('eggs')
        elt2 = self.doc.createElement('ham')
        self.doc.documentElement.appendChild(elt1)
        self.doc.documentElement.appendChild(elt2)
        self.doc.documentElement.setAttribute('color', 'green')

    def _acquisitionTest(self, DOMObj):
        checkAcquire(DOMObj, self.app, 'string')
        checkAcquireNot(DOMObj, self.app, 'firstChild')

    def checkTraversalAcquisition(self):
        "make sure we can acquire through DOM traversal"
        self._acquisitionTest(self.doc)
        self._acquisitionTest(self.doc.documentElement)
        self._acquisitionTest(self.doc.documentElement.firstChild)
        self._acquisitionTest(self.doc.documentElement.firstChild.nextSibling)
        self._acquisitionTest(self.doc.documentElement.ownerDocument)
        self._acquisitionTest(self.doc.documentElement.getAttributeNode(
            'color'))

    def checkMethodAcquisition(self):
        "make sure we acquire through proxied DOM methods"
        elt = self.doc.createElement('foo')
        self._acquisitionTest(self.doc.documentElement.appendChild(elt))

    def checkNodeListAcquisition(self):
        "make sure we can acquire through a NodeList"
        self._acquisitionTest(self.doc.documentElement.childNodes.item(0))

    def checkNamedNodeMapAcquisition(self):
        "make sure we can acquire through a NamedNodeMap"
        self._acquisitionTest(
            self.doc.documentElement.attributes.getNamedItem('color'))

                
def test_suite():
    """Return a test suite for the Zope testing framework."""

    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(WrappedAcquisitionTestCase, 'check'))
    return suite

def main():
    unittest.TextTestRunner().run(test_suite())

if __name__ == "__main__":
    main()


=== Added File Products/ParsedXML/tests/test_all.py ===
import unittest

from Products.ParsedXML.tests import test_dom
from Products.ParsedXML.tests import test_wrappeddom
from Products.ParsedXML.tests import test_printer
from Products.ParsedXML.tests import test_parser
from Products.ParsedXML.tests import test_persistence
from Products.ParsedXML.tests import test_truthable
from Products.ParsedXML.tests import test_acquisition
from Products.ParsedXML.tests import test_aqpain
from Products.ParsedXML.tests import test_zopeinterface
from Products.ParsedXML.tests import test_collection
from Products.ParsedXML.tests import test_ODB
from Products.ParsedXML.tests import test_elementid
 
def test_suite():
    suite = unittest.TestSuite()
    suite.addTest(test_dom.test_suite())
    suite.addTest(test_wrappeddom.test_suite())
    suite.addTest(test_printer.test_suite())
    suite.addTest(test_parser.test_suite())
    suite.addTest(test_persistence.test_suite())
    suite.addTest(test_truthable.test_suite())
    suite.addTest(test_acquisition.test_suite())
    suite.addTest(test_aqpain.test_suite())
    suite.addTest(test_zopeinterface.test_suite())
    suite.addTest(test_collection.test_suite())
    suite.addTest(test_ODB.test_suite())
    suite.addTest(test_elementid.test_suite())
    return suite

def main():
    if hasattr(unittest, 'JUnitTextTestRunner'):
        unittest.JUnitTextTestRunner().run(test_suite())
    else:
        unittest.TextTestRunner(verbosity=0).run(test_suite())

if __name__ == '__main__':
    main()






=== Added File Products/ParsedXML/tests/test_aqpain.py ===
"""Test that checks the fragility of using acquistion wrappers to
indicate tree hierarchy.

The current implementation of the DOM uses acquisition wrappers to
store references to a node's parent node.  While this allows very
efficient access to the parent, it is fragile in the case of multiple
wrappers referring to the same node.  If client code holds two
wrappers for a node and modifies the node's position in the tree using
one of them, the other will store incorrect information on the shape
of the tree.

For acquisition to be used to adequately be used to present the
containment hierarchy for a node, a complete chain of wrappers would
need to be constructed each time a node is reparented, starting from
the outermost node in the ancestor chain.  Application code would need
to be wary that old references to a node are replaced by the new
wrapper.  The Python DOM API makes no such requirement at the present
time, nor should it need to.

This script shows a contrived example that exercises this DOM bug.
While this particular code is unlikely in real applications, the ease
with which multiple acquisition wrappers can be produced in more
complex application code is easy to see.

"""

import unittest

from Products.ParsedXML.DOM.ExpatBuilder import ExpatBuilder
from Products.ParsedXML.Printer import PrintVisitor

class AcquisitionPain(unittest.TestCase):

    def setUp(self):
        self.doc = ExpatBuilder().parseString("<doc><e1/><e2/></doc>")
        self.printer = PrintVisitor(self.doc)

    def checkParentReferenceIntegrity(self):
        e1a = self.doc.documentElement.firstChild
        e1b = self.doc.documentElement.firstChild
        e2 = e1b.nextSibling
        e2.appendChild(e1b)
        assert e1a.parentNode.isSameNode(e1b.parentNode), \
               "Two references to the same node return different parent nodes."

def test_suite():
    """Return a test suite for the Zope testing framework."""

    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(AcquisitionPain, 'check'))
    return suite

def main():
    unittest.TextTestRunner().run(test_suite())

if __name__ == "__main__":
    main()


=== Added File Products/ParsedXML/tests/test_collection.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################
"Tests for garbage collection."

import unittest
import ZODB # for Persistent
import os
import string
import sys

from Products.ParsedXML import ParsedXML, DOM

import App.ApplicationManager

class ReferenceTestCase(unittest.TestCase):

    def setUp(self):
        self.dbman = App.ApplicationManager.DebugManager() 

    def getRefcounts(self, ob):
        "return number of refcounts for instances of ob's class"
        name = '%s.%s' % (ob.__module__, ob.__class__.__name__)
        for i in self.dbman.refcount():
            if i[1] == name:
                return i[0]
        return 0

    def checkParsedXMLCollect(self):
        "see if refcounts from ParsedXML product init are released"
        doc = ParsedXML.ParsedXML('foo')
        refcounts1 = self.getRefcounts(doc)
        doc = ParsedXML.ParsedXML('foo')
        refcounts2 = self.getRefcounts(doc)
        assert refcounts2 == refcounts1, (
            "ParsedXML leaked %d refcounts" % (refcounts2 - refcounts1))

    def checkDOMParseCollect(self):
        "see if refcounts from DOM parse creation are released"
        testDir = os.path.join(
            sys.modules['Products.ParsedXML'].__path__[0],
            'tests')
        filename = os.path.join(testDir, 'xml', '4ohn4ktj.xml')
        doc = DOM.ExpatBuilder.parse(filename)
        refcounts1 = self.getRefcounts(doc)
        doc = DOM.ExpatBuilder.parse(filename)        
        refcounts2 = self.getRefcounts(doc)
        assert refcounts2 == refcounts1, (
            "DOM parse leaked %d refcounts" % (refcounts2 - refcounts1))

    def checkDOMCreateCollect(self):
        "see if refcounts from DOM creation are released"
        doc = DOM.theDOMImplementation.createDocument(None, 'doc', None)
        refcounts1 = self.getRefcounts(doc)
        doc = DOM.theDOMImplementation.createDocument(None, 'doc', None)
        refcounts2 = self.getRefcounts(doc)
        assert refcounts2 == refcounts1, (
            "DOM parse leaked %d refcounts" % (refcounts2 - refcounts1))

def test_suite():
    """Return a test suite for the Zope testing framework."""

    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(ReferenceTestCase, 'check'))
    return suite

def main():
    unittest.TextTestRunner().run(test_suite())

if __name__ == "__main__":
    main()


=== Added File Products/ParsedXML/tests/test_dom.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################

import unittest
from Products.ParsedXML import DOM
from Products.ParsedXML.DOM import ExpatBuilder
from Products.ParsedXML.StrIO import StringIO
from domapi import DOMImplementationTestSuite

def DOMParseString(self, xml):
    file = StringIO(xml)
    return ExpatBuilder.parse(file)

def test_suite():
    """Return a test suite for the Zope testing framework."""
    return DOMImplementationTestSuite(DOM.theDOMImplementation, DOMParseString)

def main():
    unittest.TextTestRunner().run(test_suite())

if __name__ == '__main__':
    main()





=== Added File Products/ParsedXML/tests/test_elementid.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################

import unittest

from Products.ParsedXML import DOM
from Products.ParsedXML.DOM import ExpatBuilder
from Products.ParsedXML.StrIO import StringIO
from domapi import DOMImplementationTestSuite

def DOMParseString(xml):
    file = StringIO(xml)
    return ExpatBuilder.parse(file)

def get_element_ids(node):
    result = []
    if node.nodeType == node.ELEMENT_NODE:
        result.append(node.elementId)
    for child in node.childNodes:
        result.extend(get_element_ids(child))
    return result

def check_unique_ids(node):
    element_ids = get_element_ids(node)
    element_ids.sort()
    last = element_ids[0]
    for element_id in element_ids[1:]:
        assert last != element_id,\
               'Found at least one double element_id: %s' % element_id
        last = element_id

class ElementIdTestCase(unittest.TestCase):
    def setUp(self):
        self.doc = DOMParseString('''
        <doc>
        <p>Test</p>
        <p>Another test</p>
        <p>Foo<sub/><sub2>hey</sub2></p>
        </doc>
        ''')

    def checkElementIdsAfterParse(self):
        element_ids = get_element_ids(self.doc)
        for i in xrange(len(element_ids)):
            assert i == element_ids[i]
            
    def checkElementIdsAfterAppend(self):
        element = self.doc.createElement('foo')
        self.doc.documentElement.appendChild(element)
        check_unique_ids(self.doc)

    def checkElementIdsAfterAppend2(self):
        element = self.doc.createElement('foo')
        self.doc.documentElement.insertBefore(
            element, self.doc.documentElement.childNodes[0])
        check_unique_ids(self.doc)

    def checkCloneNodeShallow(self):
        cloned = self.doc.documentElement.cloneNode(0)
        self.doc.documentElement.appendChild(cloned)
        check_unique_ids(self.doc)

    def checkCloneNodeDeep(self):
        cloned = self.doc.documentElement.cloneNode(1)
        self.doc.documentElement.appendChild(cloned)
        check_unique_ids(self.doc)

    def checkImportNodeShallow(self):
        otherdoc = DOMParseString('''
        <hey><some></some></hey>
        ''')
        imported = self.doc.importNode(
            otherdoc.documentElement, 0)
        self.doc.documentElement.appendChild(imported)
        check_unique_ids(self.doc)
        
    def checkImportNodeDeep(self):
        otherdoc = DOMParseString('''
        <hey><some></some></hey>
        ''')
        imported = self.doc.importNode(
            otherdoc.documentElement, 1)
        self.doc.documentElement.appendChild(imported)
        check_unique_ids(self.doc)
        
    
def test_suite():
    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(ElementIdTestCase, 'check'))
    return suite

def main():
    unittest.TextTestRunner().run(test_suite())

if __name__ == "__main__":
    main()


=== Added File Products/ParsedXML/tests/test_parser.py === (451/551 lines abridged)
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment

[-=- -=- -=- 451 lines omitted -=- -=- -=-]


    def checkXMLNSPrefixParse(self):
        "check that xmlns prefix attrs are parsed properly"
        inStr = '<doc xmlns:spamNS="uri:test_namespace"/>'
        doc = ParsedXML.ParsedXML('foo', inStr)
        attr = doc.documentElement.attributes.item(0)
        checkAttribute(attr, 'prefix', 'xmlns')
        checkAttribute(attr, 'localName', 'spamNS')
        checkAttribute(attr, 'namespaceURI', 'http://www.w3.org/2000/xmlns/')
        checkAttribute(attr, 'value', 'uri:test_namespace')        

    def checkXMLNSParse(self):
        "check that xmlns attrs are parsed properly"
        inStr = '<doc xmlns="uri:test_namespace"/>'
        doc = ParsedXML.ParsedXML('foo', inStr)
        attr = doc.documentElement.attributes.item(0)
        checkAttribute(attr, 'prefix', 'xmlns')
        checkAttribute(attr, 'localName', None)
        checkAttribute(attr, 'namespaceURI', 'http://www.w3.org/2000/xmlns/')
        checkAttribute(attr, 'value', 'uri:test_namespace')        

    def checkNoNSParse(self):
        """check that attrs parsed with no NS but with NS aware parse
        can be retrieved with NS of None"""
        inStr = '<doc version="1.0"/>'
        doc = ParsedXML.ParsedXML('foo', inStr)
        assert doc.documentElement.getAttributeNS(None, 'version'), (
            "NS-free attribute not gotten by NS-free getAttributeNS")

def test_suite():
    """Return a test suite for the Zope testing framework."""

    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(ParseOasisXMLTestSaTestCase, 'check'))
    suite.addTest(unittest.makeSuite(ParseTestCase, 'check'))
    suite.addTest(unittest.makeSuite(Lvl2ParseTestCase, 'check'))
    return suite

def main():
    unittest.TextTestRunner(verbosity=3).run(test_suite())

if __name__ == "__main__":
    main()









=== Added File Products/ParsedXML/tests/test_persistence.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################

# DB stuff copied from testBTrees.py

import unittest
import ZODB # for Persistent
import glob
import os
import sys

from Products.ParsedXML import ParsedXML
from Products.ParsedXML.StrIO import StringIO

import unittest

class PersistenceTestCase(unittest.TestCase):

    implementation = ParsedXML.theDOMImplementation

    def openDB(self):
        from ZODB.FileStorage import FileStorage
        from ZODB.DB import DB
        storage = FileStorage(self.dbName)
        db = DB(storage)
        self.db = db.open().root()

    def closeDB(self):
        get_transaction().commit()
        self.document = None
        self.db._p_jar._db.close()
        self.db = None

    def getAppDocument(self):
        "put the document that startup put in the db in self.document"
        self.document = self.db['doc']

    def cycleDB(self):
        """close and open the db and replace self.document.
        Any nonpersistent changes to self.document should be lost."""
        self.closeDB()
        self.openDB()
        self.getAppDocument()

    def delDB(self):
        map(os.unlink, glob.glob("fs_tmp__*"))

    def setUp(self):
        """open db, create a document in the db, set self.document to it"""

        self.dbName = 'fs_tmp__%s' % os.getpid()
        self.openDB()
        self.db['doc'] = ParsedXML.ParsedXML('foo')
        get_transaction().commit()
        self.document = self.db['doc']

    def tearDown(self):
        self.closeDB()
        self.delDB()

    def checkIDPersistence(self):
        "assert that changing the ID persists over transactions"
        self.document._setId('newId')
        self.cycleDB()
        assert self.document.getId() == 'newId'

    def checkParsedXMLDOMPersistence(self):
        "assert that a Parsed XML DOM edit persists over transactions"
        elt = self.document.createElement('elt')
        self.document.firstChild.appendChild(elt)
        self.cycleDB()
        childLen = self.document.firstChild.childNodes.length
        assert childLen == 1, "DOM edit didn't persist"

    def checkDOMPersistence(self):
        "assert that a DOM edit persists over transactions"

        doc = ParsedXML.createDOMDocument()

        import OFS.SimpleItem
        si = self.db['si'] = OFS.SimpleItem.SimpleItem()
        si.doc = doc
        elt = si.doc.createElement('elt')
        si.doc.firstChild.appendChild(elt)

        self.cycleDB()
        # not using the normal db document, must grab ourselves
        si = self.db['si']
                
        childLen = si.doc.firstChild.childNodes.length
        assert childLen == 1, "DOM edit didn't persist"
        
    def checkParsePersistence(self):
        "assert that a parse persists over transactions"
        testDir = os.path.join(
            sys.modules['Products.ParsedXML'].__path__[0],
            'tests')
        filename = os.path.join(testDir, 'xml', '4ohn4ktj.xml')
        file = open(filename)
        self.document.parseXML(filename)
        file.close()
        childLen = self.document.firstChild.childNodes.length
        self.cycleDB()
        childLen1 = self.document.firstChild.childNodes.length
        assert childLen == childLen1, "parse didn't persist"

    def checkSubnodeParsePersistence(self):
        "assert that a subnode parse persists over transactions"        
        docString = '<?xml version="1.0" ?><foo></foo>'
        subNodeString = '<foo>bar</foo>'
        self.document.documentElement.parseXML(StringIO(subNodeString))
        self.cycleDB()
        childLen = self.document.documentElement.childNodes.length
        assert childLen == 1, "parse on subnode didn't persist"

    # right now it's too annoying to get parsing to work at a transient
    # document proxy, but it could be less aggravating if we had a better
    # way to get at the persistent document.
    #def checkTransientDocumentParsePersistence(self):
    #    """assert that a parse of a transient proxy of the document
    #    persists over transactions"""
    #    docStringBefore = '<?xml version="1.0" ?><foo></foo>'
    #    docStringAfter = '<?xml version="1.0" ?><foo>bar</foo>'
    #    self.document.documentElement.ownerDocument.parseXML(
    #        StringIO(docStringAfter))
    #    self.cycleDB()
    #    childLen = self.document.documentElement.childNodes.length
    #    assert childLen == 1, "parse on subnode didn't persist"

#      def checkTheseDamnTests(self):
#          "assert that I understand how these tests should work"
#          docString = '<?xml version="1.0" ?><foo>fff</foo>'        
#          self.document.parseXML(StringIO(docString))
#          get_transaction().commit()
#          # db and doc length now 1
#          self.document.documentElement.removeChild(
#              self.document.documentElement.firstChild)
#          # doc length 0, db length 1
        
#          # do what closeDB and openDB do, but *don't commit*
#          # so the above edit shouldn't stay.

#          #closeDB but don't commit
#          #get_transaction().commit()
#          self.document = None
#          self.db._p_jar._db.close()
#          self.db = None

#          #openDB
#          from ZODB.FileStorage import FileStorage
#          from ZODB.DB import DB
#          storage = FileStorage(self.dbName)
#          db = DB(storage)
#          self.db = db.open().root()

#          self.getAppDocument()
#          get_transaction().commit()
#          assert self.document.documentElement.childNodes.length == 1, (
#              "these tests are faulty")


def test_suite():
    """Return a test suite for the Zope testing framework."""

    return unittest.makeSuite(PersistenceTestCase, 'check')

def main():
    unittest.TextTestRunner().run(test_suite())

if __name__ == '__main__':
    main()
    


=== Added File Products/ParsedXML/tests/test_prettyprinter.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################

import unittest
import ZODB # for Persistent
import string

# FIXME: could test with Core DOM instead, do we want to?
from Products.ParsedXML import ParsedXML, PrettyPrinter
from Products.ParsedXML.StrIO import StringIO

def printElement(element, encoding = None, html = 0, contentType = None):
    output = StringIO()
    PrettyPrinter.PrintVisitor(element, output, encoding, html, contentType)()
    return output.getvalue()

def checkOutput(wanted, got, message="Bad output"):
    assert wanted == got, \
           ("%s.  Wanted:\n%s[[EOF]]\nGot:\n%s[[EOF]]\n" 
            % (message, wanted, got))


class PrintTestBase(unittest.TestCase):
    implementation = ParsedXML.theDOMImplementation

    def parse(self, xml):
        return ParsedXML.ParsedXML('foo', xml)


class PrintTestCase(PrintTestBase):

    def checkAttrOrder(self):
        inStr = '<?xml version="1.0" ?>\n<doc a1="v1" a2="v2" a3="v3"/>\n'
        doc = self.parse(inStr)
        output = printElement(doc)

        checkOutput(inStr, output, "attribute order not preserved")

    def checkDefaultAttrSkipped(self):
        inStr = '<!DOCTYPE doc [<!ELEMENT doc EMPTY>' \
                '<!ATTLIST doc a1 CDATA "v1">]><doc></doc>'
        outStr = '<?xml version="1.0" ?>\n<doc/>\n'
        doc = self.parse(inStr)
        output = printElement(doc)

        checkOutput(outStr, output, "default attribute printed")

    def checkAttrEntRefExpansion(self):
        "entity references must be expanded in attributes"
        doc = self.implementation.createDocument(None, 'root', None)
        attr = doc.createAttribute("attrName")
        # this is a text string; &test; is not an entity reference,
        # so its & should be converted to the proper ref on printing,
        # as should the & and < and >.
        attr.value = "&test; &<>"
        # this reference should be expanded to the empty string
        attr.appendChild(doc.createEntityReference('foo'))
        doc.documentElement.setAttributeNode(attr)

        outStr = '<root attrName="&amp;test; &amp;&lt;&gt;"/>'
        output = printElement(doc.documentElement)
        checkOutput(outStr, output, "improper attr entity expansion")

    def checkTextEntRefExpansion(self):
        "only some entity references should be expanded in text"
        doc = self.implementation.createDocument(None, 'root', None)
        # &< must be converted to the proper reference; > should not.
        text = doc.createTextNode("&<>]]>")
        outStr = '&amp;&lt;>]]&gt;'
        output = printElement(text)
        checkOutput(outStr, output, "improper text entity expansion")

    #TODO: check for expansion of entity refs in other contexts;
    #currently we're expanding aggressively, but it's not a priority
    #because the parser gets to play around with refs too

class HTMLPrintTestCase(PrintTestBase):

    def checkMinimize(self):
        inStr = ('<html><p><hr/><hr noshade="1"/></p><p/><p></p>' +
                 '<p align="center" /></html>')
        outStr = ('<html><p><hr /><hr noshade="1" /></p><p></p><p></p>' +
                  '<p align="center"></p></html>\n')
        doc = self.parse(inStr)
        output = printElement(doc, encoding = None, html = 1)

        checkOutput(outStr, output, "improper HTML minimization")

    def checkCapitalize(self):
        inStr = ('<html><HR nOsHaDe="1" /></html>\n')
        doc = self.parse(inStr)
        output = printElement(doc, encoding = None, html = 1,
                              contentType = 'html')
        checkOutput(string.upper(inStr), output,
                    "improper HTML contenttype HTML capitalization")
        output = printElement(doc, encoding = None, html = 1,
                              contentType = 'xml')
        checkOutput(string.lower(inStr), output,
                    "improper XML contenttype HTML capitalization")
        

class Lvl2PrintTestCase(PrintTestBase):

    def checkNamespacePrint(self):
        outStr = '<?xml version="1.0" ?>\n' \
                    '<bar xmlns:foo="uri:foo">\n' \
                    '<foo:baz/></bar>\n'
        doc = self.parse(outStr)
        output = printElement(doc)
        checkOutput(outStr, output)

    def checkNamespaceAttrOrder(self):
        inStr = ('<?xml version="1.0" ?>\n'
                  '<doc>'
                  '  <fooE xmlns="defaultURL" xmlns:oneN="oneURL" '
                          'xmlns:twoN="twoURL" xmlns:threeN="threeURL"/>'
                  '</doc>\n')
        doc = self.parse(inStr)
        output = printElement(doc)
        checkOutput(inStr, output, "attribute order not preserved")


    def checkHierarchicalElementNamespacePrint(self):
        # print new ns, don't print ns printed by ancestor
        outStr = ('<?xml version="1.0" ?>\n'
                  '<fooN:fooE xmlns:fooN="fooURL">'
                  '  <barN:barE xmlns:barN="barURL">'
                  '  <fooN:fooE>'
                  '    <fooN:fooE/>'
                  '  </fooN:fooE>'
                  '  </barN:barE>'
                  '</fooN:fooE>\n')
        doc = self.parse(outStr)
        output = printElement(doc)
        checkOutput(outStr, output)

    def checkDefaultNamespacePrint(self):
        outStr = ('<?xml version="1.0" ?>\n'
                  '<fooE xmlns="defaultURL"><fooE xmlns="barURL"/>'
                  '</fooE>\n')
        doc = self.parse(outStr)
        output = printElement(doc)
        checkOutput(outStr, output)

    def checkDefaultAndPrefixNamespacePrint(self):
        # try and tickle a namespace printing bug
        outStr = ('<?xml version="1.0" ?>\n'
                  '<doc>'
                  '  <fooE xmlns="defaultURL" xmlns:fooN="fooURL" '
                          'xmlns:barN="barUrl" xmlns:bazN="bazUrl">'
                  '  <barE bazN:bazE="baz"/>'
                  '  <bazN:bazE/>'
                  '  <quxN xmlns:quxE="quxUrl"/>'
                  '  <quxN xmlns:quxE="quxUrl" bazN:bazE="baz"/>'
                  '  </fooE>'
                  '</doc>\n')
        doc = self.parse(outStr)
        output = printElement(doc)
        checkOutput(outStr, output)


def test_suite():
    """Return a test suite for the Zope testing framework."""

    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(PrintTestCase, 'check'))
    suite.addTest(unittest.makeSuite(HTMLPrintTestCase, 'check'))
    suite.addTest(unittest.makeSuite(Lvl2PrintTestCase, 'check'))
    return suite

def main():
    unittest.TextTestRunner().run(test_suite())

if __name__ == '__main__':
    main()


=== Added File Products/ParsedXML/tests/test_printer.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################

import unittest
import ZODB # for Persistent
import string

# FIXME: could test with Core DOM instead, do we want to?
from Products.ParsedXML import ParsedXML, Printer
from Products.ParsedXML.StrIO import StringIO

def printElement(element, encoding = None, html = 0, contentType = None):
    output = StringIO()
    Printer.PrintVisitor(element, output, encoding, html, contentType)()
    return output.getvalue()

def checkOutput(wanted, got, message="Bad output"):
    assert wanted == got, \
           ("%s.  Wanted:\n%s[[EOF]]\nGot:\n%s[[EOF]]\n" 
            % (message, wanted, got))


class PrintTestBase(unittest.TestCase):
    implementation = ParsedXML.theDOMImplementation

    def parse(self, xml):
        return ParsedXML.ParsedXML('foo', xml)


class PrintTestCase(PrintTestBase):

    def checkAttrOrder(self):
        inStr = '<?xml version="1.0" ?>\n<doc a1="v1" a2="v2" a3="v3"/>\n'
        doc = self.parse(inStr)
        output = printElement(doc)

        checkOutput(inStr, output, "attribute order not preserved")

    def checkDefaultAttrSkipped(self):
        inStr = '<!DOCTYPE doc [<!ELEMENT doc EMPTY>' \
                '<!ATTLIST doc a1 CDATA "v1">]><doc></doc>'
        outStr = '<?xml version="1.0" ?>\n<doc/>\n'
        doc = self.parse(inStr)
        output = printElement(doc)

        checkOutput(outStr, output, "default attribute printed")

    def checkAttrEntRefExpansion(self):
        "entity references must be expanded in attributes"
        doc = self.implementation.createDocument(None, 'root', None)
        attr = doc.createAttribute("attrName")
        # this is a text string; &test; is not an entity reference,
        # so its & should be converted to the proper ref on printing,
        # as should the & and < and >.
        attr.value = "&test; &<>"
        # this reference should be expanded to the empty string
        attr.appendChild(doc.createEntityReference('foo'))
        doc.documentElement.setAttributeNode(attr)

        outStr = '<root attrName="&amp;test; &amp;&lt;&gt;"/>'
        output = printElement(doc.documentElement)
        checkOutput(outStr, output, "improper attr entity expansion")

    def checkTextEntRefExpansion(self):
        "only some entity references should be expanded in text"
        doc = self.implementation.createDocument(None, 'root', None)
        # &< must be converted to the proper reference; > should not.
        text = doc.createTextNode("&<>]]>")
        outStr = '&amp;&lt;>]]&gt;'
        output = printElement(text)
        checkOutput(outStr, output, "improper text entity expansion")

    #TODO: check for expansion of entity refs in other contexts;
    #currently we're expanding aggressively, but it's not a priority
    #because the parser gets to play around with refs too

class HTMLPrintTestCase(PrintTestBase):

    def checkMinimize(self):
        inStr = ('<html><p><hr/><hr noshade="1"/></p><p/><p></p>' +
                 '<p align="center" /></html>')
        outStr = ('<html><p><hr /><hr noshade="1" /></p><p></p><p></p>' +
                  '<p align="center"></p></html>\n')
        doc = self.parse(inStr)
        output = printElement(doc, encoding = None, html = 1)

        checkOutput(outStr, output, "improper HTML minimization")

    def checkCapitalize(self):
        inStr = ('<html><HR nOsHaDe="1" /></html>\n')
        doc = self.parse(inStr)
        output = printElement(doc, encoding = None, html = 1,
                              contentType = 'html')
        checkOutput(string.upper(inStr), output,
                    "improper HTML contenttype HTML capitalization")
        output = printElement(doc, encoding = None, html = 1,
                              contentType = 'xml')
        checkOutput(string.lower(inStr), output,
                    "improper XML contenttype HTML capitalization")
        

class Lvl2PrintTestCase(PrintTestBase):

    def checkNamespacePrint(self):
        outStr = '<?xml version="1.0" ?>\n' \
                    '<bar xmlns:foo="uri:foo">\n' \
                    '<foo:baz/></bar>\n'
        doc = self.parse(outStr)
        output = printElement(doc)
        checkOutput(outStr, output)

    def checkNamespaceAttrOrder(self):
        inStr = ('<?xml version="1.0" ?>\n'
                  '<doc>'
                  '  <fooE xmlns="defaultURL" xmlns:oneN="oneURL" '
                          'xmlns:twoN="twoURL" xmlns:threeN="threeURL"/>'
                  '</doc>\n')
        doc = self.parse(inStr)
        output = printElement(doc)
        checkOutput(inStr, output, "attribute order not preserved")


    def checkHierarchicalElementNamespacePrint(self):
        # print new ns, don't print ns printed by ancestor
        outStr = ('<?xml version="1.0" ?>\n'
                  '<fooN:fooE xmlns:fooN="fooURL">'
                  '  <barN:barE xmlns:barN="barURL">'
                  '  <fooN:fooE>'
                  '    <fooN:fooE/>'
                  '  </fooN:fooE>'
                  '  </barN:barE>'
                  '</fooN:fooE>\n')
        doc = self.parse(outStr)
        output = printElement(doc)
        checkOutput(outStr, output)

    def checkDefaultNamespacePrint(self):
        outStr = ('<?xml version="1.0" ?>\n'
                  '<fooE xmlns="defaultURL"><fooE xmlns="barURL"/>'
                  '</fooE>\n')
        doc = self.parse(outStr)
        output = printElement(doc)
        checkOutput(outStr, output)

    def checkDefaultAndPrefixNamespacePrint(self):
        # try and tickle a namespace printing bug
        outStr = ('<?xml version="1.0" ?>\n'
                  '<doc>'
                  '  <fooE xmlns="defaultURL" xmlns:fooN="fooURL" '
                          'xmlns:barN="barUrl" xmlns:bazN="bazUrl">'
                  '  <barE bazN:bazE="baz"/>'
                  '  <bazN:bazE/>'
                  '  <quxN xmlns:quxE="quxUrl"/>'
                  '  <quxN xmlns:quxE="quxUrl" bazN:bazE="baz"/>'
                  '  </fooE>'
                  '</doc>\n')
        doc = self.parse(outStr)
        output = printElement(doc)
        checkOutput(outStr, output)


def test_suite():
    """Return a test suite for the Zope testing framework."""

    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(PrintTestCase, 'check'))
    suite.addTest(unittest.makeSuite(HTMLPrintTestCase, 'check'))
    suite.addTest(unittest.makeSuite(Lvl2PrintTestCase, 'check'))
    return suite

def main():
    unittest.TextTestRunner().run(test_suite())

if __name__ == '__main__':
    main()


=== Added File Products/ParsedXML/tests/test_pyxmldom.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################

import unittest
from domapi import DOMImplementationTestSuite

from xml.dom import ext, implementation
from xml.dom.ext.reader import PyExpat

def DOMParseString(self, xml):
    reader = PyExpat.Reader()
    return reader.fromString(xml)

def test_suite():
    """Return a test suite for the Zope testing framework."""
    return DOMImplementationTestSuite(implementation, DOMParseString)

def main():
    unittest.TextTestRunner().run(test_suite())

if __name__ == "__main__":
    main()


=== Added File Products/ParsedXML/tests/test_truthable.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################
"tests to make sure that DOM objects support truth testing"

import unittest
import ZODB # for Persistent
from Products.ParsedXML import ParsedXML, DOM

from operator import truth

class WrappedTruthableTestCaseBase(unittest.TestCase):

    def setUp(self):
        self.document = doc = ParsedXML.ParsedXML('foo')
        self.floating_element = doc.createElement("per")
        self.attached_element = doc.documentElement

class DOMTruthableTestCaseBase(unittest.TestCase):

    def setUp(self):
        self.document = doc = DOM.theDOMImplementation.createDocument(
            None, 'root', None)
        self.floating_element = doc.createElement("per")
        self.attached_element = doc.documentElement

class TruthableTestCaseTests:

    def checkFloatingTruthable(self):
        assert truth(self.floating_element) == 1

    def checkDOMTruthable(self):
        assert truth(self.document) == 1
        assert truth(self.document.documentElement.parentNode) == 1

    def checkAttachedTruthable(self):
        assert truth(self.attached_element) == 1

class DOMTruthableTestCase(DOMTruthableTestCaseBase,
                           TruthableTestCaseTests):
    pass

class WrappedTruthableTestCase(WrappedTruthableTestCaseBase,
                               TruthableTestCaseTests):
    pass

def test_suite():
    """Return a test suite for the Zope testing framework."""

    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(DOMTruthableTestCase, 'check'))
    suite.addTest(unittest.makeSuite(WrappedTruthableTestCase, 'check'))
    return suite

def main():
    unittest.TextTestRunner().run(test_suite())

if __name__ == "__main__":
    main()


=== Added File Products/ParsedXML/tests/test_wrappeddom.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################

import unittest
import ZODB # for Persistent
from Products.ParsedXML import ParsedXML
from domapi import DOMImplementationTestSuite

def ParsedXMLParseString(self, xml):
    return ParsedXML.ParsedXML('foo', xml)

def test_suite():
    """Return a test suite for the Zope testing framework."""
    return DOMImplementationTestSuite(ParsedXML.theDOMImplementation, 
        ParsedXMLParseString)

def main():
    unittest.TextTestRunner().run(test_suite())

if __name__ == '__main__':
    main()


=== Added File Products/ParsedXML/tests/test_zopeinterface.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################

"""Test that some Zope interfaces are supported properly."""

import unittest
import ZODB # for Persistent
from Products.ParsedXML import ParsedXML
from Products.ParsedXML.StrIO import StringIO


def assertSize(doc):
    "assert that the document size what's reported by len"
    gs = doc.get_size()
    l = len(str(doc))
    assert gs == l, "get_size reports %d while len reports %d" % (gs, l)
    
class GetSizeTestCase(unittest.TestCase):
    "test that get_size works.  We only test on the persistent Document."

    def setUp(self):
        self.document = ParsedXML.ParsedXML('foo')

    def checkGetSize(self):
        "assert that get_size works"
        assertSize(self.document)

    def checkGetSizeParse(self):
        "assert that get_size works after a parse"        
        inStr = '<spam><eggs attr1="foo"><ham/>text</eggs></spam>'
        self.document.parseXML(StringIO(inStr))
        assertSize(self.document)        
        self.document.documentElement.parseXML(StringIO(inStr))
        assertSize(self.document)        

    def checkGetSizeDOMMethods(self):
        "assert that get_size works after some DOM method manipulations"
        self.document.documentElement.appendChild(
            self.document.createElement('spam'))
        assertSize(self.document)
        self.document.documentElement.appendChild(
            self.document.createTextNode('spam'))
        assertSize(self.document)
        self.document.documentElement.appendChild(
            self.document.createTextNode('spam'))
        assertSize(self.document)
        self.document.normalize()
        assertSize(self.document)
        self.document.documentElement.setAttribute('eggs', 'ham')
        assertSize(self.document)

    def checkgetSizeDOMAttributess(self):
        "assert that get_size works after some DOM attribute manipulations"
        self.document.documentElement.appendChild(
            self.document.createTextNode('spam'))
        self.document.documentElement.firstChild.data = "spamspamspam"
        assertSize(self.document)
        self.document.documentElement.setAttribute('eggs', 'ham')
        self.document.documentElement.attributes.item(0).value = 'spam'
        assertSize(self.document)
        
def test_suite():
    """Return a test suite for the Zope testing framework."""

    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(GetSizeTestCase, 'check'))
    return suite

def main():
    unittest.TextTestRunner().run(test_suite())

if __name__ == "__main__":
    main()





More information about the zopeorg-checkins mailing list