[Zope-Checkins] CVS: Packages/ZConfig/tests - test_config.py:1.2 test_datatypes.py:1.2 test_loader.py:1.2 test_schema.py:1.2 test_subst.py:1.2 test_zopeschema.py:1.2 __init__.py:1.2 runtests.py:1.2 testConfig.py:NONE testSubstitution.py:NONE

Fred L. Drake, Jr. fred@zope.com
Fri, 3 Jan 2003 16:06:31 -0500


Update of /cvs-repository/Packages/ZConfig/tests
In directory cvs.zope.org:/tmp/cvs-serv11713/tests

Modified Files:
	__init__.py runtests.py 
Added Files:
	test_config.py test_datatypes.py test_loader.py test_schema.py 
	test_subst.py test_zopeschema.py 
Removed Files:
	testConfig.py testSubstitution.py 
Log Message:
Merge the zconfig-schema-devel-branch into the trunk for the ZConfig package.
Copyright notices get 2003 added as well.

The zconfig-schema-devel-branch should no longer be used.


=== Packages/ZConfig/tests/test_config.py 1.1 => 1.2 ===
--- /dev/null	Fri Jan  3 16:06:30 2003
+++ Packages/ZConfig/tests/test_config.py	Fri Jan  3 16:05:56 2003
@@ -0,0 +1,287 @@
+##############################################################################
+#
+# Copyright (c) 2002, 2003 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')


=== Packages/ZConfig/tests/test_datatypes.py 1.1 => 1.2 ===
--- /dev/null	Fri Jan  3 16:06:30 2003
+++ Packages/ZConfig/tests/test_datatypes.py	Fri Jan  3 16:05:56 2003
@@ -0,0 +1,283 @@
+##############################################################################
+#
+# Copyright (c) 2002, 2003 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 sys
+import socket
+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_byte_size(self):
+        eq = self.assertEqual
+        raises = self.assertRaises
+        convert = self.types.get('byte-size')
+        eq(convert('128'), 128)
+        eq(convert('128KB'), 128*1024)
+        eq(convert('128MB'), 128*1024*1024)
+        eq(convert('128GB'), 128*1024*1024*1024L)
+        raises(ValueError, convert, '128TB')
+        eq(convert('128'), 128)
+        eq(convert('128kb'), 128*1024)
+        eq(convert('128mb'), 128*1024*1024)
+        eq(convert('128gb'), 128*1024*1024*1024L)
+        raises(ValueError, convert, '128tb')
+
+    def test_time_interval(self):
+        eq = self.assertEqual
+        raises = self.assertRaises
+        convert = self.types.get('time-interval')
+        eq(convert('120'), 120)
+        eq(convert('120S'), 120)
+        eq(convert('120M'), 120*60)
+        eq(convert('120H'), 120*60*60)
+        eq(convert('120D'), 120*60*60*24)
+        raises(ValueError, convert, '120W')
+        eq(convert('120'), 120)
+        eq(convert('120s'), 120)
+        eq(convert('120m'), 120*60)
+        eq(convert('120h'), 120*60*60)
+        eq(convert('120d'), 120*60*60*24)
+        raises(ValueError, convert, '120w')
+
+
+def test_suite():
+    return unittest.makeSuite(DatatypeTestCase)
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


=== Packages/ZConfig/tests/test_loader.py 1.1 => 1.2 ===
--- /dev/null	Fri Jan  3 16:06:30 2003
+++ Packages/ZConfig/tests/test_loader.py	Fri Jan  3 16:05:56 2003
@@ -0,0 +1,131 @@
+##############################################################################
+#
+# Copyright (c) 2002, 2003 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 unittest
+import urlparse
+
+from StringIO import StringIO
+
+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_with_cache(self):
+        loader = ZConfig.loader.SchemaLoader()
+        url1 = urlparse.urljoin(CONFIG_BASE, "library.xml")
+        schema1 = loader.loadURL(url1)
+        sio = 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_import_errors(self):
+        # must specify exactly one of package or src
+        self.assertRaises(ZConfig.SchemaError, ZConfig.loadSchemaFile,
+                          StringIO("<schema><import/></schema>"))
+        self.assertRaises(ZConfig.SchemaError, ZConfig.loadSchemaFile,
+                          StringIO("<schema>"
+                                   "  <import src='library.xml'"
+                                   "          package='ZConfig'/>"
+                                   "</schema>"))
+
+    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')


=== Packages/ZConfig/tests/test_schema.py 1.1 => 1.2 === (428/528 lines abridged)
--- /dev/null	Fri Jan  3 16:06:30 2003
+++ Packages/ZConfig/tests/test_schema.py	Fri Jan  3 16:05:56 2003
@@ -0,0 +1,525 @@
+##############################################################################
+#
+# Copyright (c) 2002, 2003 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)

[-=- -=- -=- 428 lines omitted -=- -=- -=-]

+            "    <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')


=== Packages/ZConfig/tests/test_subst.py 1.1 => 1.2 ===
--- /dev/null	Fri Jan  3 16:06:30 2003
+++ Packages/ZConfig/tests/test_subst.py	Fri Jan  3 16:05:56 2003
@@ -0,0 +1,97 @@
+##############################################################################
+#
+# Copyright (c) 2002, 2003 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')


=== Packages/ZConfig/tests/test_zopeschema.py 1.1 => 1.2 ===
--- /dev/null	Fri Jan  3 16:06:30 2003
+++ Packages/ZConfig/tests/test_zopeschema.py	Fri Jan  3 16:05:56 2003
@@ -0,0 +1,208 @@
+##############################################################################
+#
+# Copyright (c) 2002, 2003 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')


=== Packages/ZConfig/tests/__init__.py 1.1 => 1.2 ===
--- Packages/ZConfig/tests/__init__.py:1.1	Tue Oct  8 17:42:17 2002
+++ Packages/ZConfig/tests/__init__.py	Fri Jan  3 16:05:56 2003
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2002 Zope Corporation and Contributors.
+# Copyright (c) 2002, 2003 Zope Corporation and Contributors.
 # All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,


=== Packages/ZConfig/tests/runtests.py 1.1 => 1.2 ===
--- Packages/ZConfig/tests/runtests.py:1.1	Thu Oct 10 11:13:08 2002
+++ Packages/ZConfig/tests/runtests.py	Fri Jan  3 16:05:56 2003
@@ -1,4 +1,17 @@
 #! /usr/bin/env python
+##############################################################################
+#
+# Copyright (c) 2002, 2003 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

=== Removed File Packages/ZConfig/tests/testConfig.py ===

=== Removed File Packages/ZConfig/tests/testSubstitution.py ===