[Zope3-checkins] CVS: Zope/lib/python/ZConfig/tests - test_config.py:1.1.4.1 test_datatypes.py:1.1.4.1 test_loader.py:1.1.4.1 test_schema.py:1.1.4.1 test_subst.py:1.1.4.1 test_zopeschema.py:1.1.4.1 runtests.py:1.1.4.2

Chris McDonough chrism@zope.com
Fri, 3 Jan 2003 10:52:09 -0500


Update of /cvs-repository/Zope/lib/python/ZConfig/tests
In directory cvs.zope.org:/tmp/cvs-serv2937/tests

Modified Files:
      Tag: chrism-install-branch
	runtests.py 
Added Files:
      Tag: chrism-install-branch
	test_config.py test_datatypes.py test_loader.py test_schema.py 
	test_subst.py test_zopeschema.py 
Log Message:
Merge zconfig-schema-devel-branch into chrism-install-branch.  Why not? ;-)


=== Added File Zope/lib/python/ZConfig/tests/test_config.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Tests of the configuration data structures and loader."""

import os
import StringIO
import tempfile
import unittest
import urllib

import ZConfig

from ZConfig.Context import Context
from ZConfig.url import urljoin

try:
    __file__
except NameError:
    import sys
    __file__ = sys.argv[0]

d = os.path.abspath(os.path.join(os.path.dirname(__file__), "input"))
CONFIG_BASE = "file://%s/" % urllib.pathname2url(d)


class TestBase(unittest.TestCase):

    def load(self, relurl, context=None):
        url = urljoin(CONFIG_BASE, relurl)
        if context is None:
            conf = ZConfig.loadURL(url)
        else:
            conf = context.loadURL(url)
        self.assertEqual(conf.url, url)
        self.assert_(conf.name is None)
        self.assert_(conf.type is None)
        self.assert_(conf.delegate is None)
        return conf

    def loadtext(self, text):
        sio = StringIO.StringIO(text)
        return ZConfig.loadFile(sio)

    def check_simple_gets(self, conf):
        self.assertEqual(conf.get('empty'), '')
        self.assertEqual(conf.getint('int-var'), 12)
        self.assertEqual(conf.getint('neg-int'), -2)
        self.assertEqual(conf.getfloat('float-var'), 12.02)
        self.assertEqual(conf.get('var1'), 'abc')
        self.assert_(conf.getbool('true-var-1'))
        self.assert_(conf.getbool('true-var-2'))
        self.assert_(conf.getbool('true-var-3'))
        self.assert_(not conf.getbool('false-var-1'))
        self.assert_(not conf.getbool('false-var-2'))
        self.assert_(not conf.getbool('false-var-3'))
        self.assertEqual(conf.getlist('list-1'), [])
        self.assertEqual(conf.getlist('list-2'), ['abc'])
        self.assertEqual(conf.getlist('list-3'), ['abc', 'def', 'ghi'])
        self.assertEqual(conf.getlist('list-4'), ['[', 'what', 'now?', ']'])
        self.assert_(conf.getlist('list-0') is None)
        missing = Thing()
        self.assert_(conf.getlist('list-0', missing) is missing)
        self.assertEqual(conf.getlist('list-1', missing), [])
        self.assertEqual(conf.getlist('list-2', missing), ['abc'])
        self.assertEqual(conf.getlist('list-3', missing),
                         ['abc', 'def', 'ghi'])
        self.assertEqual(conf.getlist('list-4', missing),
                         ['[', 'what', 'now?', ']'])


class Thing:
    pass

class ConfigurationTestCase(TestBase):

    def test_simple_gets(self):
        conf = self.load("simple.conf")
        self.check_simple_gets(conf)

    def test_type_errors(self):
        conf = self.load("simple.conf")
        getbool = conf.getbool
        getint = conf.getint
        self.assertRaises(ValueError, getbool, 'int-var')
        self.assertRaises(ValueError, getbool, 'float-var')
        self.assertRaises(ValueError, getbool, 'neg-int')
        self.assertRaises(ValueError, getint, 'true-var-1')
        self.assertRaises(ValueError, getint, 'true-var-2')
        self.assertRaises(ValueError, getint, 'true-var-3')
        self.assertRaises(ValueError, getint, 'false-var-1')
        self.assertRaises(ValueError, getint, 'false-var-2')
        self.assertRaises(ValueError, getint, 'false-var-3')
        self.assertRaises(ValueError, getint, 'float-var')

    def test_range_errors(self):
        conf = self.load("simple.conf")
        getfloat = conf.getfloat
        getint = conf.getint
        self.assertRaises(ValueError, getint, 'int-var', min=20)
        self.assertRaises(ValueError, getint, 'int-var', max=10)
        self.assertRaises(ValueError, getint, 'neg-int', min=-1)
        self.assertRaises(ValueError, getint, 'neg-int', max=-3)
        self.assertRaises(ValueError, getfloat, 'float-var', min=12.03)
        self.assertRaises(ValueError, getfloat, 'float-var', max=12.01)

    def test_items(self):
        conf = self.load("simplesections.conf")
        self.assertEqual(sorted_items(conf),
                         [("var", "foo"), ("var-0", "foo-0"),
                          ("var-1", "foo-1"), ("var-2", "foo-2"),
                          ("var-3", "foo-3"), ("var-4", "foo-4"),
                          ("var-5", "foo-5"), ("var-6", "foo-6")])
        self.assertEqual(sorted_items(conf.getSection("section", "name")),
                         [("var", "bar"), ("var-one", "splat"),
                          ("var-two", "stuff")])

    def test_has_key(self):
        conf = self.load("simplesections.conf")
        sect = conf.getSection("section", "name")
        for key in ("var", "var-one", "var-two"):
            self.assert_(sect.has_key(key))
            self.assert_(sect.has_key(key.upper()))
        self.assert_(not sect.has_key("var-three"))

    def test_missing_named_section(self):
        conf = self.load("simplesections.conf")
        self.assertRaises(ZConfig.ConfigurationMissingSectionError,
                          conf.getSection, "section", "does-not-exist")

    def test_keys(self):
        conf = self.load("simplesections.conf")
        self.assertEqual(sorted_keys(conf),
                         ["var", "var-0", "var-1", "var-2", "var-3",
                          "var-4", "var-5", "var-6"])
        sect = conf.getSection("section", "Name")
        self.assertEqual(sorted_keys(sect),
                         ["var", "var-one", "var-two"])
        sect = conf.getSection("Section", "delegate")
        self.assertEqual(sorted_keys(sect), ["var", "var-two"])
        sect = conf.getSection("SECTION", "ANOTHER")
        self.assertEqual(sorted_keys(sect), ["var", "var-three"])
        L = [sect for sect in conf.getChildSections() if not sect.name]
        self.assertEqual(len(L), 3)
        section, trivial, minimal = L
        self.assert_(section.name is None)
        self.assertEqual(section.type, "section")
        self.assertEqual(sorted_keys(section), ["var", "var-two"])
        self.assert_(trivial.name is None)
        self.assertEqual(trivial.type, "trivial")
        self.assertEqual(sorted_keys(trivial), ["var"])
        self.assert_(minimal.name is None)
        self.assertEqual(minimal.type, "minimal")
        self.assertEqual(minimal.keys(), [])

    def test_simple_sections(self):
        conf = self.load("simplesections.conf")
        self.assertEqual(conf.get("var"), "foo")
        # check each interleaved position between sections
        for c in "0123456":
            self.assertEqual(conf.get("var-" + c), "foo-" + c)
        self.assert_(conf.get("var-7") is None)
        sect = conf.getSection("section", "name")
        for k, v in [("var", "bar"), ("var-one", "splat"),
                     ("var-two", "stuff")]:
            self.assertEqual(sect.get(k), v)
            self.assertEqual(sect.get(k.upper()), v)
        self.assert_(sect.get("not-there") is None)
        sect = conf.getSection("section", "delegate")
        for k, v in [("var", "spam"), ("var-two", "stuff")]:
            self.assertEqual(sect.get(k), v)
            self.assertEqual(sect.get(k.upper()), v)
        self.assert_(sect.get("Var-One") is None)
        L = []
        for sect in conf.getChildSections():
            if sect.type == "trivial":
                L.append(sect)
                self.assertEqual(sect.get("var"), "triv")
                break
        L2 = conf.getChildSections("TRIVIAL")
        self.assertEqual(L, L2)

    def test_no_delegation(self):
        url = urljoin(CONFIG_BASE, "simplesections.conf")
        context = NoDelegationContext()
        self.assertRaises(ZConfig.ConfigurationTypeError,
                          context.loadURL, url)

    def test_include(self):
        conf = self.load("include.conf")
        self.assertEqual(conf.get("var1"), "abc")
        self.assertEqual(conf.get("VAR1"), "abc")
        self.assertEqual(conf.get("var2"), "value2")
        self.assertEqual(conf.get("VAR2"), "value2")
        self.assertEqual(conf.get("var3"), "value3")
        self.assertEqual(conf.get("VAR3"), "value3")

    def test_define(self):
        conf = self.load("simple.conf")
        self.assertEqual(conf.get("getname"), "value")
        self.assertEqual(conf.get("getnametwice"), "valuevalue")
        self.assertEqual(conf.get("getdollars"), "$$")
        self.assertEqual(conf.get("getempty"), "xy")
        self.assertEqual(conf.get("getwords"), "abc two words def")

    def test_define_errors(self):
        self.assertRaises(ZConfig.ConfigurationSyntaxError,
                          self.loadtext, "%define\n")
        self.assertRaises(ZConfig.ConfigurationSyntaxError,
                          self.loadtext, "%define abc-def\n")
        self.assertRaises(ZConfig.ConfigurationSyntaxError,
                          self.loadtext, "%define a value\n%define a value\n")

    def test_fragment_ident_disallowed(self):
        self.assertRaises(ZConfig.ConfigurationError,
                          self.load, "simplesections.conf#another")

    def test_load_from_abspath(self):
        fn = self.write_tempfile()
        try:
            self.check_load_from_path(fn)
        finally:
            os.unlink(fn)

    def test_load_from_relpath(self):
        fn = self.write_tempfile()
        dir, name = os.path.split(fn)
        pwd = os.getcwd()
        try:
            os.chdir(dir)
            self.check_load_from_path(name)
        finally:
            os.chdir(pwd)
            os.unlink(fn)

    def test_load_from_fileobj(self):
        sio = StringIO.StringIO("name value\n"
                                "<section>\n"
                                "  name value2\n"
                                "</section>\n")
        cf = ZConfig.loadFile(sio)
        self.assertEqual(cf.get("Name"), "value")
        self.assertEqual(cf.getSection("Section").get("Name"), "value2")

    def write_tempfile(self):
        fn = tempfile.mktemp()
        fp = open(fn, "w")
        fp.write("key value\n")
        fp.close()
        return fn

    def check_load_from_path(self, path):
        context = Context()
        context.loadURL(path)


class NoDelegationContext(Context):
    def getDelegateType(self, type):
        return None


def sorted_items(conf):
    L = conf.items()
    L.sort()
    return L

def sorted_keys(conf):
    L = conf.keys()
    L.sort()
    return L


def test_suite():
    return unittest.makeSuite(ConfigurationTestCase)

if __name__ == '__main__':
    unittest.main(defaultTest='test_suite')


=== Added File Zope/lib/python/ZConfig/tests/test_datatypes.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Tests of standard ZConfig datatypes."""

import os
import socket
import sys
import tempfile
import unittest

import ZConfig.datatypes

try:
    here = __file__
except NameError:
    here = sys.argv[0]

class DatatypeTestCase(unittest.TestCase):
    types = ZConfig.datatypes.Registry()

    def test_datatype_basickey(self):
        convert = self.types.get("basic-key")
        eq = self.assertEqual
        raises = self.assertRaises

        eq(convert("abc"), "abc")
        eq(convert("ABC_DEF.123"), "abc_def.123")
        eq(convert("Abc-Def-456"), "abc-def-456")
        eq(convert("Abc.Def"), "abc.def")

        raises(ValueError, convert, "_abc")
        raises(ValueError, convert, "-abc")
        raises(ValueError, convert, "123")
        raises(ValueError, convert, "")

    def test_datatype_boolean(self):
        convert = self.types.get("boolean")
        check = self.assert_
        raises = self.assertRaises

        check(convert("on"))
        check(convert("true"))
        check(convert("yes"))
        check(not convert("off"))
        check(not convert("false"))
        check(not convert("no"))
        raises(ValueError, convert, '0')
        raises(ValueError, convert, '1')
        raises(ValueError, convert, '')
        raises(ValueError, convert, 'junk')

    def test_datatype_float(self):
        convert = self.types.get("float")
        eq = self.assertEqual
        raises = self.assertRaises

        eq(convert("1"), 1.0)
        self.assert_(type(convert(1)) is type(1.0))
        eq(convert("1.1"), 1.1)
        eq(convert("50.50"), 50.50)
        eq(convert("-50.50"), -50.50)
        eq(convert(0), 0.0)
        eq(convert("0"), 0.0)
        eq(convert("-0"), 0.0)
        eq(convert("0.0"), 0.0)

        raises(ValueError, convert, "junk")
        raises(ValueError, convert, "0x234.1.9")
        raises(ValueError, convert, "0.9-")

        # These are not portable representations; make sure they are
        # disallowed everywhere for consistency.
        raises(ValueError, convert, "inf")
        raises(ValueError, convert, "-inf")
        raises(ValueError, convert, "nan")

    def test_datatype_identifier(self):
        convert = self.types.get("identifier")
        eq = self.assertEqual
        raises = self.assertRaises

        eq(convert("AbcDef"), "AbcDef")
        eq(convert("a________"), "a________")
        eq(convert("abc_def"), "abc_def")
        eq(convert("int123"), "int123")
        eq(convert("_abc"), "_abc")
        eq(convert("_123"), "_123")
        eq(convert("__dict__"), "__dict__")
        raises(ValueError, convert, "2345")
        raises(ValueError, convert, "-abc")
        raises(ValueError, convert, "-123")
        raises(ValueError, convert, "")

    def test_datatype_inet_address(self):
        convert = self.types.get("inet-address")
        eq = self.assertEqual
        eq(convert("Host.Example.Com:80"), ("host.example.com", 80))
        eq(convert(":80"),                 ("", 80))
        eq(convert("80"),                  ("", 80))
        eq(convert("host.EXAMPLE.com"),    ("host.example.com", None))

    def test_datatype_integer(self):
        convert = self.types.get("integer")
        eq = self.assertEqual
        raises = self.assertRaises

        eq(convert('-100'), -100)
        eq(convert('-1'), -1)
        eq(convert('-0'), 0)
        eq(convert('0'), 0)
        eq(convert('1'), 1)
        eq(convert('100'), 100)
        eq(convert('65535'), 65535)
        eq(convert('65536'), 65536)

        big = sys.maxint + 1L  # Python 2.1 needs the L suffix here
        s = str(big)           # s won't have the suffix
        eq(convert(s), big)
        eq(convert("-" + s), -big)

        raises(ValueError, convert, 'abc')
        raises(ValueError, convert, '-0xabc')
        raises(ValueError, convert, '')
        raises(ValueError, convert, '123 456')
        raises(ValueError, convert, '123-')

    def test_datatype_locale(self):
        convert = self.types.get("locale")
        # Python supports "C" even when the _locale module is not available
        self.assertEqual(convert("C"), "C")
        self.assertRaises(ValueError, convert, "locale-does-not-exist")

    def test_datatype_port(self):
        convert = self.types.get("port-number")
        eq = self.assertEqual
        raises = self.assertRaises

        raises(ValueError, convert, '-1')
        raises(ValueError, convert, '0')
        eq(convert('1'), 1)
        eq(convert('80'), 80)
        eq(convert('1023'), 1023)
        eq(convert('1024'), 1024)
        eq(convert('60000'), 60000)
        eq(convert('65535'), 0xffff)
        raises(ValueError, convert, '65536')

    def test_datatype_socket_address(self):
        convert = self.types.get("socket-address")
        eq = self.assertEqual
        raises = self.assertRaises
        AF_INET = socket.AF_INET
        eq(convert("Host.Example.Com:80"),(AF_INET, ("host.example.com", 80)))
        eq(convert(":80"),                (AF_INET, ("", 80)))
        eq(convert("80"),                 (AF_INET, ("", 80)))
        eq(convert("host.EXAMPLE.com"),   (AF_INET, ("host.example.com",None)))
        if hasattr(socket, "AF_UNIX"):
            eq(convert("/tmp/var/@345.4"),
               (socket.AF_UNIX, "/tmp/var/@345.4"))
            eq(convert("/tmp/var/@345.4:80"),
               (socket.AF_UNIX, "/tmp/var/@345.4:80"))
        else:
            raises(ValueError, convert, "/tmp/var/@345.4")
            raises(ValueError, convert, "/tmp/var/@345.4:80")

    def test_constructor(self):
        convert = self.types.get('constructor')
        eq = self.assertEqual
        raises = self.assertRaises
        eq(convert('Foo()'),          ('Foo', [], {}))
        eq(convert('Foo(1,a=1,b=2)'), ('Foo', [1], {'a':1, 'b':2}))
        eq(convert('Foo(1,2,3)'),     ('Foo', [1,2,3], {}))
        eq(convert('Foo(1,2,3)'),     ('Foo', [1,2,3], {}))
        raises(ValueError, convert, 'Foo')
        raises(ValueError, convert, 'Foo(')
        raises(NameError, convert, 'Foo(a, b, c)')

    def test_ipaddr_or_hostname(self):
        convert = self.types.get('ipaddr-or-hostname')
        eq = self.assertEqual
        raises = self.assertRaises
        eq(convert('hostname'),          'hostname')
        eq(convert('hostname.com'),      'hostname.com')
        eq(convert('www.hostname.com'),  'www.hostname.com')
        eq(convert('127.0.0.1'),         '127.0.0.1')
        raises(ValueError, convert,  '1hostnamewithleadingnumeric')
        raises(ValueError, convert,  '255.255')
        raises(ValueError, convert,  '12345678')
        raises(ValueError, convert,  '999.999.999.999')
        raises(ValueError, convert,  'a!badhostname')

    def test_existing_directory(self):
        convert = self.types.get('existing-directory')
        eq = self.assertEqual
        raises = self.assertRaises
        eq(convert('.'), '.')
        eq(convert(os.path.dirname(here)), os.path.dirname(here))
        raises(ValueError, convert, tempfile.mktemp())

    def test_existing_file(self):
        convert = self.types.get('existing-file')
        eq = self.assertEqual
        raises = self.assertRaises
        eq(convert('.'), '.')
        eq(convert(here), here)
        raises(ValueError, convert, tempfile.mktemp())

    def test_existing_path(self):
        convert = self.types.get('existing-path')
        eq = self.assertEqual
        raises = self.assertRaises
        eq(convert('.'), '.')
        eq(convert(here), here)
        eq(convert(os.path.dirname(here)), os.path.dirname(here))
        raises(ValueError, convert, tempfile.mktemp())

    def test_existing_dirpath(self):
        convert = self.types.get('existing-dirpath')
        eq = self.assertEqual
        raises = self.assertRaises
        eq(convert('.'), '.')
        eq(convert(here), here)
        raises(ValueError, convert, '/a/hopefully/nonexistent/path')
        raises(ValueError, convert, here + '/bogus')

    def test_space_sep_key_value(self):
        convert = self.types.get('key-value')
        eq = self.assertEqual
        eq(convert('A B'), ['A', 'B'])
        eq(convert('Foo Boo'), ['Foo', 'Boo'])
        eq(convert('Foo Boo Baz'), ['Foo', 'Boo Baz'])
        eq(convert('Foo'), ['Foo', ''])

def test_suite():
    return unittest.makeSuite(DatatypeTestCase)

if __name__ == '__main__':
    unittest.main(defaultTest='test_suite')


=== Added File Zope/lib/python/ZConfig/tests/test_loader.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Tests of ZConfig.loader classes and helper functions."""

import StringIO
import unittest
import urlparse

import ZConfig
import ZConfig.loader

from ZConfig import url

from ZConfig.tests.test_config import CONFIG_BASE


class LoaderTestCase(unittest.TestCase):

    def test_schema_caching(self):
        loader = ZConfig.loader.SchemaLoader()
        url = urlparse.urljoin(CONFIG_BASE, "simple.xml")
        schema1 = loader.loadURL(url)
        schema2 = loader.loadURL(url)
        self.assert_(schema1 is schema2)

    def test_schema_components(self):
        loader = ZConfig.loader.SchemaLoader()
        url = urlparse.urljoin(CONFIG_BASE, "library.xml")
        schema = loader.loadURL(url)
        type_a = loader.loadURL(url + "#type-a")
        type_b = loader.loadURL(url + "#type-b")
        self.assertEqual(type_a.name, "type-a")
        self.assertEqual(type_b.name, "type-b")
        # make sure we're using the cached schema for the types
        self.assert_(type_a is schema.gettype("type-a"))
        self.assert_(type_b is schema.gettype("type-b"))

    def test_simple_import(self):
        loader = ZConfig.loader.SchemaLoader()
        url1 = urlparse.urljoin(CONFIG_BASE, "library.xml")
        schema1 = loader.loadURL(url1)
        sio = StringIO.StringIO("<schema>"
                                "  <import src='library.xml'/>"
                                "  <section type='type-a' name='section'/>"
                                "</schema>")
        url2 = urlparse.urljoin(CONFIG_BASE, "stringio")
        schema2 = loader.loadFile(sio, url2)
        self.assert_(schema1.gettype("type-a") is schema2.gettype("type-a"))

    def test_zconfig_resource(self):
        loader = ZConfig.loader.SchemaLoader()
        r = loader.openResource("zconfig:schema.dtd")
        self.assert_(r.fragment is None)
        self.assertEqual(r.url, "zconfig:schema.dtd")
        # just make sure we can read it; we don't care about the content:
        self.assert_(r.readline())
        self.assert_(not r.closed)
        r.close()
        self.assert_(r.closed)

    def test_urldefrag(self):
        eq = self.assertEqual
        eq(url.urldefrag("zconfig:abc/def.ghi#frag"),
           ("zconfig:abc/def.ghi", "frag"))
        eq(url.urldefrag("zconfig:abc/def.ghi"),
           ("zconfig:abc/def.ghi", ''))

    def test_urlsplit_absolute(self):
        parts = url.urlsplit("zconfig:path/to/resource/file.txt#fragment")
        self.assertEqual(parts, ("zconfig", '', "path/to/resource/file.txt",
                                 '', "fragment"))
        self.assertRaises(ValueError, url.urlsplit, "zconfig://host")
        self.assertRaises(ValueError, url.urlsplit, "zconfig:host?query")

    def test_urlsplit_relative(self):
        eq = self.assertEqual
        raises = self.assertRaises

        def urlsplit(s):
            return url.urlsplit(s, scheme="zconfig")

        eq(urlsplit("#frag"),
           ('zconfig', '', '', '', "frag"))
        eq(urlsplit("path/to/resource#frag"),
           ('zconfig', '', "path/to/resource", '', "frag"))
        eq(url.urlsplit("path/to/resource/file.txt#fragment", "zconfig"),
           ('zconfig', '', "path/to/resource/file.txt", '', "fragment"))

        raises(ValueError, urlsplit, "/path/to/resource")
        raises(ValueError, urlsplit, "/path/to/resource?query")
        raises(ValueError, urlsplit, "path/to/resource?query")

    def test_urljoin(self):
        eq = self.assertEqual
        eq(url.urljoin("zconfig:path/file.txt#oldfrag", "../newpath/foo.xml"),
           "zconfig:newpath/foo.xml")
        eq(url.urljoin("zconfig:abc.xml", "def.xml"),
           "zconfig:def.xml")
        eq(url.urljoin("zconfig:abc.xml", "#frag"),
           "zconfig:abc.xml#frag")
        self.assertRaises(ValueError, url.urljoin,
                          "zconfig:abc.xml", "../def.xml")


def test_suite():
    return unittest.makeSuite(LoaderTestCase)

if __name__ == '__main__':
    unittest.main(defaultTest='test_suite')


=== Added File Zope/lib/python/ZConfig/tests/test_schema.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Tests of ZConfig schemas."""

import StringIO
import unittest

import ZConfig

from ZConfig.loader import ConfigLoader
from ZConfig.url import urljoin
from ZConfig.tests.test_config import CONFIG_BASE


def uppercase(value):
    return str(value).upper()

def appsection(value):
    return MySection(value)

class MySection:
    def __init__(self, value):
        self.conf = value
        self.length = len(value)


class BaseSchemaTest(unittest.TestCase):
    """Utility methods which can be used with the schema support."""

    def load_both(self, schema_url, conf_url):
        schema = self.load_schema(schema_url)
        conf = self.load_config(schema, conf_url)
        return schema, conf

    def load_schema(self, relurl):
        self.url = urljoin(CONFIG_BASE, relurl)
        self.schema = ZConfig.loadSchema(self.url)
        self.assert_(self.schema.issection())
        return self.schema

    def load_schema_text(self, text):
        sio = StringIO.StringIO(text)
        self.schema = ZConfig.loadSchemaFile(sio)
        return self.schema

    def load_config(self, schema, conf_url, num_handlers=0):
        conf_url = urljoin(CONFIG_BASE, conf_url)
        self.conf, self.handlers = ConfigLoader(schema).loadURL(conf_url)
        self.assertEqual(len(self.handlers), num_handlers)
        return self.conf

    def load_config_text(self, schema, text, num_handlers=0):
        sio = StringIO.StringIO(text)
        self.conf, self.handlers = ZConfig.loadConfigFile(schema, sio)
        self.assertEqual(len(self.handlers), num_handlers)
        return self.conf


class SchemaTestCase(BaseSchemaTest):
    """Tests of the basic schema support itself."""

    def test_minimal_schema(self):
        schema = self.load_schema_text("<schema/>")
        self.assertEqual(len(schema), 0)
        self.assertEqual(schema.getchildnames(), [])
        self.assertRaises(IndexError,
                          lambda schema=schema: schema[0])
        self.assertRaises(ZConfig.ConfigurationError,
                          schema.getinfo, "foo")

    def test_simple(self):
        schema, conf = self.load_both("simple.xml", "simple.conf")
        eq = self.assertEqual
        eq(conf.var1, 'abc')
        eq(conf.int_var, 12)
        eq(conf.float_var, 12.02)
        eq(conf.neg_int, -2)

        check = self.assert_
        check(conf.true_var_1)
        check(conf.true_var_2)
        check(conf.true_var_3)
        check(not conf.false_var_1)
        check(not conf.false_var_2)
        check(not conf.false_var_3)

    def test_app_datatype(self):
        dtname = __name__ + ".uppercase"
        schema = self.load_schema_text(
            "<schema>"
            "  <key name='a' datatype='%s'/>"
            "  <key name='b' datatype='%s' default='abc'/>"
            "  <multikey name='c' datatype='%s'>"
            "    <default>abc</default>"
            "    <default>abc</default>"
            "    </multikey>"
            "  <multikey name='d' datatype='%s'>"
            "    <default>not</default>"
            "    <default>lower</default>"
            "    <default>case</default>"
            "    </multikey>"
            "</schema>"
            % (dtname, dtname, dtname, dtname))
        conf = self.load_config_text(schema,
                                     "a qwerty\n"
                                     "c upp\n"
                                     "c er \n"
                                     "c case\n")
        eq = self.assertEqual
        eq(conf.a, 'QWERTY')
        eq(conf.b, 'ABC')
        eq(conf.c, ['UPP', 'ER', 'CASE'])
        eq(conf.d, ['NOT', 'LOWER', 'CASE'])

    def test_app_sectiontype(self):
        schema = self.load_schema_text(
            "<schema datatype='.appsection' prefix='%s'>"
            "  <sectiontype type='foo' datatype='.MySection'>"
            "    <key name='sample' datatype='integer' default='345'/>"
            "    </sectiontype>"
            "  <section name='sect' type='foo' />"
            "</schema>"
            % __name__)
        conf = self.load_config_text(schema,
                                     "<foo sect>\n"
                                     "  sample 42\n"
                                     "</foo>")
        self.assert_(isinstance(conf, MySection))
        self.assertEqual(conf.length, 1)
        o1 = conf.conf[0]
        self.assert_(isinstance(o1, MySection))
        self.assertEqual(o1.length, 1)
        self.assertEqual(o1.conf.sample, 42)
        o2 = conf.conf.sect
        self.assert_(o1 is o2)

    def test_empty_sections(self):
        schema = self.load_schema_text(
            "<schema>"
            "  <sectiontype type='section'/>"
            "  <section type='section' name='s1'/>"
            "  <section type='section' name='s2'/>"
            "</schema>")
        conf = self.load_config_text(schema,
                                     "<section s1>\n"
                                     "</section>\n"
                                     "<section s2/>")
        self.assert_(conf.s1 is not None)
        self.assert_(conf.s2 is not None)

    def test_deeply_nested_sections(self):
        schema = self.load_schema_text(
            "<schema>"
            "  <sectiontype type='type1'>"
            "    <key name='key' default='type1-value'/>"
            "    </sectiontype>"
            "  <sectiontype type='type2'>"
            "    <key name='key' default='type2-value'/>"
            "    <section name='sect' type='type1'/>"
            "    </sectiontype>"
            "  <sectiontype type='type3'>"
            "    <key name='key' default='type3-value'/>"
            "    <section name='sect' type='type2'/>"
            "    </sectiontype>"
            "  <section name='sect' type='type3'/>"
            "</schema>")
        conf = self.load_config_text(schema,
                                     "<type3 sect>\n"
                                     "  key sect3-value\n"
                                     "  <type2 sect>\n"
                                     "    key sect2-value\n"
                                     "    <type1 sect/>\n"
                                     "  </type2>\n"
                                     "</type3>")
        eq = self.assertEqual
        eq(conf.sect.sect.sect.key, "type1-value")
        eq(len(conf.sect.sect.sect), 1)
        eq(conf.sect.sect.key, "sect2-value")
        eq(len(conf.sect.sect), 2)
        eq(conf.sect.key, "sect3-value")
        eq(len(conf.sect), 2)

    def test_multivalued_keys(self):
        schema = self.load_schema_text(
            "<schema handler='def'>"
            "  <multikey name='a' handler='ABC' />"
            "  <multikey name='b' datatype='integer'>"
            "    <default>1</default>"
            "    <default>2</default>"
            "  </multikey>"
            "  <multikey name='c' datatype='integer'>"
            "    <default>3</default>"
            "    <default>4</default>"
            "    <default>5</default>"
            "  </multikey>"
            "  <multikey name='d' />"
            "</schema>")
        conf = self.load_config_text(schema,
                                     "a foo\n"
                                     "a bar\n"
                                     "c 41\n"
                                     "c 42\n"
                                     "c 43\n",
                                     num_handlers=2)
        L = []
        self.handlers({'abc': L.append,
                       'DEF': L.append})
        self.assertEqual(L, [['foo', 'bar'], conf])
        L = []
        self.handlers({'abc': None,
                       'DEF': L.append})
        self.assertEqual(L, [conf])
        self.assertEqual(conf.a, ['foo', 'bar'])
        self.assertEqual(conf.b, [1, 2])
        self.assertEqual(conf.c, [41, 42, 43])
        self.assertEqual(conf.d, [])

    def test_key_default_element(self):
        self.assertRaises(ZConfig.SchemaError, self.load_schema_text,
                          "<schema>"
                          "  <key name='name'>"
                          "    <default>text</default>"
                          "  </key>"
                          "</schema>")

    def test_bad_handler_maps(self):
        schema = self.load_schema_text(
            "<schema>"
            "  <key name='a' handler='abc'/>"
            "  <key name='b' handler='def'/>"
            "</schema>")
        conf = self.load_config_text(schema, "a foo\n b bar",
                                     num_handlers=2)
        self.assertRaises(ZConfig.ConfigurationError,
                          self.handlers, {'abc': id, 'ABC': id, 'def': id})
        self.assertRaises(ZConfig.ConfigurationError,
                          self.handlers, {})

    def test_handler_ordering(self):
        schema = self.load_schema_text(
            "<schema handler='c'>"
            "  <sectiontype type='inner'>"
            "  </sectiontype>"
            "  <sectiontype type='outer'>"
            "    <section type='inner' name='sect-inner' handler='a'/>"
            "  </sectiontype>"
            "  <section type='outer' name='sect-outer' handler='b'/>"
            "</schema>")
        conf = self.load_config_text(schema,
                                     "<outer sect-outer>\n"
                                     "  <inner sect-inner/>\n"
                                     "</outer>",
                                     num_handlers=3)
        L = []
        self.handlers({'a': L.append,
                       'b': L.append,
                       'c': L.append})
        outer = conf.sect_outer
        inner = outer.sect_inner
        self.assertEqual(L, [inner, outer, conf])

    def test_duplicate_section_names(self):
        schema = self.load_schema_text(
            "<schema>"
            "  <sectiontype type='sect'/>"
            "  <sectiontype type='nesting'>"
            "    <section name='a' type='sect'/>"
            "    </sectiontype>"
            "  <section name='a' type='nesting'/>"
            "</schema>")
        self.assertRaises(ZConfig.ConfigurationError,
                          self.load_config_text,
                          schema, "<sect a/>\n<sect a/>\n")
        conf = self.load_config_text(schema,
                                     "<nesting a>\n"
                                     "  <sect a/>\n"
                                     "</nesting>")

    def test_disallowed_duplicate_attribute(self):
        self.assertRaises(ZConfig.SchemaError,
                          self.load_schema_text,
                          "<schema>"
                          "  <key name='a'/>"
                          "  <key name='b' attribute='a'/>"
                          "</schema>")

    def test_unknown_datatype_name(self):
        self.assertRaises(ZConfig.SchemaError,
                          self.load_schema_text, "<schema datatype='foobar'/>")

    def test_load_sectiongroup(self):
        schema = self.load_schema_text(
            "<schema>"
            "  <sectiongroup type='group'>"
            "    <sectiontype type='t1'>"
            "      <key name='k1' default='default1'/>"
            "      </sectiontype>"
            "    <sectiontype type='t2'>"
            "      <key name='k2' default='default2'/>"
            "      </sectiontype>"
            "    </sectiongroup>"
            "  <multisection name='*' type='group' attribute='g'/>"
            "</schema>")
        # check the types that get defined
        t = schema.gettype("group")
        self.assert_(t.istypegroup())
        t1 = schema.gettype("t1")
        self.assert_(not t1.istypegroup())
        self.assert_(t.gettype("t1") is t1)
        t2 = schema.gettype("t2")
        self.assert_(not t2.istypegroup())
        self.assert_(t.gettype("t2") is t2)
        self.assertRaises(ZConfig.ConfigurationError, t.gettype, "group")
        self.assert_(t1 is not t2)
        # try loading a config that relies on this schema
        conf = self.load_config_text(schema,
                                     "<t1/>\n"
                                     "<t1>\n k1 value1\n </t1>\n"
                                     "<t2/>\n"
                                     "<t2>\n k2 value2\n </t2>\n")
        eq = self.assertEqual
        eq(len(conf.g), 4)
        eq(conf.g[0].k1, "default1")
        eq(conf.g[1].k1, "value1")
        eq(conf.g[2].k2, "default2")
        eq(conf.g[3].k2, "value2")

        # white box:
        self.assert_(conf.g[0]._type is t1)
        self.assert_(conf.g[1]._type is t1)
        self.assert_(conf.g[2]._type is t2)
        self.assert_(conf.g[3]._type is t2)

    def test_arbitrary_key(self):
        schema = self.load_schema_text(
            "<schema>"
            "  <key name='+' required='yes' attribute='keymap'"
            "       datatype='integer'/>"
            "</schema>")
        conf = self.load_config_text(schema, "some-key 42")
        self.assertEqual(conf.keymap, {'some-key': 42})

    def test_arbitrary_multikey(self):
        schema = self.load_schema_text(
            "<schema>"
            "  <multikey name='+' required='yes' attribute='keymap'"
            "            datatype='integer'/>"
            "</schema>")
        conf = self.load_config_text(schema, "some-key 42\n some-key 43")
        self.assertEqual(conf.keymap, {'some-key': [42, 43]})

    def test_arbitrary_keys_with_others(self):
        schema = self.load_schema_text(
            "<schema>"
            "  <key name='k1' default='v1'/>"
            "  <key name='k2' default='2' datatype='integer'/>"
            "  <key name='+' required='yes' attribute='keymap'"
            "       datatype='integer'/>"
            "</schema>")
        conf = self.load_config_text(schema, "some-key 42 \n k2 3")
        self.assertEqual(conf.k1, 'v1')
        self.assertEqual(conf.k2, 3)
        self.assertEqual(conf.keymap, {'some-key': 42})

    def test_arbitrary_key_missing(self):
        schema = self.load_schema_text(
            "<schema>"
            "  <key name='+' required='yes' attribute='keymap' />"
            "</schema>")
        self.assertRaises(ZConfig.ConfigurationError,
                          self.load_config_text, schema, "# empty config file")

    def test_arbitrary_key_bad_schema(self):
        self.assertRaises(ZConfig.SchemaError,
                          self.load_schema_text,
                          "<schema>"
                          "  <key name='+' attribute='attr1'/>"
                          "  <key name='+' attribute='attr2'/>"
                          "</schema>")

    def test_getrequiredtypes(self):
        schema = self.load_schema("library.xml")
        self.assertEqual(schema.getrequiredtypes(), [])

        schema = self.load_schema_text(
            "<schema type='top'>"
            "  <sectiontype type='used'/>"
            "  <sectiontype type='unused'/>"
            "  <section type='used' name='a'/>"
            "</schema>")
        L = schema.getrequiredtypes()
        L.sort()
        self.assertEqual(L, ["top", "used"])

    def test_getunusedtypes(self):
        schema = self.load_schema("library.xml")
        L = schema.getunusedtypes()
        L.sort()
        self.assertEqual(L, ["type-a", "type-b"])

        schema = self.load_schema_text(
            "<schema type='top'>"
            "  <sectiontype type='used'/>"
            "  <sectiontype type='unused'/>"
            "  <section type='used' name='a'/>"
            "</schema>")
        self.assertEqual(schema.getunusedtypes(), ["unused"])

    def test_section_value_mutation(self):
        schema, conf = self.load_both("simple.xml", "simple.conf")
        orig = conf.empty
        new = []
        conf.empty = new
        self.assert_(conf[0] is new)

    def test_simple_anonymous_section(self):
        schema = self.load_schema_text(
            "<schema>"
            "  <sectiontype type='sect'>"
            "    <key name='key' default='value'/>"
            "  </sectiontype>"
            "  <section name='*' type='sect' attribute='attr'/>"
            "</schema>")
        conf = self.load_config_text(schema, "<sect/>")
        self.assertEqual(conf.attr.key, "value")

    def test_simple_anynamed_section(self):
        schema = self.load_schema_text(
            "<schema>"
            "  <sectiontype type='sect'>"
            "    <key name='key' default='value'/>"
            "  </sectiontype>"
            "  <section name='+' type='sect' attribute='attr'/>"
            "</schema>")
        conf = self.load_config_text(schema, "<sect name/>")
        self.assertEqual(conf.attr.key, "value")
        self.assertEqual(conf.attr.getSectionName(), "name")

        # if we omit the name, it's an error
        self.assertRaises(ZConfig.ConfigurationError,
                          self.load_config_text, schema, "<sect/>")

    def test_nested_abstract_sectiontype(self):
        schema = self.load_schema_text(
            "<schema>"
            "  <sectiongroup type='abstract'>"
            "    <sectiontype type='t1'/>"
            "    <sectiontype type='t2'>"
            "      <section type='abstract' name='s1'/>"
            "    </sectiontype>"
            "  </sectiongroup>"
            "  <section type='abstract' name='*' attribute='s2'/>"
            "</schema>")
        conf = self.load_config_text(schema, "<t2>\n <t1 s1/>\n</t2>")

    def test_reserved_attribute_prefix(self):
        template = ("<schema>\n"
                    "  <sectiontype type='s'/>\n"
                    "  %s\n"
                    "</schema>")
        def check(thing, self=self, template=template):
            text = template % thing
            self.assertRaises(ZConfig.SchemaError,
                              self.load_schema_text, text)

        check("<key name='a' attribute='getSection'/>")
        check("<key name='a' attribute='getSectionThing'/>")
        check("<multikey name='a' attribute='getSection'/>")
        check("<multikey name='a' attribute='getSectionThing'/>")
        check("<section type='s' name='*' attribute='getSection'/>")
        check("<section type='s' name='*' attribute='getSectionThing'/>")
        check("<multisection type='s' name='*' attribute='getSection'/>")
        check("<multisection type='s' name='*' attribute='getSectionThing'/>")


def test_suite():
    return unittest.makeSuite(SchemaTestCase)

if __name__ == '__main__':
    unittest.main(defaultTest='test_suite')


=== Added File Zope/lib/python/ZConfig/tests/test_subst.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Tests of the string interpolation module."""

# This is needed to support Python 2.1.
from __future__ import nested_scopes

import unittest

from ZConfig import SubstitutionReplacementError, SubstitutionSyntaxError
from ZConfig.substitution import isname, substitute


class SubstitutionTestCase(unittest.TestCase):
    def test_simple_names(self):
        d = {"name": "value",
             "name1": "abc",
             "name_": "def",
             "_123": "ghi"}
        def check(s, v):
            self.assertEqual(substitute(s, d), v)
        check("$name", "value")
        check(" $name ", " value ")
        check("${name}", "value")
        check(" ${name} ", " value ")
        check("$name$name", "valuevalue")
        check("$name1$name", "abcvalue")
        check("$name_$name", "defvalue")
        check("$_123$name", "ghivalue")
        check("$name $name", "value value")
        check("$name1 $name", "abc value")
        check("$name_ $name", "def value")
        check("$_123 $name", "ghi value")
        check("splat", "splat")
        check("$$", "$")
        check("$$$name$$", "$value$")

    def test_undefined_names(self):
        d = {"name": "value"}
        self.assertRaises(SubstitutionReplacementError,
                          substitute, "$splat", d)
        self.assertRaises(SubstitutionReplacementError,
                          substitute, "$splat1", d)
        self.assertRaises(SubstitutionReplacementError,
                          substitute, "$splat_", d)

    def test_syntax_errors(self):
        d = {"name": "${next"}
        def check(s):
            self.assertRaises(SubstitutionSyntaxError,
                              substitute, s, d)
        check("${")
        check("${name")
        check("${1name}")
        check("${ name}")

    def test_edge_cases(self):
        # It's debatable what should happen for these cases, so we'll
        # follow the lead of the Bourne shell here.
        def check(s):
            self.assertRaises(SubstitutionSyntaxError,
                              substitute, s, {})
        check("$1")
        check("$")
        check("$ stuff")

    def test_non_nesting(self):
        d = {"name": "$value"}
        self.assertEqual(substitute("$name", d), "$value")

    def test_isname(self):
        self.assert_(isname("abc"))
        self.assert_(isname("abc_def"))
        self.assert_(isname("_abc"))
        self.assert_(isname("abc_"))
        self.assert_(not isname("abc-def"))
        self.assert_(not isname("-def"))
        self.assert_(not isname("abc-"))
        self.assert_(not isname(""))


def test_suite():
    return unittest.makeSuite(SubstitutionTestCase)

if __name__ == '__main__':
    unittest.main(defaultTest='test_suite')


=== Added File Zope/lib/python/ZConfig/tests/test_zopeschema.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Tests of ZConfig schemas."""

import unittest
import ZConfig

from ZConfig.tests.test_schema import BaseSchemaTest

try:
    True
except NameError:
    True = 1
    False = 0
    
class StreamHandler:
    pass

class Formatter:
    pass

def _assert(expr):
    if not expr:
        raise AssertionError, expr

def _get_arglist(s):
    pos = []
    kw = {}
    args = s.split(',')
    args = filter(None, args)
    while args:
        arg = args.pop(0)
        try:
            if '=' in arg:
                k,v=arg.split('=', 1)
                k = k.strip()
                v = v.strip()
                kw[k] = eval(v)
            else:
                arg = arg.strip()
                pos.append(eval(arg))
        except SyntaxError:
            if not args:
                raise
            args[0] = '%s, %s' % (arg, args[0])
    return pos, kw

def _get_classandargs(constructor):
    klass, args = parse_constructor(constructor)
    pos, kw = get_arglist(args)
    return klass, pos, kw

def _parse_constructor(value):
    parenmsg = (
        'Invalid constructor (unbalanced parenthesis in "%s")' % value
        )
    openparen = value.find('(')
    if openparen < 0:
        raise ValueError(parenmsg)
    klass = value[:openparen]
    if not value.endswith(')'):
        raise ValueError(parenmsg)
    arglist = value[openparen+1:-1]
    return klass, arglist

def _importer(name):
    if not "." in name:
        raise ValueError("unloadable datatype name: " + `name`)
    components = name.split('.')
    start = components[0]
    g = globals()
    package = __import__(start, g, g)
    modulenames = [start]
    for component in components[1:]:
        modulenames.append(component)
        try:
            package = getattr(package, component)
        except AttributeError:
            n = '.'.join(modulenames)
            package = __import__(n, g, g, component)
    return package

def ipaddr(value):
    if value is None:
        return
    import socket
    try:
        socket.gethostbyaddr(value)
    except socket.error:
        socket.gethostbyname(value)

def directory(value):
    _assert(os.path.isdir(value))
    return value

def dirname(value):
    _assert( os.path.exists(os.path.dirname(value)) )
    return value

def constructor(value):
    klass, arglist = _parse_constructor(value)
    _importer(klass)
    pos, kw = _get_arglist(arglist)
    return klass, pos, kw

class ZopeSchemaTestCase(BaseSchemaTest):

    # tests

    def test_defaultbug(self):
        schema = self.load_schema('zconfig:zope.xml')
        conf = self.load_config(schema, 'empty.conf')

    def test_load_populated(self):
        schema = self.load_schema('zconfig:zope.xml')
        conf = self.load_config(schema, 'zope-allpopulated.conf')
        self.assertEqual(conf.zope_home, '.')
        self.assertEqual(conf.instance_home, '.')
        self.assertEqual(conf.software_home, '.')
        self.assertEqual(conf.client_home, '.')
        self.assertEqual(conf.debug_mode, True)
        self.assertEqual(conf.effective_user, 'chrism')
        self.assertEqual(conf.enable_product_installation, True)
        self.assertEqual(conf.locale, None)
        self.assertEqual(conf.zserver_threads, 4)
        self.assertEqual(conf.python_check_interval, 500)
        self.assertEqual(conf.use_daemon_process, True)
        self.assertEqual(conf.zserver_read_only_mode, False)
        self.assertEqual(conf.pid_filename, 'Z2.pid')
        self.assertEqual(conf.lock_filename, 'Z2.lock')
        constructor = ('ZConfig.tests.test_zopeschema.StreamHandler', [], {})
        formatter   = ('ZConfig.tests.test_zopeschema.Formatter', [], {})
        self.assertEqual(conf.event.level, 10)
        self.assertEqual(conf.event.handlers[0].constructor, constructor)
        self.assertEqual(conf.event.handlers[0].formatter, formatter)
        self.assertEqual(conf.event.handlers[1].constructor, constructor)
        self.assertEqual(conf.event.handlers[1].formatter, formatter)
        self.assertEqual(conf.trace.level, 20)
        self.assertEqual(conf.trace.handlers[0].constructor, constructor)
        self.assertEqual(conf.trace.handlers[0].formatter, formatter)
        self.assertEqual(conf.access.level, 30)
        self.assertEqual(conf.access.handlers[0].constructor, constructor)
        self.assertEqual(conf.access.handlers[0].formatter, formatter)
        self.assertEqual(conf.structured_text_header_level, 3)
        self.assertEqual(conf.maximum_security_manager_stack_size, 100)
        self.assertEqual(conf.publisher_profile_file, 'bleah')
        self.assertEqual(conf.module, 'Zope')
        self.assertEqual(conf.cgi_environment_variables,
                         [['A','1'], ['B', '2']])
        self.assertEqual(conf.dns_ip_address, '127.0.0.1')
        self.assertEqual(conf.http_realm, 'Zope')
        servers = conf.servers
        for n in range(len(servers)):
            if n == 0:
                self.assertEqual(servers[n].port, 8080)
                self.assertEqual(servers[n].force_connection_close, False)
            if n == 1:
                self.assertEqual(servers[n].port, 8081)
                self.assertEqual(servers[n].force_connection_close, True)
            if n == 2:
                self.assertEqual(servers[n].port, 8021)
            if n == 3:
                self.assertEqual(servers[n].resource, '/foo/bar/fcgi.soc')
        self.assertEqual(conf.automatically_quote_dtml_request_data, True)
        self.assertEqual(conf.skip_authentication_checking, True)
        self.assertEqual(conf.skip_ownership_checking, True)
        self.assertEqual(conf.maximum_number_of_session_objects, 1000)
        self.assertEqual(conf.session_add_notify_script_path, '/flab')
        self.assertEqual(conf.session_delete_notify_script_path, '/flab')
        self.assertEqual(conf.session_timeout_minutes, 20)
        self.assertEqual(conf.suppress_all_access_rules, True)
        self.assertEqual(conf.suppress_all_site_roots, True)
        self.assertEqual(conf.database_quota_size, 100)
        self.assertEqual(conf.read_only_database, False)
        self.assertEqual(conf.zeo_client_name, 'chris')
        databases = conf.databases
        for n in range(len(databases)):
            if n == 0:
                self.assertEqual(databases[n].mount_point, '/')
                self.assertEqual(databases[n].storages[0].file_name, 'foo/bar')
            if n == 1:
                self.assertEqual(databases[n].mount_point, '/mount')
                self.assertEqual(databases[n].storages[0].file_name, 'foo/baz')
                self.assertEqual(databases[n].storages[1].file_name, 'bar/baz')
            self.assertEqual(databases[n].db_class, 'ZODB.DB')
            self.assertEqual(databases[n].cache_size, 5000)
            self.assertEqual(databases[n].pool_size, 7)
            self.assertEqual(databases[n].cache_deactivate_after, 60)
            self.assertEqual(databases[n].version_pool_size, 3)
            self.assertEqual(databases[n].version_cache_size, 100)
            self.assertEqual(databases[n].version_cache_deactivate_after, 10)

def test_suite():
    return unittest.makeSuite(ZopeSchemaTestCase)

if __name__ == '__main__':
    unittest.main(defaultTest='test_suite')


=== Zope/lib/python/ZConfig/tests/runtests.py 1.1.4.1 => 1.1.4.2 ===
--- Zope/lib/python/ZConfig/tests/runtests.py:1.1.4.1	Thu Oct 10 14:29:12 2002
+++ Zope/lib/python/ZConfig/tests/runtests.py	Fri Jan  3 10:52:01 2003
@@ -1,4 +1,17 @@
 #! /usr/bin/env python
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
 """Script to run all the regression tests for the ZConfig package."""
 
 import os