[Zope3-checkins] CVS: Zope3/src/zope/publisher/tests - __init__.py:1.2 basetestiapplicationrequest.py:1.2 basetestipublicationrequest.py:1.2 basetestipublisherrequest.py:1.2 httprequest.py:1.2 publication.py:1.2 test_baserequest.py:1.2 test_browserlanguages.py:1.2 test_browserrequest.py:1.2 test_browserresponse.py:1.2 test_http.py:1.2 test_httpcharsets.py:1.2 test_ipublication.py:1.2 test_mapply.py:1.2 test_publisher.py:1.2 test_requestdataproperty.py:1.2 test_xmlrpcmethodpublisher.py:1.2 test_xmlrpcrequest.py:1.2 views.py:1.2 xmlrpcviews.py:1.2

Jim Fulton jim@zope.com
Wed, 25 Dec 2002 09:15:50 -0500


Update of /cvs-repository/Zope3/src/zope/publisher/tests
In directory cvs.zope.org:/tmp/cvs-serv20790/src/zope/publisher/tests

Added Files:
	__init__.py basetestiapplicationrequest.py 
	basetestipublicationrequest.py basetestipublisherrequest.py 
	httprequest.py publication.py test_baserequest.py 
	test_browserlanguages.py test_browserrequest.py 
	test_browserresponse.py test_http.py test_httpcharsets.py 
	test_ipublication.py test_mapply.py test_publisher.py 
	test_requestdataproperty.py test_xmlrpcmethodpublisher.py 
	test_xmlrpcrequest.py views.py xmlrpcviews.py 
Log Message:
Grand renaming:

- Renamed most files (especially python modules) to lower case.

- Moved views and interfaces into separate hierarchies within each
  project, where each top-level directory under the zope package
  is a separate project.

- Moved everything to src from lib/python.

  lib/python will eventually go away. I need access to the cvs
  repository to make this happen, however.

There are probably some bits that are broken. All tests pass
and zope runs, but I haven't tried everything. There are a number
of cleanups I'll work on tomorrow.



=== Zope3/src/zope/publisher/tests/__init__.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/__init__.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.


=== Zope3/src/zope/publisher/tests/basetestiapplicationrequest.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/basetestiapplicationrequest.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+import sys
+from zope.interface.verify import verifyObject
+from zope.publisher.interfaces import IApplicationRequest
+
+from zope.interface.common.tests.basemapping import BaseTestIEnumerableMapping
+
+from zope.interface.common.tests.basemapping \
+     import testIEnumerableMapping, testIReadMapping
+
+
+class BaseTestIApplicationRequest(BaseTestIEnumerableMapping):
+    def testVerifyIApplicationRequest(self):
+        verifyObject(IApplicationRequest, self._Test__new())
+
+    def testHaveCustomTestsForIApplicationRequest(self):
+        # Make sure that tests are defined for things we can't test here
+        self.test_IApplicationRequest_body
+
+    def testEnvironment(self):
+        request = self._Test__new(foo='Foo', bar='Bar')
+
+        try:
+            request.environment = {}
+        except AttributeError:
+            pass
+        else:
+            raise "Shouldn't be able to set environment"
+
+        environment = request.environment
+
+        testIReadMapping(self, environment,
+                         {'foo': 'Foo', 'bar': 'Bar'},
+                         ['splat'])


=== Zope3/src/zope/publisher/tests/basetestipublicationrequest.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/basetestipublicationrequest.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,66 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+import sys
+from zope.interface.verify import verifyObject
+from zope.publisher.interfaces import IPublicationRequest
+
+
+class BaseTestIPublicationRequest:
+    def testVerifyIPublicationRequest(self):
+        verifyObject(IPublicationRequest, self._Test__new())
+
+    def testHaveCustomTestsForIPublicationRequest(self):
+        # Make sure that tests are defined for things we can't test here
+        self.test_IPublicationRequest_getPositionalArguments
+
+    def testTraversalStack(self):
+        request = self._Test__new()
+        stack = ['Engineering', 'ZopeCorp']
+        request.setTraversalStack(stack)
+        self.assertEqual(list(request.getTraversalStack()), stack)
+
+    def testHoldCloseAndGetResponse(self):
+        request = self._Test__new()
+
+        response = request.response
+        rcresponse = sys.getrefcount(response)
+
+        resource = object()
+        rcresource = sys.getrefcount(resource)
+
+        request.hold(resource)
+
+        self.failUnless(sys.getrefcount(resource) > rcresource)
+
+        request.close()
+        self.failUnless(sys.getrefcount(response) < rcresponse)
+        self.assertEqual(sys.getrefcount(resource), rcresource)
+
+    def testSkinManagement(self):
+        request = self._Test__new()
+        self.assertEqual(request.getPresentationSkin(), '')
+        skin = 'terse'
+        request.setViewSkin(skin)
+        self.assertEqual(request.getPresentationSkin(), skin)
+
+    def test_getPresentationType(self):
+        type = self._Test__expectedViewType()
+        request = self._Test__new()
+        self.assertEqual(request.getPresentationType(), type)


=== Zope3/src/zope/publisher/tests/basetestipublisherrequest.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/basetestipublisherrequest.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,41 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+import sys
+from zope.interface.verify import verifyObject
+from zope.publisher.interfaces import IPublisherRequest
+
+
+class BaseTestIPublisherRequest:
+    def testVerifyIPublisherRequest(self):
+        verifyObject(IPublisherRequest, self._Test__new())
+
+    def testHaveCustomTestsForIPublisherRequest(self):
+        # Make sure that tests are defined for things we can't test here
+        self.test_IPublisherRequest_retry
+        self.test_IPublisherRequest_traverse
+        self.test_IPublisherRequest_processInputs
+
+    def testPublicationManagement(self):
+        from zope.publisher.tests.publication import TestPublication
+
+        request = self._Test__new()
+        publication = TestPublication()
+        request.setPublication(publication)
+        self.assertEqual(id(request.publication), id(publication))


=== Zope3/src/zope/publisher/tests/httprequest.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/httprequest.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,47 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+"""
+Test request for writing tests that need HTTP requests.
+
+Note that this is used by tests in other packages.
+
+$Id$
+"""
+
+from StringIO import StringIO
+
+from zope.publisher.http import HTTPRequest
+
+_testEnv =  {
+    'SERVER_URL':         'http://foobar.com',
+    'HTTP_HOST':          'foobar.com',
+    'CONTENT_LENGTH':     '0',
+    'GATEWAY_INTERFACE':  'Test/1.0',
+}
+
+class TestRequest(HTTPRequest):
+
+    def __init__(self, body_instream=None, outstream=None, environ=None, **kw):
+        if body_instream is None:
+            body_instream = StringIO('')
+        if outstream is None:
+            outstream = StringIO()
+
+
+        env = {}
+        env.update(_testEnv)
+        if environ: env.update(environ)
+        env.update(kw)
+
+        super(TestRequest, self).__init__(body_instream, outstream, env)


=== Zope3/src/zope/publisher/tests/publication.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/publication.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,68 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+
+from zope.publisher.interfaces import IPublication
+
+class TestPublication:
+
+    __implements__ =  IPublication
+
+    def afterCall(self, request):
+        '''See interface IPublication'''
+        self._afterCall = getattr(self, '_afterCall', 0) + 1
+
+    def traverseName(self, request, ob, name, check_auth=1):
+        '''See interface IPublication'''
+        return getattr(ob, name, "%s value" % name)
+
+    def afterTraversal(self, request, ob):
+        '''See interface IPublication'''
+        self._afterTraversal = getattr(self, '_afterTraversal', 0) + 1
+
+    def beforeTraversal(self, request):
+        '''See interface IPublication'''
+        self._beforeTraversal = getattr(self, '_beforeTraversal', 0) + 1
+
+    def callObject(self, request, ob):
+        '''See interface IPublication'''
+        return ob(request)
+
+    def getApplication(self, request):
+        '''See interface IPublication'''
+        return app
+
+    def handleException(self, object, request, exc_info, retry_allowed=1):
+        '''See interface IPublication'''
+        try:
+            request.response.setBody("%s: %s" % (exc_info[:2]))
+        finally:
+            exc_info = 0
+
+
+    def callTraversalHooks(self, request, ob):
+        '''See interface IPublication'''
+        self._callTraversalHooks = getattr(self, '_callTraversalHooks', 0) + 1
+
+
+class App:
+
+    def __init__(self, name):
+        self.name = name
+
+    def index_html(self, request):
+        return self
+
+app = App('')
+app.ZopeCorp = App('ZopeCorp')
+app.ZopeCorp.Engineering = App('Engineering')


=== Zope3/src/zope/publisher/tests/test_baserequest.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/test_baserequest.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,94 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from unittest import TestCase, TestSuite, main, makeSuite
+from zope.testing.cleanup import CleanUp # Base class w registry cleanup
+
+from zope.publisher.tests.basetestipublicationrequest \
+     import BaseTestIPublicationRequest
+
+from zope.publisher.tests.basetestipublisherrequest \
+     import BaseTestIPublisherRequest
+
+from zope.publisher.tests.basetestiapplicationrequest \
+     import BaseTestIApplicationRequest
+
+from StringIO import StringIO
+
+class TestBaseRequest(BaseTestIPublicationRequest,
+                      BaseTestIApplicationRequest,
+                      BaseTestIPublisherRequest,
+                      TestCase):
+
+    def _Test__new(self, **kw):
+        from zope.publisher.base import BaseRequest
+        return BaseRequest(StringIO(''), StringIO(), kw)
+
+    def _Test__expectedViewType(self):
+        return None # we don't expect
+
+    def test_IApplicationRequest_body(self):
+        from zope.publisher.base import BaseRequest
+
+        request = BaseRequest(StringIO('spam'), StringIO(), {})
+        self.assertEqual(request.body, 'spam')
+
+        request = BaseRequest(StringIO('spam'), StringIO(), {})
+        self.assertEqual(request.bodyFile.read(), 'spam')
+
+    def test_IPublicationRequest_getPositionalArguments(self):
+        self.assertEqual(self._Test__new().getPositionalArguments(), ())
+
+    def test_IPublisherRequest_retry(self):
+        self.assertEqual(self._Test__new().supportsRetry(), 0)
+
+    def test_IPublisherRequest_traverse(self):
+        from zope.publisher.tests.publication import TestPublication
+        request = self._Test__new()
+        request.setPublication(TestPublication())
+        app = request.publication.getApplication(request)
+
+        request.setTraversalStack([])
+        self.assertEqual(request.traverse(app).name, '')
+        request.setTraversalStack(['ZopeCorp'])
+        self.assertEqual(request.traverse(app).name, 'ZopeCorp')
+        request.setTraversalStack(['Engineering', 'ZopeCorp'])
+        self.assertEqual(request.traverse(app).name, 'Engineering')
+
+    def test_IPublisherRequest_processInputs(self):
+        self._Test__new().processInputs()
+
+
+    # Needed by BaseTestIEnumerableMapping tests:
+    def _IEnumerableMapping__stateDict(self):
+        return {'id': 'ZopeOrg', 'title': 'Zope Community Web Site',
+                'greet': 'Welcome to the Zope Community Web site'}
+
+    def _IEnumerableMapping__sample(self):
+        return self._Test__new(**(self._IEnumerableMapping__stateDict()))
+
+    def _IEnumerableMapping__absentKeys(self):
+        return 'foo', 'bar'
+
+
+def test_suite():
+    return makeSuite(TestBaseRequest)
+
+if __name__=='__main__':
+    main(defaultTest='test_suite')


=== Zope3/src/zope/publisher/tests/test_browserlanguages.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/test_browserlanguages.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,38 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+import unittest, sys
+
+class Test(unittest.TestCase):
+
+    def test(self):
+        request = {'HTTP_ACCEPT_LANGUAGE': 'da, en-gb;q=0.8, en;q=0.7'}
+
+        from zope.publisher.browser import BrowserLanguages
+
+        browser_languages = BrowserLanguages(request)
+
+        self.assertEqual(list(browser_languages.getPreferredLanguages()),
+                         ['da', 'en-gb', 'en'])
+
+    # XXX Add support for quality statements
+
+
+
+
+def test_suite():
+    loader=unittest.TestLoader()
+    return loader.loadTestsFromTestCase(Test)
+
+if __name__=='__main__':
+    unittest.TextTestRunner().run(test_suite())


=== Zope3/src/zope/publisher/tests/test_browserrequest.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/test_browserrequest.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,263 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+import unittest
+
+from zope.component.tests.placelesssetup import PlacelessSetup
+from zope.component.adapter import provideAdapter
+
+from zope.interfaces.i18n import IUserPreferredCharsets
+
+from zope.publisher.http import IHTTPRequest
+from zope.publisher.http import HTTPCharsets
+from zope.publisher.browser import BrowserRequest
+from zope.publisher.browser import BrowserResponse
+from zope.publisher.interfaces import NotFound
+
+from zope.publisher.base import DefaultPublication
+from zope.publisher.interfaces.browser import IBrowserPresentation
+
+from StringIO import StringIO
+
+from zope.publisher.tests.test_http import HTTPTests
+
+from zope.publisher.publish import publish as publish_
+def publish(request):
+    publish_(request, handle_errors=0)
+
+class Publication(DefaultPublication):
+
+    def getDefaultTraversal(self, request, ob):
+        if hasattr(ob, 'browserDefault'):
+            return ob.browserDefault(request)
+        return ob, ()
+
+
+
+class BrowserTests(HTTPTests, PlacelessSetup):
+
+    _testEnv =  {
+        'PATH_INFO':           '/folder/item',
+        'QUERY_STRING':        'a=5&b:int=6',
+        'SERVER_URL':          'http://foobar.com',
+        'HTTP_HOST':           'foobar.com',
+        'CONTENT_LENGTH':      '0',
+        'HTTP_AUTHORIZATION':  'Should be in accessible',
+        'GATEWAY_INTERFACE':   'TestFooInterface/1.0',
+        'HTTP_OFF_THE_WALL':   "Spam 'n eggs",
+        'HTTP_ACCEPT_CHARSET': 'ISO-8859-1, UTF-8;q=0.66, UTF-16;q=0.33',
+    }
+
+    def setUp(self):
+        PlacelessSetup.setUp(self)
+        provideAdapter(IHTTPRequest, IUserPreferredCharsets, HTTPCharsets)
+
+        class AppRoot:
+            " "
+
+        class Folder:
+            " "
+
+        class Item:
+            " "
+            def __call__(self, a, b):
+                return "%s, %s" % (`a`, `b`)
+
+        class Item3:
+            " "
+            def __call__(self, *args):
+                return "..."
+
+        class View:
+            " "
+            def browserDefault(self, request):
+                return self, ['index']
+
+            def index(self, a, b):
+                " "
+                return "%s, %s" % (`a`, `b`)
+
+        class Item2:
+            " "
+            view = View()
+
+            def browserDefault(self, request):
+                return self, ['view']
+
+
+        self.app = AppRoot()
+        self.app.folder = Folder()
+        self.app.folder.item = Item()
+        self.app.folder.item2 = Item2()
+        self.app.folder.item3 = Item3()
+
+    def _createRequest(self, extra_env={}, body="", outstream=None):
+        env = self._testEnv.copy()
+        env.update(extra_env)
+        if len(body):
+            env['CONTENT_LENGTH'] = str(len(body))
+
+        publication = Publication(self.app)
+        if outstream is None:
+            outstream = StringIO()
+        instream = StringIO(body)
+        request = BrowserRequest(instream, outstream, env)
+        request.setPublication(publication)
+        return request
+
+    def testTraversalToItem(self):
+        res = self._publisherResults()
+        self.failUnlessEqual(
+            res,
+            "Status: 200 Ok\r\n"
+            "Content-Length: 7\r\n"
+            "Content-Type: text/plain;charset=utf-8\r\n"
+            "X-Powered-By: Zope (www.zope.org), Python (www.python.org)\r\n"
+            "\r\n"
+            "u'5', 6")
+
+    def testIPresentationRequest(self):
+        # test the IView request
+        r = self._createRequest()
+
+        self.failUnless( r.getPresentationType() is IBrowserPresentation)
+        self.assertEqual( r.getPresentationSkin(), '')
+        r.setViewSkin( 'morefoo' )
+        self.assertEqual( r.getPresentationSkin(), 'morefoo')
+
+    def testNoDefault(self):
+        request = self._createRequest()
+        response = request.response
+        publish(request)
+        self.failIf(response.getBase())
+
+    def testDefault(self):
+        extra = {'PATH_INFO': '/folder/item2'}
+        request = self._createRequest(extra)
+        response = request.response
+        publish(request)
+        self.assertEqual(response.getBase(),
+                         'http://foobar.com/folder/item2/view/index')
+
+    def testDefaultPOST(self):
+        extra = {'PATH_INFO': '/folder/item2', "REQUEST_METHOD": "POST"}
+        request = self._createRequest(extra, body='a=5&b:int=6')
+        response = request.response
+        publish(request)
+        self.assertEqual(response.getBase(),
+                         'http://foobar.com/folder/item2/view/index')
+
+    def testDefault2(self):
+        extra = {'PATH_INFO': '/folder/item2/view'}
+        request = self._createRequest(extra)
+        response = request.response
+        publish(request)
+        self.assertEqual(response.getBase(),
+                         'http://foobar.com/folder/item2/view/index')
+
+    def testDefault3(self):
+        extra = {'PATH_INFO': '/folder/item2/view/index'}
+        request = self._createRequest(extra)
+        response = request.response
+        publish(request)
+        self.failIf(response.getBase())
+
+    def testDefault4(self):
+        extra = {'PATH_INFO': '/folder/item2/view/'}
+        request = self._createRequest(extra)
+        response = request.response
+        publish(request)
+        self.failIf(response.getBase())
+
+    def testDefault6(self):
+        extra = {'PATH_INFO': '/folder/item2/'}
+        request = self._createRequest(extra)
+        response = request.response
+        publish(request)
+        self.assertEqual(response.getBase(),
+                         'http://foobar.com/folder/item2/view/index')
+
+    def testBadPath(self):
+        extra = {'PATH_INFO': '/folder/nothere/'}
+        request = self._createRequest(extra)
+        self.assertRaises(NotFound, publish, request)
+
+    def testBadPath2(self):
+        extra = {'PATH_INFO': '/folder%2Fitem2/'}
+        request = self._createRequest(extra)
+        self.assertRaises(NotFound, publish, request)
+
+    def testForm(self):
+        request = self._createRequest()
+        publish(request)
+        self.assertEqual(request.form,
+                         {u'a':u'5', u'b':6})
+
+    def testFormListTypes(self):
+        #extra = {'QUERY_STRING':'x.a:list:record=5&x.a:list:record=6'}
+        extra = {'QUERY_STRING':'a:list=5&a:list=6&b=1'}
+        request = self._createRequest(extra)
+        publish(request)
+        self.assertEqual(request.form, {u'a':[u'5',u'6'], u'b':u'1'})
+
+    def testFormListRecordTypes(self):
+        extra = {'QUERY_STRING':'a.x:list:record=5&a.x:list:record=6&b=1'}
+        request = self._createRequest(extra)
+        publish(request)
+        keys = request.form.keys()
+        keys.sort()
+        self.assertEqual(keys, [u'a',u'b'])
+        self.assertEqual(request.form[u'b'], u'1')
+        self.assertEqual(request.form[u'a'].keys(), [u'x'])
+        self.assertEqual(request.form[u'a'][u'x'], [u'5',u'6'])
+
+    def testFormListTypes2(self):
+        extra = {'QUERY_STRING':'a=5&a=6&b=1'}
+        request = self._createRequest(extra)
+        publish(request)
+        self.assertEqual(request.form, {'a':[u'5',u'6'], 'b':u'1'})
+
+    def testFormDefaults(self):
+        extra = {'QUERY_STRING':'a:default=10&a=6&b=1'}
+        request = self._createRequest(extra)
+        publish(request)
+        self.assertEqual(request.form, {u'a':u'6', u'b':u'1'})
+
+    def testFormDefaults2(self):
+        extra = {'QUERY_STRING':'a:default=10&b=1'}
+        request = self._createRequest(extra)
+        publish(request)
+        self.assertEqual(request.form, {u'a':u'10', u'b':u'1'})
+
+    def testFormFieldName(self):
+        extra = {'QUERY_STRING':'c+%2B%2F%3D%26c%3Aint=6',
+                 'PATH_INFO': '/folder/item3/'}
+        request = self._createRequest(extra)
+        publish(request)
+        self.assertEqual(request.form, {u'c +/=&c': 6})
+
+    def testFormFieldValue(self):
+        extra = {'QUERY_STRING':'a=b+%2B%2F%3D%26b%3Aint',
+                 'PATH_INFO': '/folder/item3/'}
+        request = self._createRequest(extra)
+        publish(request)
+        self.assertEqual(request.form, {u'a':u'b +/=&b:int'})
+
+
+def test_suite():
+    loader = unittest.TestLoader()
+    return loader.loadTestsFromTestCase(BrowserTests)
+
+
+if __name__ == '__main__':
+    unittest.TextTestRunner().run( test_suite() )


=== Zope3/src/zope/publisher/tests/test_browserresponse.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/test_browserresponse.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,100 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+"""Browser response tests
+
+XXX longer description goes here.
+
+$Id$
+"""
+
+from unittest import TestCase, TestSuite, main, makeSuite
+from zope.publisher.browser import BrowserResponse
+from StringIO import StringIO
+
+# XXX Waaa need more tests
+
+class Test(TestCase):
+
+    def test_contentType_DWIM_in_setBody(self):
+        response = BrowserResponse(StringIO())
+        response.setBody(
+            """<html>
+            <blah>
+            </html>
+            """)
+        self.assert_(response.getHeader('content-type').startswith("text/html")
+                     )
+
+        response = BrowserResponse(StringIO())
+        response.setBody(
+            """<html foo="1"
+            bar="x">
+            <blah>
+            </html>
+            """)
+        self.assert_(response.getHeader('content-type').startswith("text/html")
+                     )
+
+        response = BrowserResponse(StringIO())
+        response.setBody(
+            """<html foo="1"
+            bar="x">
+            <blah>
+            </html>
+            """)
+        self.assert_(response.getHeader('content-type').startswith("text/html")
+                     )
+
+        response = BrowserResponse(StringIO())
+        response.setBody(
+            """<!doctype html>
+            <html foo="1"
+            bar="x">
+            <blah>
+            </html>
+            """)
+        self.assert_(response.getHeader('content-type').startswith("text/html")
+                     )
+
+        response = BrowserResponse(StringIO())
+        response.setBody(
+            """Hello world
+            """)
+        self.assert_(response.getHeader('content-type').startswith(
+            "text/plain")
+                     )
+
+        response = BrowserResponse(StringIO())
+        response.setBody(
+            """<p>Hello world
+            """)
+        self.assert_(response.getHeader('content-type').startswith(
+            "text/plain")
+                     )
+
+
+
+
+
+
+
+
+
+def test_suite():
+    return TestSuite((
+        makeSuite(Test),
+        ))
+
+if __name__=='__main__':
+    main(defaultTest='test_suite')


=== Zope3/src/zope/publisher/tests/test_http.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/test_http.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,160 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+import unittest
+
+from zope.publisher.http import HTTPRequest
+from zope.publisher.http import HTTPResponse
+
+from zope.publisher.publish import publish
+from zope.publisher.base import DefaultPublication
+
+from zope.interface.verify import verifyObject
+from zope.interface.implements import instancesOfObjectImplements
+
+from StringIO import StringIO
+
+
+class HTTPTests(unittest.TestCase):
+
+    _testEnv =  {
+        'PATH_INFO':          '/folder/item',
+        'a':                  '5',
+        'b':                  6,
+        'SERVER_URL':         'http://foobar.com',
+        'HTTP_HOST':          'foobar.com',
+        'CONTENT_LENGTH':     '0',
+        'HTTP_AUTHORIZATION': 'Should be in accessible',
+        'GATEWAY_INTERFACE':  'TestFooInterface/1.0',
+        'HTTP_OFF_THE_WALL':  "Spam 'n eggs",
+        'HTTP_ACCEPT_CHARSET': 'ISO-8859-1, UTF-8;q=0.66, UTF-16;q=0.33',
+    }
+
+    def setUp(self):
+        class AppRoot:
+            " "
+
+        class Folder:
+            " "
+
+        class Item:
+            " "
+            def __call__(self, a, b):
+                return "%s, %s" % (`a`, `b`)
+
+        self.app = AppRoot()
+        self.app.folder = Folder()
+        self.app.folder.item = Item()
+
+    def _createRequest(self, extra_env={}, body="", outstream=None):
+        env = self._testEnv.copy()
+        env.update(extra_env)
+        if len(body):
+            env['CONTENT_LENGTH'] = str(len(body))
+
+        publication = DefaultPublication(self.app)
+        if outstream is None:
+            outstream = StringIO()
+        instream = StringIO(body)
+        request = HTTPRequest(instream, outstream, env)
+        request.setPublication(publication)
+        return request
+
+    def _publisherResults(self, extra_env={}, body=""):
+        outstream = StringIO()
+        request = self._createRequest(extra_env, body, outstream=outstream)
+        publish(request, handle_errors=0)
+        return outstream.getvalue()
+
+    def testTraversalToItem(self):
+        res = self._publisherResults()
+        self.failUnlessEqual(
+            res,
+            "Status: 200 Ok\r\n"
+            "Content-Length: 6\r\n"
+            "X-Powered-By: Zope (www.zope.org), Python (www.python.org)\r\n"
+            "\r\n"
+            "'5', 6")
+
+    def testRequestEnvironment(self):
+        req = self._createRequest()
+        publish(req, handle_errors=0) # Force expansion of URL variables
+
+        self.assertEquals(str(req.URL), 'http://foobar.com/folder/item')
+        self.assertEquals(req.URL['-1'], 'http://foobar.com/folder')
+        self.assertEquals(req.URL['-2'], 'http://foobar.com')
+        self.assertRaises(KeyError, req.URL.__getitem__, '-3')
+
+        self.assertEquals(req.URL['0'], 'http://foobar.com')
+        self.assertEquals(req.URL['1'], 'http://foobar.com/folder')
+        self.assertEquals(req.URL['2'], 'http://foobar.com/folder/item')
+        self.assertRaises(KeyError, req.URL.__getitem__, '3')
+
+        self.assertEquals(req['SERVER_URL'], 'http://foobar.com')
+        self.assertEquals(req['HTTP_HOST'], 'foobar.com')
+        self.assertEquals(req['PATH_INFO'], '/folder/item')
+        self.assertEquals(req['CONTENT_LENGTH'], '0')
+        self.assertRaises(KeyError, req.__getitem__, 'HTTP_AUTHORIZATION')
+        self.assertEquals(req['GATEWAY_INTERFACE'], 'TestFooInterface/1.0')
+        self.assertEquals(req['HTTP_OFF_THE_WALL'], "Spam 'n eggs")
+
+        self.assertRaises(KeyError, req.__getitem__,
+                          'HTTP_WE_DID_NOT_PROVIDE_THIS')
+
+    def testCookies(self):
+        cookies = {
+            'HTTP_COOKIE': 'foo=bar; spam="eggs", this="Should be accepted"'
+        }
+        req = self._createRequest(extra_env=cookies)
+
+        self.assertEquals(req.cookies[u'foo'], u'bar')
+        self.assertEquals(req[u'foo'], u'bar')
+
+        self.assertEquals(req.cookies[u'spam'], u'eggs')
+        self.assertEquals(req[u'spam'], u'eggs')
+
+        self.assertEquals(req.cookies[u'this'], u'Should be accepted')
+        self.assertEquals(req[u'this'], u'Should be accepted')
+
+    def testBasicAuth(self):
+        from zope.publisher.interfaces.http import IHTTPCredentials
+        import base64
+        req = self._createRequest()
+        verifyObject(IHTTPCredentials, req)
+        lpq = req._authUserPW()
+        self.assertEquals(lpq, None)
+        env = {}
+        login, password = ("tim", "123")
+        s = base64.encodestring("%s:%s" % (login, password)).rstrip()
+        env['HTTP_AUTHORIZATION'] = "Basic %s" % s
+        req = self._createRequest(env)
+        lpw = req._authUserPW()
+        self.assertEquals(lpw, (login, password))
+
+    def testIPresentationRequest(self):
+        # test the IView request
+        r = self._createRequest()
+
+        self.failUnless( r.getPresentationType() is None)
+        self.assertEqual( r.getPresentationSkin(), '')
+        r.setViewSkin( 'morefoo' )
+        self.assertEqual( r.getPresentationSkin(), 'morefoo')
+
+
+def test_suite():
+    loader = unittest.TestLoader()
+    return loader.loadTestsFromTestCase(HTTPTests)
+
+
+if __name__ == '__main__':
+    unittest.TextTestRunner().run( test_suite() )


=== Zope3/src/zope/publisher/tests/test_httpcharsets.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/test_httpcharsets.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,62 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+"""Retrieval of HTTP character set information.
+
+$Id$
+"""
+import unittest, sys
+
+from zope.publisher.http import HTTPCharsets
+
+
+class HTTPCharsetTest(unittest.TestCase):
+
+    def testGetPreferredCharset(self):
+        request = {'HTTP_ACCEPT_CHARSET':
+                   'ISO-8859-1, UTF-8;q=0.66, UTF-16;q=0.33'}
+        browser_charsets = HTTPCharsets(request)
+        self.assertEqual(list(browser_charsets.getPreferredCharsets()),
+                         ['utf-8', 'iso-8859-1', 'utf-16'])
+
+    def testGetPreferredCharsetOrdering(self):
+        # test that the charsets are returned sorted according to
+        # their "quality value"
+        request = {'HTTP_ACCEPT_CHARSET':
+                   'ISO-8859-1, UTF-16;Q=0.33, UTF-8;q=0.66'}
+        browser_charsets = HTTPCharsets(request)
+        self.assertEqual(list(browser_charsets.getPreferredCharsets()),
+                         ['utf-8', 'iso-8859-1', 'utf-16'])
+
+    def testGetPreferredCharsetBogusQuality(self):
+        # test that handling of bogus "quality values" and non-quality
+        # parameters is reasonable
+        request = {'HTTP_ACCEPT_CHARSET':
+                   'ISO-8859-1;x, UTF-16;Q=0.33, UTF-8;q=foo'}
+        browser_charsets = HTTPCharsets(request)
+        self.assertEqual(list(browser_charsets.getPreferredCharsets()),
+                         ['iso-8859-1', 'utf-16'])
+
+    def testNoStar(self):
+        request = {'HTTP_ACCEPT_CHARSET': 'utf-16;q=0.66'}
+        browser_charsets = HTTPCharsets(request)
+        self.assertEqual(list(browser_charsets.getPreferredCharsets()),
+                         ['iso-8859-1', 'utf-16'])
+
+
+def test_suite():
+    loader=unittest.TestLoader()
+    return loader.loadTestsFromTestCase(HTTPCharsetTest)
+
+if __name__=='__main__':
+    unittest.TextTestRunner().run(test_suite())


=== Zope3/src/zope/publisher/tests/test_ipublication.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/test_ipublication.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,110 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+import sys
+from unittest import TestCase, TestSuite, main, makeSuite
+from StringIO import StringIO
+from zope.interface.verify import verifyObject
+
+from zope.publisher.interfaces import IPublication
+
+class BaseIPublicationTest:
+
+    # This test isn't as interesting as we'd like it to be because we
+    # know too little about the semantics if a particular publication
+    # object.
+
+    def testVerifyIPublication(self):
+        verifyObject(IPublication, self._Test__new())
+
+    def setUp(self):
+        self._request = request = self._Test__request()
+        self._publication = request.publication
+
+    def testgetApplication(self):
+        self._publication.getApplication(self._request)
+
+
+class Test(BaseIPublicationTest, TestCase):
+
+    def _Test__new(self):
+        from zope.publisher.tests.publication import TestPublication
+        return TestPublication()
+
+    def _Test__request(self):
+        from zope.publisher.base import BaseRequest
+        request = BaseRequest(StringIO(''), StringIO(), {})
+        request.setTraversalStack(['Engineering', 'ZopeCorp'])
+        publication = self._Test__new()
+        request.setPublication(publication)
+
+        return request
+
+    # The following are specific to our particular stub, but might be
+    # good examples of tests for other implementations.
+
+    def test_afterCall(self):
+        self._publication.afterCall(self._request)
+        self.assertEqual(self._publication._afterCall, 1)
+
+    def test_traverseName(self):
+        ob = self._publication.getApplication(self._request)
+        ob = self._publication.traverseName(self._request, ob, 'ZopeCorp')
+        self.assertEqual(ob.name, 'ZopeCorp')
+        ob = self._publication.traverseName(self._request, ob, 'Engineering')
+        self.assertEqual(ob.name, 'Engineering')
+
+    def test_afterTraversal(self):
+        self._publication.afterTraversal(self._request, None)
+        self.assertEqual(self._publication._afterTraversal, 1)
+
+    def test_beforeTraversal(self):
+        self._publication.beforeTraversal(self._request)
+        self.assertEqual(self._publication._beforeTraversal, 1)
+
+    def test_callObject(self):
+        result = self._publication.callObject(
+            self._request, lambda request: 42)
+        self.assertEqual(result, 42)
+
+    def test_getApplication(self):
+        from zope.publisher.tests.publication import app
+        result = self._publication.getApplication(self._request)
+        self.assertEqual(id(result), id(app))
+
+    def test_handleException(self):
+        try:
+            raise ValueError, 1
+        except:
+            exc_info = sys.exc_info()
+
+        try:
+            self._publication.handleException(object, self._request, exc_info)
+        finally:
+            exc_info = 0
+
+    def test_callTraversalHooks(self):
+        self._publication.callTraversalHooks(self._request, None)
+        self.assertEqual(self._publication._callTraversalHooks, 1)
+
+def test_suite():
+    return makeSuite(Test)
+
+if __name__=='__main__':
+    main(defaultTest='test_suite')


=== Zope3/src/zope/publisher/tests/test_mapply.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/test_mapply.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,56 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+import unittest
+
+from zope.publisher.publish import mapply
+
+
+class MapplyTests(unittest.TestCase):
+    def testMethod(self):
+        def compute(a,b,c=4):
+            return '%d%d%d' % (a, b, c)
+        values = {'a':2, 'b':3, 'c':5}
+        v = mapply(compute, (), values)
+        self.failUnlessEqual(v, '235')
+
+        v = mapply(compute, (7,), values)
+        self.failUnlessEqual(v, '735')
+
+    def testClass(self):
+        values = {'a':2, 'b':3, 'c':5}
+        class c:
+            a = 3
+            def __call__(self, b, c=4):
+                return '%d%d%d' % (self.a, b, c)
+            compute = __call__
+        cc = c()
+        v = mapply(cc, (), values)
+        self.failUnlessEqual(v, '335')
+
+        del values['c']
+        v = mapply(cc.compute, (), values)
+        self.failUnlessEqual(v, '334')
+
+        class c2: pass
+        c2inst = c2()
+        c2inst.__call__ = cc
+        v = mapply(c2inst, (), values)
+        self.failUnlessEqual(v, '334')
+
+def test_suite():
+    loader = unittest.TestLoader()
+    return loader.loadTestsFromTestCase(MapplyTests)
+
+if __name__=='__main__':
+    unittest.TextTestRunner().run(test_suite())


=== Zope3/src/zope/publisher/tests/test_publisher.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/test_publisher.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,108 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+
+import unittest
+
+from zope.publisher.publish import publish
+from zope.publisher.base import BaseRequest
+from zope.publisher.base import DefaultPublication
+from zope.publisher.interfaces import Retry, Unauthorized, NotFound, DebugError
+from zope.publisher.interfaces import IPublication
+
+from zope.interface.verify import verifyClass
+from zope.interface.implements import instancesOfObjectImplements
+
+from StringIO import StringIO
+
+class TestPublication(DefaultPublication):
+    # Override handleException to reraise for testing purposes
+    def handleException(self, object, request, exc_info, retry_allowed=1):
+        raise exc_info[0], exc_info[1], exc_info[2]
+
+class PublisherTests(unittest.TestCase):
+    def setUp(self):
+        class AppRoot:
+            " "
+
+        class Folder:
+            " "
+
+        class Item:
+            " "
+            def __call__(self):
+                return "item"
+
+        class NoDocstringItem:
+            def __call__(self):
+                return "Yo! No docstring!"
+
+        self.app = AppRoot()
+        self.app.folder = Folder()
+        self.app.folder.item = Item()
+
+        self.app._item = Item()
+        self.app.noDocString = NoDocstringItem()
+
+    def _createRequest(self, path, outstream=None, **kw):
+        if outstream is None:
+            outstream = StringIO()
+        publication = TestPublication(self.app)
+        path = path.split('/')
+        path.reverse()
+        request = BaseRequest(StringIO(''), outstream, kw)
+        request.setTraversalStack(path)
+        request.setPublication(publication)
+        return request
+
+    def _publisherResults(self, path, **kw):
+        outstream = StringIO()
+        request = self._createRequest(path, outstream=outstream, **kw)
+        publish(request, handle_errors=0)
+        return outstream.getvalue()
+
+    def testImplementsIPublication(self):
+        self.failUnless(IPublication.isImplementedBy(
+                            DefaultPublication(self.app)))
+
+    def testInterfacesVerify(self):
+        for interface in instancesOfObjectImplements(DefaultPublication):
+            verifyClass(interface, DefaultPublication)
+
+    def testTraversalToItem(self):
+        res = self._publisherResults('/folder/item')
+        self.failUnlessEqual(res, 'item')
+        res = self._publisherResults('/folder/item/')
+        self.failUnlessEqual(res, 'item')
+        res = self._publisherResults('folder/item')
+        self.failUnlessEqual(res, 'item')
+
+    def testUnderscoreUnauthorizedException(self):
+        self.assertRaises(Unauthorized, self._publisherResults, '/_item')
+
+    def testNotFoundException(self):
+        self.assertRaises(NotFound, self._publisherResults, '/foo')
+
+    def testDebugError(self):
+        self.assertRaises(DebugError, self._publisherResults, '/noDocString')
+
+def test_suite():
+    loader = unittest.TestLoader()
+    return loader.loadTestsFromTestCase(PublisherTests)
+
+if __name__=='__main__':
+    unittest.TextTestRunner().run( test_suite() )


=== Zope3/src/zope/publisher/tests/test_requestdataproperty.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/test_requestdataproperty.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,74 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from unittest import TestCase, TestSuite, main, makeSuite
+
+from zope.interface.common.tests.basemapping \
+     import testIEnumerableMapping, testIReadMapping
+
+from zope.publisher.base \
+     import RequestDataProperty, RequestDataGetter, RequestDataMapper
+
+class TestDataGettr(RequestDataGetter): _gettrname = 'getSomething'
+class TestDataMapper(RequestDataMapper): _mapname = '_data'
+
+_marker = object()
+class Data(object):
+
+    def getSomething(self, name, default=_marker):
+        if name.startswith('Z'):
+            return "something %s" % name
+
+        if default is not _marker:
+            return default
+
+        raise KeyError, name
+
+    something = RequestDataProperty(TestDataGettr)
+    somedata = RequestDataProperty(TestDataMapper)
+
+class Test(TestCase):
+
+    def testRequestDataGettr(self):
+        testIReadMapping(self, Data().something,
+                         {"Zope": "something Zope"}, ["spam"])
+
+    def testRequestDataMapper(self):
+        data = Data()
+        sample = {'foo': 'Foo', 'bar': 'Bar'}
+        data._data = sample
+        inst = data.somedata
+        testIReadMapping(self, inst, sample, ["spam"])
+        testIEnumerableMapping(self, inst, sample)
+
+    def testNoAssign(self):
+        data = Data()
+        try: data.something = {}
+        except AttributeError: pass
+        else: raise """Shouldn't be able to assign"""
+        try: data.somedata = {}
+        except AttributeError: pass
+        else: raise """Shouldn't be able to assign"""
+
+
+def test_suite():
+    return makeSuite(Test)
+
+if __name__=='__main__':
+    main(defaultTest='test_suite')


=== Zope3/src/zope/publisher/tests/test_xmlrpcmethodpublisher.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/test_xmlrpcmethodpublisher.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,57 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+import unittest, sys
+
+from zope.publisher.xmlrpc import MethodPublisher
+from zope.publisher.interfaces.xmlrpc import IXMLRPCPublisher
+
+from zope.interface.verify import verifyClass
+from zope.interface.implements import instancesOfObjectImplements
+
+class Presentation(MethodPublisher):
+    index = 'index'
+    action = 'action'
+    foo = 'foo'
+
+
+class TestMethodPublisher(unittest.TestCase):
+    def setUp(self):
+        self.pres = Presentation()
+
+    def testImplementsIXMLRPCPublisher(self):
+        self.failUnless(IXMLRPCPublisher.isImplementedBy(self.pres))
+
+    def testInterfacesVerify(self):
+        for interface in instancesOfObjectImplements(Presentation):
+            verifyClass(interface, Presentation)
+
+    def testXMLRPCTraverseIndex(self):
+        self.assertEquals(self.pres.publishTraverse(None, 'index'),
+            'index')
+
+    def testXMLRPCTraverseAction(self):
+        self.assertEquals(self.pres.publishTraverse(None, 'action'),
+            'action')
+
+    def testXMLRPCTraverseNotFound(self):
+        self.failUnlessRaises(AttributeError, self.pres.publishTraverse,
+            None, 'bar')
+
+
+def test_suite():
+    loader = unittest.TestLoader()
+    return loader.loadTestsFromTestCase(TestMethodPublisher)
+
+if __name__ == '__main__':
+    unittest.TextTestRunner().run(test_suite())


=== Zope3/src/zope/publisher/tests/test_xmlrpcrequest.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/test_xmlrpcrequest.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,146 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+import unittest
+
+from zope.component.tests.placelesssetup import PlacelessSetup
+from zope.component.adapter import provideAdapter
+
+from zope.interfaces.i18n import IUserPreferredCharsets
+
+from zope.publisher.http import IHTTPRequest
+from zope.publisher.http import HTTPCharsets
+
+from zope.publisher.xmlrpc import XMLRPCRequest
+from zope.publisher.xmlrpc import XMLRPCResponse
+
+from zope.publisher.publish import publish
+from zope.publisher.base import DefaultPublication
+from zope.publisher.interfaces.xmlrpc import IXMLRPCPresentation
+
+from cStringIO import StringIO
+
+class Publication(DefaultPublication):
+
+    require_docstrings = 0
+
+    def getDefaultTraversal(self, request, ob):
+        if hasattr(ob, 'browserDefault'):
+            return ob.browserDefault(request)
+        return ob, ()
+
+
+xmlrpc_call = '''<?xml version='1.0'?>
+<methodCall>
+  <methodName>action</methodName>
+  <params>
+    <param>
+      <value><int>1</int></value>
+    </param>
+  </params>
+</methodCall>
+'''
+
+
+class XMLRPCTests(unittest.TestCase, PlacelessSetup):
+    """The only thing different to HTTP is the input processing; so there
+       is no need to redo all the HTTP tests again.
+    """
+
+    _testEnv =  {
+        'PATH_INFO':          '/folder/item2/view/',
+        'QUERY_STRING':       '',
+        'SERVER_URL':         'http://foobar.com',
+        'HTTP_HOST':          'foobar.com',
+        'CONTENT_LENGTH':     '0',
+        'REQUEST_METHOD':     'POST',
+        'HTTP_AUTHORIZATION': 'Should be in accessible',
+        'GATEWAY_INTERFACE':  'TestFooInterface/1.0',
+        'HTTP_OFF_THE_WALL':  "Spam 'n eggs",
+        'HTTP_ACCEPT_CHARSET': 'ISO-8859-1, UTF-8;q=0.66, UTF-16;q=0.33',
+    }
+
+    def setUp(self):
+        PlacelessSetup.setUp(self)
+        provideAdapter(IHTTPRequest, IUserPreferredCharsets, HTTPCharsets)
+        class AppRoot:
+            " "
+
+        class Folder:
+            " "
+
+        class Item:
+
+            def __call__(self, a, b):
+                return "%s, %s" % (`a`, `b`)
+
+            def doit(self, a, b):
+                return 'do something %s %s' % (a, b)
+
+        class View:
+
+            def action(self, a):
+                return "Parameter[type: %s; value: %s" %(
+                    type(a).__name__, `a`)
+
+        class Item2:
+            view = View()
+
+
+        self.app = AppRoot()
+        self.app.folder = Folder()
+        self.app.folder.item = Item()
+        self.app.folder.item2 = Item2()
+
+
+    def _createRequest(self, extra_env={}, body="", outstream=None):
+        env = self._testEnv.copy()
+        env.update(extra_env)
+        if len(body):
+            env['CONTENT_LENGTH'] = str(len(body))
+
+        publication = Publication(self.app)
+        if outstream is None:
+            outstream = StringIO()
+        instream = StringIO(body)
+        request = XMLRPCRequest(instream, outstream, env)
+        request.setPublication(publication)
+        return request
+
+
+    def testIPresentationRequest(self):
+        r = self._createRequest()
+        self.failUnless( r.getPresentationType() is IXMLRPCPresentation)
+
+
+    def testProcessInput(self):
+        req = self._createRequest({}, xmlrpc_call)
+        req.processInputs()
+        self.failUnlessEqual(req._args, (1,))
+        self.failUnlessEqual(tuple(req._path_suffix), ('action',))
+
+
+    def testTraversal(self):
+        req = self._createRequest({}, xmlrpc_call)
+        req.processInputs()
+        action = req.traverse(self.app)
+        self.failUnlessEqual(action(*req._args),
+                             "Parameter[type: int; value: 1")
+
+
+def test_suite():
+    loader = unittest.TestLoader()
+    return loader.loadTestsFromTestCase(XMLRPCTests)
+
+if __name__=='__main__':
+    unittest.TextTestRunner().run( test_suite() )


=== Zope3/src/zope/publisher/tests/views.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/views.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,34 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+"""
+
+Revision information: $Id$
+"""
+
+from zope.interface import Interface
+from zope.publisher.browser import BrowserView
+from zope.publisher.interfaces.browser import IBrowserPresentation
+
+class IC(Interface): pass
+
+class V1(BrowserView): pass
+
+class VZMI(V1): pass
+
+class R1:
+    __implements__ = IBrowserPresentation
+    def __init__(self, request): self.request = request
+
+class RZMI(R1):
+    pass


=== Zope3/src/zope/publisher/tests/xmlrpcviews.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:15:50 2002
+++ Zope3/src/zope/publisher/tests/xmlrpcviews.py	Wed Dec 25 09:15:19 2002
@@ -0,0 +1,41 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+"""
+
+Revision information: $Id$
+"""
+
+from zope.interface import Interface
+from zope.publisher.interfaces.xmlrpc import IXMLRPCPublisher
+
+class IC(Interface): pass
+
+class V1:
+    __implements__ = IXMLRPCPublisher
+
+    def __init__(self, context, request):
+        self.context = context
+        self.request = request
+
+class VZMI(V1):
+    pass
+
+class R1:
+    def __init__(self, request):
+        self.request = request
+
+    __implements__ = IXMLRPCPublisher
+
+class RZMI(R1):
+    pass