Commits

Robert Brewer committed 96d7e48

Removed "filter" from lots of places, including renaming of tests.

Comments (0)

Files changed (28)

     environ['SCRIPT_NAME'] = cherrypy.request.script_name
     environ['PATH_INFO'] = cherrypy.request.path_info
     
-    # update the environ with the dict passed to the filter's
-    # constructor
     if env:
         environ.update(env)
     
     prefer_parent_path()
     
     testList = [
-        'test_baseurl_filter',
-        'test_cache_filter',
-        'test_combinedfilters',
+        'test_baseurl',
+        'test_caching',
         'test_config',
         'test_core',
-        'test_custom_filters',
-        'test_decodingencoding_filter',
-        'test_gzip_filter',
+        'test_tools',
+        'test_decodingencoding',
+        'test_gzip',
         'test_objectmapping',
-        'test_response_headers_filter',
-        'test_static_filter',
+        'test_response_headers',
+        'test_static',
         'test_tutorials',
-        'test_virtualhost_filter',
-        'test_session_filter',
-        'test_sessionauthenticate_filter',
+        'test_virtualhost',
+        'test_session',
+        'test_sessionauthenticate',
 ##        'test_states',
-        'test_xmlrpc_filter',
-        'test_wsgiapp_filter',
+        'test_xmlrpc',
+        'test_wsgiapp',
     ]
     CommandLineParser(testList).run()
     

test/test_baseurl.py

+import test
+test.prefer_parent_path()
+
+import cherrypy
+
+
+def setup_server():
+    class Root:
+        def index(self):
+            raise cherrypy.HTTPRedirect('dummy')
+        index.exposed = True
+    
+    cherrypy.tree.mount(Root())
+    cherrypy.config.update({
+            'environment': 'production',
+            'log_to_screen': False,
+            'tools.base_url.on': True,
+            'tools.base_url.base': 'http://www.mydomain.com',
+    })
+
+
+import helper
+
+class BaseUrlTest(helper.CPWebCase):
+    
+    def testBaseUrl(self):
+        self.getPage("/")
+        self.assertHeader('Location',
+                          "http://www.mydomain.com%s/dummy" % self.prefix())
+
+
+if __name__ == '__main__':
+    setup_server()
+    helper.testmain()

test/test_baseurl_filter.py

-import test
-test.prefer_parent_path()
-
-import cherrypy
-
-
-def setup_server():
-    class Root:
-        def index(self):
-            raise cherrypy.HTTPRedirect('dummy')
-        index.exposed = True
-    
-    cherrypy.tree.mount(Root())
-    cherrypy.config.update({
-            'environment': 'production',
-            'log_to_screen': False,
-            'tools.base_url.on': True,
-            'tools.base_url.base': 'http://www.mydomain.com',
-    })
-
-
-import helper
-
-class BaseUrlFilterTest(helper.CPWebCase):
-    
-    def testBaseUrlFilter(self):
-        self.getPage("/")
-        self.assertHeader('Location',
-                          "http://www.mydomain.com%s/dummy" % self.prefix())
-
-
-if __name__ == '__main__':
-    setup_server()
-    helper.testmain()

test/test_cache_filter.py

-import test
-test.prefer_parent_path()
-
-import cherrypy
-import time
-
-
-def setup_server():
-    class Root:
-        
-        _cp_config = {'tools.caching.on': True}
-        
-        def __init__(self):
-            cherrypy.counter = 0
-        
-        def index(self):
-            cherrypy.counter += 1
-            msg = "visit #%s" % cherrypy.counter
-            return msg
-        index.exposed = True
-    
-    cherrypy.tree.mount(Root())
-    cherrypy.config.update({
-        'log_to_screen': False,
-        'environment': 'production',
-    })
-
-
-import helper
-
-class CacheFilterTest(helper.CPWebCase):
-    
-    def testCaching(self):
-        for trial in xrange(10):
-            self.getPage("/")
-            # The response should be the same every time!
-            self.assertBody('visit #1')
-
-if __name__ == '__main__':
-    setup_server()
-    helper.testmain()
-

test/test_caching.py

+import test
+test.prefer_parent_path()
+
+import cherrypy
+import time
+
+
+def setup_server():
+    class Root:
+        
+        _cp_config = {'tools.caching.on': True}
+        
+        def __init__(self):
+            cherrypy.counter = 0
+        
+        def index(self):
+            cherrypy.counter += 1
+            msg = "visit #%s" % cherrypy.counter
+            return msg
+        index.exposed = True
+    
+    cherrypy.tree.mount(Root())
+    cherrypy.config.update({
+        'log_to_screen': False,
+        'environment': 'production',
+    })
+
+
+import helper
+
+class CacheTest(helper.CPWebCase):
+    
+    def testCaching(self):
+        for trial in xrange(10):
+            self.getPage("/")
+            # The response should be the same every time!
+            self.assertBody('visit #1')
+
+if __name__ == '__main__':
+    setup_server()
+    helper.testmain()
+

test/test_combinedfilters.py

-import test
-test.prefer_parent_path()
-
-import gzip, StringIO
-import cherrypy
-
-europoundUnicode = u'\x80\xa3'
-
-def setup_server():
-    class Root:
-        def index(self):
-            yield u"Hello,"
-            yield u"world"
-            yield europoundUnicode
-        index.exposed = True
-
-    cherrypy.tree.mount(Root())
-    cherrypy.config.update({
-            'log_to_screen': False,
-            'environment': 'production',
-            'tools.gzip.on': True,
-            'tools.encode.on': True,
-    })
-
-import helper
-
-class CombinedFiltersTest(helper.CPWebCase):
-    
-    def testCombinedFilters(self):
-        expectedResult = (u"Hello,world" + europoundUnicode).encode('utf-8')
-        zbuf = StringIO.StringIO()
-        zfile = gzip.GzipFile(mode='wb', fileobj=zbuf, compresslevel=9)
-        zfile.write(expectedResult)
-        zfile.close()
-        
-        self.getPage("/", headers=[("Accept-Encoding", "gzip")])
-        self.assertInBody(zbuf.getvalue()[:3])
-
-
-if __name__ == '__main__':
-    setup_server()
-    helper.testmain()

test/test_custom_filters.py

-"""Test the various means of instantiating and invoking filters."""
-
-import types
-import test
-test.prefer_parent_path()
-
-import cherrypy
-from cherrypy import tools
-
-
-def setup_server():
-    
-    def check_access():
-        if not getattr(cherrypy.request, "login", None):
-            raise cherrypy.HTTPError(401)
-    tools.check_access = tools.Tool('before_request_body', check_access)
-    
-    def numerify():
-        def number_it(body):
-            for chunk in body:
-                for k, v in cherrypy.request.numerify_map:
-                    chunk = chunk.replace(k, v)
-                yield chunk
-        cherrypy.response.body = number_it(cherrypy.response.body)
-    
-    class NumTool(tools.Tool):
-        def setup(self):
-            def makemap():
-                m = self.merged_args().get("map", {})
-                cherrypy.request.numerify_map = m.items()
-            cherrypy.request.hooks.attach('on_start_resource', makemap)
-            cherrypy.request.hooks.attach(self.point, self.callable)
-    tools.numerify = NumTool('before_finalize', numerify)
-    
-    # It's not mandatory to inherit from tools.Tool.
-    class NadsatTool:
-        
-        def __init__(self):
-            self.counter = 0
-            self.ended = {}
-            self.name = "nadsat"
-        
-        def nadsat(self):
-            def nadsat_it_up(body):
-                for chunk in body:
-                    chunk = chunk.replace("good", "horrorshow")
-                    chunk = chunk.replace("piece", "lomtick")
-                    yield chunk
-            cherrypy.response.body = nadsat_it_up(cherrypy.response.body)
-        
-        def cleanup(self):
-            # This runs after the request has been completely written out.
-            cherrypy.response.body = "razdrez"
-            self.ended[cherrypy.request.counter] = True
-        
-        def setup(self):
-            cherrypy.request.counter = self.counter = self.counter + 1
-            self.ended[cherrypy.request.counter] = False
-            cherrypy.request.hooks.callbacks['before_finalize'].insert(0, self.nadsat)
-            cherrypy.request.hooks.attach('on_end_request', self.cleanup)
-    tools.nadsat = NadsatTool()
-    
-    class Root:
-        def index(self):
-            return "Howdy earth!"
-        index.exposed = True
-    root = Root()
-    
-    
-    class TestType(type):
-        """Metaclass which automatically exposes all functions in each subclass,
-        and adds an instance of the subclass as an attribute of root.
-        """
-        def __init__(cls, name, bases, dct):
-            type.__init__(name, bases, dct)
-            for value in dct.itervalues():
-                if isinstance(value, types.FunctionType):
-                    value.exposed = True
-            setattr(root, name.lower(), cls())
-    class Test(object):
-        __metaclass__ = TestType
-    
-    
-    # METHOD ONE:
-    # Use _cp_config
-    class Demo(Test):
-        
-        _cp_config = {"tools.nadsat.on": True}
-        
-        def index(self):
-            return "A good piece of cherry pie"
-        
-        def ended(self, id):
-            return repr(tools.nadsat.ended[int(id)])
-        
-        def err(self):
-            raise ValueError()
-        
-        def errinstream(self):
-            raise ValueError()
-            yield "confidential"
-        
-        # METHOD TWO: decorator using tool.wrap
-        def restricted(self):
-            return "Welcome!"
-        restricted = tools.check_access.wrap()(restricted)
-        
-        def err_in_onstart(self):
-            return "success!"
-    
-    
-    cherrypy.config.update({'log_to_screen': False,
-                            'environment': 'production',
-                            'show_tracebacks': True,
-                            })
-    
-    conf = {
-        # METHOD THREE:
-        # Do it all in config
-        '/demo': {
-            'tools.numerify.on': True,
-            'tools.numerify.map': {"pie": "3.14159"},
-        },
-        '/demo/restricted': {
-            'show_tracebacks': False,
-        },
-        '/demo/errinstream': {
-            'stream_response': True,
-        },
-        '/demo/err_in_onstart': {
-            # Because this isn't a dict, on_start_resource will error.
-            'tools.numerify.map': "pie->3.14159"
-        },
-    }
-    cherrypy.tree.mount(root, conf=conf)
-
-
-#                             Client-side code                             #
-
-import helper
-
-
-class FilterTests(helper.CPWebCase):
-    
-    def testDemo(self):
-        self.getPage("/demo/")
-        # If body is "razdrez", then on_end_request is being called too early.
-        self.assertBody("A horrorshow lomtick of cherry 3.14159")
-        # If this fails, then on_end_request isn't being called at all.
-        self.getPage("/demo/ended/1")
-        self.assertBody("True")
-        
-        valerr = '\n    raise ValueError()\nValueError'
-        self.getPage("/demo/err")
-        # If body is "razdrez", then on_end_request is being called too early.
-        self.assertErrorPage(500, pattern=valerr)
-        # If this fails, then on_end_request isn't being called at all.
-        self.getPage("/demo/ended/3")
-        self.assertBody("True")
-        
-        # If body is "razdrez", then on_end_request is being called too early.
-        self.getPage("/demo/errinstream")
-        # Because this error is raised after the response body has
-        # started, the status should not change to an error status.
-        self.assertStatus("200 OK")
-        self.assertBody("Unrecoverable error in the server.")
-        # If this fails, then on_end_request isn't being called at all.
-        self.getPage("/demo/ended/5")
-        self.assertBody("True")
-        
-        # Test the decorator technique.
-        self.getPage("/demo/restricted")
-        self.assertErrorPage(401)
-    
-    def testGuaranteedFilters(self):
-        # The on_start_resource and on_end_request filter methods are all
-        # guaranteed to run, even if there are failures in other on_start
-        # or on_end methods. This is NOT true of the other filter methods.
-        # Here, we have set up a failure in NumerifyFilter.on_start_resource,
-        # but because that failure is logged and passed over, the error
-        # page we obtain in the user agent should be from before_finalize.
-        self.getPage("/demo/err_in_onstart")
-        self.assertErrorPage(500)
-        self.assertInBody("AttributeError: 'Request' object has no "
-                          "attribute 'numerify_map'")
-
-
-if __name__ == '__main__':
-    setup_server()
-    helper.testmain()
-

test/test_decodingencoding.py

+import test
+test.prefer_parent_path()
+
+import cherrypy
+europoundUnicode = u'\x80\xa3'
+sing = u"\u6bdb\u6cfd\u4e1c: Sing, Little Birdie?"
+sing8 = sing.encode('utf-8')
+sing16 = sing.encode('utf-16')
+
+
+def setup_server():
+    class Root:
+        def index(self, param):
+            assert param == europoundUnicode
+            yield europoundUnicode
+        index.exposed = True
+        
+        def mao_zedong(self):
+            return sing
+        mao_zedong.exposed = True
+
+    cherrypy.tree.mount(Root())
+    cherrypy.config.update({
+            'log_to_screen': False,
+            'environment': 'production',
+            'tools.encode.on': True,
+            'tools.decode.on': True,
+    })
+
+
+import helper
+
+
+class DecodingEncodingTest(helper.CPWebCase):
+    
+    def testDecodingEncoding(self):
+        europoundUtf8 = europoundUnicode.encode('utf-8')
+        self.getPage('/?param=%s' % europoundUtf8)
+        self.assertBody(europoundUtf8)
+        
+        # Default encoding should be utf-8
+        self.getPage('/mao_zedong')
+        self.assertBody(sing8)
+        
+        # Ask for utf-16.
+        self.getPage('/mao_zedong', [('Accept-Charset', 'utf-16')])
+        self.assertBody(sing16)
+        
+        # Ask for multiple encodings. ISO-8859-1 should fail, and utf-16
+        # should be produced.
+        self.getPage('/mao_zedong', [('Accept-Charset',
+                                      'iso-8859-1;q=1, utf-16;q=0.5')])
+        self.assertBody(sing16)
+        
+        # The "*" value should default to our default_encoding, utf-8
+        self.getPage('/mao_zedong', [('Accept-Charset', '*;q=1, utf-7;q=.2')])
+        self.assertBody(sing8)
+        
+        # Only allow iso-8859-1, which should fail and raise 406.
+        self.getPage('/mao_zedong', [('Accept-Charset', 'iso-8859-1, *;q=0')])
+        self.assertStatus("406 Not Acceptable")
+        self.assertInBody("Your client sent this Accept-Charset header: "
+                          "iso-8859-1, *;q=0. We tried these charsets: "
+                          "iso-8859-1.")
+
+
+if __name__ == "__main__":
+    setup_server()
+    helper.testmain()

test/test_decodingencoding_filter.py

-import test
-test.prefer_parent_path()
-
-import cherrypy
-europoundUnicode = u'\x80\xa3'
-sing = u"\u6bdb\u6cfd\u4e1c: Sing, Little Birdie?"
-sing8 = sing.encode('utf-8')
-sing16 = sing.encode('utf-16')
-
-
-def setup_server():
-    class Root:
-        def index(self, param):
-            assert param == europoundUnicode
-            yield europoundUnicode
-        index.exposed = True
-        
-        def mao_zedong(self):
-            return sing
-        mao_zedong.exposed = True
-
-    cherrypy.tree.mount(Root())
-    cherrypy.config.update({
-            'log_to_screen': False,
-            'environment': 'production',
-            'tools.encode.on': True,
-            'tools.decode.on': True,
-    })
-
-
-import helper
-
-
-class DecodingEncodingFilterTest(helper.CPWebCase):
-    
-    def testDecodingEncodingFilter(self):
-        europoundUtf8 = europoundUnicode.encode('utf-8')
-        self.getPage('/?param=%s' % europoundUtf8)
-        self.assertBody(europoundUtf8)
-        
-        # Default encoding should be utf-8
-        self.getPage('/mao_zedong')
-        self.assertBody(sing8)
-        
-        # Ask for utf-16.
-        self.getPage('/mao_zedong', [('Accept-Charset', 'utf-16')])
-        self.assertBody(sing16)
-        
-        # Ask for multiple encodings. ISO-8859-1 should fail, and utf-16
-        # should be produced.
-        self.getPage('/mao_zedong', [('Accept-Charset',
-                                      'iso-8859-1;q=1, utf-16;q=0.5')])
-        self.assertBody(sing16)
-        
-        # The "*" value should default to our default_encoding, utf-8
-        self.getPage('/mao_zedong', [('Accept-Charset', '*;q=1, utf-7;q=.2')])
-        self.assertBody(sing8)
-        
-        # Only allow iso-8859-1, which should fail and raise 406.
-        self.getPage('/mao_zedong', [('Accept-Charset', 'iso-8859-1, *;q=0')])
-        self.assertStatus("406 Not Acceptable")
-        self.assertInBody("Your client sent this Accept-Charset header: "
-                          "iso-8859-1, *;q=0. We tried these charsets: "
-                          "iso-8859-1.")
-
-
-if __name__ == "__main__":
-    setup_server()
-    helper.testmain()

test/test_gzip.py

+import test
+test.prefer_parent_path()
+
+import gzip, StringIO
+import cherrypy
+
+def setup_server():
+    class Root:
+        def index(self):
+            yield "Hello, world"
+        index.exposed = True
+        
+        def noshow(self):
+            # Test for ticket #147, where yield showed no exceptions (content-
+            # encoding was still gzip even though traceback wasn't zipped).
+            raise IndexError()
+            yield "Here be dragons"
+        noshow.exposed = True
+        
+        def noshow_stream(self):
+            # Test for ticket #147, where yield showed no exceptions (content-
+            # encoding was still gzip even though traceback wasn't zipped).
+            raise IndexError()
+            yield "Here be dragons"
+        noshow_stream.exposed = True
+        noshow_stream._cp_config = {'stream_response': True}
+    
+    cherrypy.tree.mount(Root())
+    cherrypy.config.update({
+        'global': {'log_to_screen': False,
+                   'environment': 'production',
+                   'show_tracebacks': True,
+                   'tools.gzip.on': True,
+                   },
+    })
+
+
+import helper
+
+europoundUtf8 = u'\x80\xa3'.encode('utf-8')
+
+class GzipTest(helper.CPWebCase):
+    
+    def testGzip(self):
+        zbuf = StringIO.StringIO()
+        zfile = gzip.GzipFile(mode='wb', fileobj=zbuf, compresslevel=9)
+        zfile.write("Hello, world")
+        zfile.close()
+        
+        self.getPage('/', headers=[("Accept-Encoding", "gzip")])
+        self.assertInBody(zbuf.getvalue()[:3])
+        self.assertHeader("Vary", "Accept-Encoding")
+        
+        # Test when gzip is denied.
+        self.getPage('/', headers=[("Accept-Encoding", "identity")])
+        self.assertNoHeader("Vary")
+        self.assertBody("Hello, world")
+        
+        self.getPage('/', headers=[("Accept-Encoding", "gzip;q=0")])
+        self.assertNoHeader("Vary")
+        self.assertBody("Hello, world")
+        
+        self.getPage('/', headers=[("Accept-Encoding", "*;q=0")])
+        self.assertStatus(406)
+        self.assertNoHeader("Vary")
+        self.assertErrorPage(406, "identity, gzip")
+        
+        # Test for ticket #147
+        self.getPage('/noshow', headers=[("Accept-Encoding", "gzip")])
+        self.assertNoHeader('Content-Encoding')
+        self.assertStatus(500)
+        self.assertErrorPage(500, pattern="IndexError\n")
+        
+        # In this case, there's nothing we can do to deliver a
+        # readable page, since 1) the gzip header is already set,
+        # and 2) we may have already written some of the body.
+        # The fix is to never stream yields when using gzip.
+        self.getPage('/noshow_stream',
+                     headers=[("Accept-Encoding", "gzip")])
+        self.assertHeader('Content-Encoding', 'gzip')
+        self.assertMatchesBody(r"Unrecoverable error in the server.$")
+
+
+if __name__ == "__main__":
+    setup_server()
+    helper.testmain()

test/test_gzip_filter.py

-import test
-test.prefer_parent_path()
-
-import gzip, StringIO
-import cherrypy
-
-def setup_server():
-    class Root:
-        def index(self):
-            yield "Hello, world"
-        index.exposed = True
-        
-        def noshow(self):
-            # Test for ticket #147, where yield showed no exceptions (content-
-            # encoding was still gzip even though traceback wasn't zipped).
-            raise IndexError()
-            yield "Here be dragons"
-        noshow.exposed = True
-        
-        def noshow_stream(self):
-            # Test for ticket #147, where yield showed no exceptions (content-
-            # encoding was still gzip even though traceback wasn't zipped).
-            raise IndexError()
-            yield "Here be dragons"
-        noshow_stream.exposed = True
-        noshow_stream._cp_config = {'stream_response': True}
-    
-    cherrypy.tree.mount(Root())
-    cherrypy.config.update({
-        'global': {'log_to_screen': False,
-                   'environment': 'production',
-                   'show_tracebacks': True,
-                   'tools.gzip.on': True,
-                   },
-    })
-
-
-import helper
-
-europoundUtf8 = u'\x80\xa3'.encode('utf-8')
-
-class GzipFilterTest(helper.CPWebCase):
-    
-    def testGzipFilter(self):
-        zbuf = StringIO.StringIO()
-        zfile = gzip.GzipFile(mode='wb', fileobj=zbuf, compresslevel=9)
-        zfile.write("Hello, world")
-        zfile.close()
-        
-        self.getPage('/', headers=[("Accept-Encoding", "gzip")])
-        self.assertInBody(zbuf.getvalue()[:3])
-        self.assertHeader("Vary", "Accept-Encoding")
-        
-        # Test when gzip is denied.
-        self.getPage('/', headers=[("Accept-Encoding", "identity")])
-        self.assertNoHeader("Vary")
-        self.assertBody("Hello, world")
-        
-        self.getPage('/', headers=[("Accept-Encoding", "gzip;q=0")])
-        self.assertNoHeader("Vary")
-        self.assertBody("Hello, world")
-        
-        self.getPage('/', headers=[("Accept-Encoding", "*;q=0")])
-        self.assertStatus(406)
-        self.assertNoHeader("Vary")
-        self.assertErrorPage(406, "identity, gzip")
-        
-        # Test for ticket #147
-        self.getPage('/noshow', headers=[("Accept-Encoding", "gzip")])
-        self.assertNoHeader('Content-Encoding')
-        self.assertStatus(500)
-        self.assertErrorPage(500, pattern="IndexError\n")
-        
-        # In this case, there's nothing we can do to deliver a
-        # readable page, since 1) the gzip header is already set,
-        # and 2) we may have already written some of the body.
-        # The fix is to never stream yields when using gzip.
-        self.getPage('/noshow_stream',
-                     headers=[("Accept-Encoding", "gzip")])
-        self.assertHeader('Content-Encoding', 'gzip')
-        self.assertMatchesBody(r"Unrecoverable error in the server.$")
-
-
-if __name__ == "__main__":
-    setup_server()
-    helper.testmain()

test/test_response_headers.py

+import test
+test.prefer_parent_path()
+
+import cherrypy
+from cherrypy.tools import response_headers
+headers = response_headers.wrap
+
+
+def setup_server():
+    class Root:
+        def index(self):
+            yield "Hello, world"
+        index = headers([("Content-Language", "en-GB"),
+                         ('Content-Type', 'text/plain')])(index)
+        index.exposed = True
+        
+        def other(self):
+            return "salut"
+        other.exposed = True
+        other._cp_config = {
+            'tools.response_headers.on': True,
+            'tools.response_headers.force': False,
+            'tools.response_headers.headers': [("Content-Language", "fr"),
+                                               ('Content-Type', 'text/plain')],
+            }
+    
+    cherrypy.tree.mount(Root())
+    cherrypy.config.update({
+            'log_to_screen': False,
+            'environment': 'production',
+    })
+
+
+import helper
+
+class ResponseHeadersTest(helper.CPWebCase):
+
+    def testResponseHeadersDecorator(self):
+        self.getPage('/')
+        self.assertHeader("Content-Language", "en-GB")
+        self.assertHeader('Content-Type', 'text/plain')
+
+    def testResponseHeaders(self):
+        self.getPage('/other')
+        self.assertHeader("Content-Language", "fr")
+        # Since 'force' is False, the tool should only change headers
+        # that have not been set yet.
+        # Content-Type should have been set when the response object
+        # was created (default to text/html)
+        self.assertHeader('Content-Type', 'text/html')
+
+if __name__ == "__main__":
+    setup_server()
+    helper.testmain()

test/test_response_headers_filter.py

-import test
-test.prefer_parent_path()
-
-import cherrypy
-from cherrypy.tools import response_headers
-headers = response_headers.wrap
-
-
-def setup_server():
-    class Root:
-        def index(self):
-            yield "Hello, world"
-        index = headers([("Content-Language", "en-GB"),
-                         ('Content-Type', 'text/plain')])(index)
-        index.exposed = True
-        
-        def other(self):
-            return "salut"
-        other.exposed = True
-        other._cp_config = {
-            'tools.response_headers.on': True,
-            'tools.response_headers.force': False,
-            'tools.response_headers.headers': [("Content-Language", "fr"),
-                                               ('Content-Type', 'text/plain')],
-            }
-    
-    cherrypy.tree.mount(Root())
-    cherrypy.config.update({
-            'log_to_screen': False,
-            'environment': 'production',
-    })
-
-
-import helper
-
-class ResponseHeadersFilterTest(helper.CPWebCase):
-
-    def testResponseHeadersDecorator(self):
-        self.getPage('/')
-        self.assertHeader("Content-Language", "en-GB")
-        self.assertHeader('Content-Type', 'text/plain')
-
-    def testResponseHeadersFilter(self):
-        self.getPage('/other')
-        self.assertHeader("Content-Language", "fr")
-        # Since 'force' is False, the filter should only change headers
-        # that have not been set yet.
-        # Content-Type should have been set when the response object
-        # was created (default to text/html)
-        self.assertHeader('Content-Type', 'text/html')
-
-if __name__ == "__main__":
-    setup_server()
-    helper.testmain()

test/test_session.py

+import test
+test.prefer_parent_path()
+
+import cherrypy, os
+
+
+def setup_server():
+    class Root:
+        
+        _cp_config = {'tools.sessions.on': True,
+                      'tools.sessions.storage_type' : 'file',
+                      'tools.sessions.storage_path' : '.',
+                      }
+        
+        def testGen(self):
+            counter = cherrypy.session.get('counter', 0) + 1
+            cherrypy.session['counter'] = counter
+            yield str(counter)
+        testGen.exposed = True
+        
+        def testStr(self):
+            counter = cherrypy.session.get('counter', 0) + 1
+            cherrypy.session['counter'] = counter
+            return str(counter)
+        testStr.exposed = True
+        
+        def setsessiontype(self, newtype):
+            cherrypy.config.update({'tools.sessions.storage_type': newtype})
+        setsessiontype.exposed = True
+        
+    cherrypy.tree.mount(Root())
+    cherrypy.config.update({
+            'log_to_screen': False,
+            'environment': 'production',
+    })
+
+import helper
+
+class SessionTest(helper.CPWebCase):
+    
+    def testSession(self):
+        self.getPage('/testStr')
+        self.assertBody('1')
+        self.getPage('/testGen', self.cookies)
+        self.assertBody('2')
+        self.getPage('/testStr', self.cookies)
+        self.assertBody('3')
+        self.getPage('/setsessiontype/file')
+        self.getPage('/testStr')
+        self.assertBody('1')
+        self.getPage('/testGen', self.cookies)
+        self.assertBody('2')
+        self.getPage('/testStr', self.cookies)
+        self.assertBody('3')
+
+        # Clean up session files
+        for fname in os.listdir('.'):
+            if fname.startswith('session-'):
+                os.unlink(fname)
+
+if __name__ == "__main__":
+    setup_server()
+    helper.testmain()
+

test/test_session_filter.py

-import test
-test.prefer_parent_path()
-
-import cherrypy, os
-
-
-def setup_server():
-    class Root:
-        
-        _cp_config = {'tools.sessions.on': True,
-                      'tools.sessions.storage_type' : 'file',
-                      'tools.sessions.storage_path' : '.',
-                      }
-        
-        def testGen(self):
-            counter = cherrypy.session.get('counter', 0) + 1
-            cherrypy.session['counter'] = counter
-            yield str(counter)
-        testGen.exposed = True
-        
-        def testStr(self):
-            counter = cherrypy.session.get('counter', 0) + 1
-            cherrypy.session['counter'] = counter
-            return str(counter)
-        testStr.exposed = True
-        
-        def setsessiontype(self, newtype):
-            cherrypy.config.update({'tools.sessions.storage_type': newtype})
-        setsessiontype.exposed = True
-        
-    cherrypy.tree.mount(Root())
-    cherrypy.config.update({
-            'log_to_screen': False,
-            'environment': 'production',
-    })
-
-import helper
-
-class SessionFilterTest(helper.CPWebCase):
-    
-    def testSessionFilter(self):
-        self.getPage('/testStr')
-        self.assertBody('1')
-        self.getPage('/testGen', self.cookies)
-        self.assertBody('2')
-        self.getPage('/testStr', self.cookies)
-        self.assertBody('3')
-        self.getPage('/setsessiontype/file')
-        self.getPage('/testStr')
-        self.assertBody('1')
-        self.getPage('/testGen', self.cookies)
-        self.assertBody('2')
-        self.getPage('/testStr', self.cookies)
-        self.assertBody('3')
-
-        # Clean up session files
-        for fname in os.listdir('.'):
-            if fname.startswith('session-'):
-                os.unlink(fname)
-
-if __name__ == "__main__":
-    setup_server()
-    helper.testmain()
-

test/test_sessionauthenticate.py

+import test
+test.prefer_parent_path()
+
+import cherrypy
+
+def setup_server():
+    
+    def check(login, password):
+        # Dummy check_login_and_password function
+        if login != 'login' or password != 'password':
+            return u'Wrong login/password'
+    
+    class Test:
+        
+        _cp_config = {'tools.sessions.on': True,
+                      'tools.session_auth.on': True,
+                      'tools.session_auth.check_login_and_password': check,
+                      }
+        
+        def index(self):
+            return "Hi, you are logged in"
+        index.exposed = True
+    
+    cherrypy.tree.mount(Test())
+    cherrypy.config.update({
+            'log_to_screen': False,
+            'environment': 'production',
+            })
+
+
+import helper
+
+class SessionAuthenticateTest(helper.CPWebCase):
+    
+    def testSessionAuthenticate(self):
+        # request a page and check for login form
+        self.getPage('/')
+        self.assertInBody('<form method="post" action="do_login">')
+
+        # setup credentials
+        login_body = 'login=login&password=password&from_page=/'
+
+        # attempt a login
+        self.getPage('/do_login', method='POST', body=login_body)
+        self.assert_(self.status in ('302 Found', '303 See Other'))
+
+        # get the page now that we are logged in
+        self.getPage('/', self.cookies)
+        self.assertBody('Hi, you are logged in')
+
+        # do a logout
+        self.getPage('/do_logout', self.cookies)
+        self.assert_(self.status in ('302 Found', '303 See Other'))
+
+        # verify we are logged out
+        self.getPage('/', self.cookies)
+        self.assertInBody('<form method="post" action="do_login">')
+
+
+if __name__ == "__main__":
+    setup_server()
+    helper.testmain()
+

test/test_sessionauthenticate_filter.py

-import test
-test.prefer_parent_path()
-
-import cherrypy
-
-def setup_server():
-    
-    def check(login, password):
-        # Dummy check_login_and_password function
-        if login != 'login' or password != 'password':
-            return u'Wrong login/password'
-    
-    class Test:
-        
-        _cp_config = {'tools.sessions.on': True,
-                      'tools.session_auth.on': True,
-                      'tools.session_auth.check_login_and_password': check,
-                      }
-        
-        def index(self):
-            return "Hi, you are logged in"
-        index.exposed = True
-    
-    cherrypy.tree.mount(Test())
-    cherrypy.config.update({
-            'log_to_screen': False,
-            'environment': 'production',
-            })
-
-
-import helper
-
-class SessionAuthenticateFilterTest(helper.CPWebCase):
-    
-    def testSessionAuthenticateFilter(self):
-        # request a page and check for login form
-        self.getPage('/')
-        self.assertInBody('<form method="post" action="do_login">')
-
-        # setup credentials
-        login_body = 'login=login&password=password&from_page=/'
-
-        # attempt a login
-        self.getPage('/do_login', method='POST', body=login_body)
-        self.assert_(self.status in ('302 Found', '303 See Other'))
-
-        # get the page now that we are logged in
-        self.getPage('/', self.cookies)
-        self.assertBody('Hi, you are logged in')
-
-        # do a logout
-        self.getPage('/do_logout', self.cookies)
-        self.assert_(self.status in ('302 Found', '303 See Other'))
-
-        # verify we are logged out
-        self.getPage('/', self.cookies)
-        self.assertInBody('<form method="post" action="do_login">')
-
-
-if __name__ == "__main__":
-    setup_server()
-    helper.testmain()
-

test/test_static.py

+import test
+test.prefer_parent_path()
+
+import os
+curdir = os.path.join(os.getcwd(), os.path.dirname(__file__))
+import threading
+
+import cherrypy
+from cherrypy.lib import cptools
+
+
+def setup_server():
+    class Root:
+        pass
+
+    class Static:
+        
+        def index(self):
+            return 'You want the Baron? You can have the Baron!'
+        index.exposed = True
+        
+        def dynamic(self):
+            return "This is a DYNAMIC page"
+        dynamic.exposed = True
+
+
+    root = Root()
+    root.static = Static()
+    
+    conf = {
+        '/static': {
+            'tools.staticdir.on': True,
+            'tools.staticdir.dir': 'static',
+            'tools.staticdir.root': curdir,
+        },
+        '/style.css': {
+            'tools.staticfile.on': True,
+            'tools.staticfile.filename': os.path.join(curdir, 'style.css'),
+        },
+        '/docroot': {
+            'tools.staticdir.on': True,
+            'tools.staticdir.root': curdir,
+            'tools.staticdir.dir': 'static',
+            'tools.staticdir.index': 'index.html',
+        },
+        '/error': {
+            'tools.staticdir.on': True,
+            'show_tracebacks': True,
+        },
+        }
+    
+    cherrypy.tree.mount(root, conf=conf)
+    
+    cherrypy.config.update({
+        'log_to_screen': False,
+        'environment': 'production',
+        })
+
+import helper
+
+class StaticTest(helper.CPWebCase):
+    
+    def testStatic(self):
+        self.getPage("/static/index.html")
+        self.assertStatus('200 OK')
+        self.assertHeader('Content-Type', 'text/html')
+        self.assertBody('Hello, world\r\n')
+        
+        # Using a staticdir.root value in a subdir...
+        self.getPage("/docroot/index.html")
+        self.assertStatus('200 OK')
+        self.assertHeader('Content-Type', 'text/html')
+        self.assertBody('Hello, world\r\n')
+        
+        # Check a filename with spaces in it
+        self.getPage("/static/has%20space.html")
+        self.assertStatus('200 OK')
+        self.assertHeader('Content-Type', 'text/html')
+        self.assertBody('Hello, world\r\n')
+        
+        self.getPage("/style.css")
+        self.assertStatus('200 OK')
+        self.assertHeader('Content-Type', 'text/css')
+        # Note: The body should be exactly 'Dummy stylesheet\n', but
+        #   unfortunately some tools such as WinZip sometimes turn \n
+        #   into \r\n on Windows when extracting the CherryPy tarball so
+        #   we just check the content
+        self.assertMatchesBody('^Dummy stylesheet')
+        
+        # Test that NotFound will then try dynamic handlers (see [878]).
+        self.getPage("/static/dynamic")
+        self.assertBody("This is a DYNAMIC page")
+        
+        # Check a directory via fall-through to dynamic handler.
+        self.getPage("/static/")
+        self.assertStatus('200 OK')
+        self.assertHeader('Content-Type', 'text/html')
+        self.assertBody('You want the Baron? You can have the Baron!')
+        
+        # Check a directory via "staticdir.index".
+        self.getPage("/docroot/")
+        self.assertStatus('200 OK')
+        self.assertHeader('Content-Type', 'text/html')
+        self.assertBody('Hello, world\r\n')
+        # The same page should be returned even if redirected.
+        self.getPage("/docroot")
+        self.assertStatus('200 OK')
+        self.assertHeader('Content-Type', 'text/html')
+        self.assertBody('Hello, world\r\n')
+        
+        # Check that we get an error if no .file or .dir
+        self.getPage("/error/thing.html")
+        self.assertErrorPage(500)
+        self.assertInBody("TypeError: staticdir() takes at least 2 "
+                          "arguments (0 given)")
+        
+        # Test up-level security
+        self.getPage("/static/../../test/style.css")
+        self.assertStatus((400, 403))
+        
+        # Test modified-since on a reasonably-large file
+        self.getPage("/static/dirback.jpg")
+        self.assertStatus("200 OK")
+        lastmod = ""
+        for k, v in self.headers:
+            if k == 'Last-Modified':
+                lastmod = v
+        ims = ("If-Modified-Since", lastmod)
+        self.getPage("/static/dirback.jpg", headers=[ims])
+        self.assertStatus("304 Not Modified")
+##        
+##        # Test lots of requests for the same file (no If-Mod).
+##        ts = []
+##        for x in xrange(500):
+##            t = threading.Thread(target=self.getPage,
+##                                 args=("/static/dirback.jpg",))
+##            ts.append(t)
+##            t.start()
+##        for t in ts:
+##            t.join()
+##
+
+if __name__ == "__main__":
+    setup_server()
+    helper.testmain()

test/test_static_filter.py

-import test
-test.prefer_parent_path()
-
-import os
-curdir = os.path.join(os.getcwd(), os.path.dirname(__file__))
-import threading
-
-import cherrypy
-from cherrypy.lib import cptools
-
-
-def setup_server():
-    class Root:
-        pass
-
-    class Static:
-        
-        def index(self):
-            return 'You want the Baron? You can have the Baron!'
-        index.exposed = True
-        
-        def dynamic(self):
-            return "This is a DYNAMIC page"
-        dynamic.exposed = True
-
-
-    root = Root()
-    root.static = Static()
-    
-    conf = {
-        '/static': {
-            'tools.staticdir.on': True,
-            'tools.staticdir.dir': 'static',
-            'tools.staticdir.root': curdir,
-        },
-        '/style.css': {
-            'tools.staticfile.on': True,
-            'tools.staticfile.filename': os.path.join(curdir, 'style.css'),
-        },
-        '/docroot': {
-            'tools.staticdir.on': True,
-            'tools.staticdir.root': curdir,
-            'tools.staticdir.dir': 'static',
-            'tools.staticdir.index': 'index.html',
-        },
-        '/error': {
-            'tools.staticdir.on': True,
-            'show_tracebacks': True,
-        },
-        }
-    
-    cherrypy.tree.mount(root, conf=conf)
-    
-    cherrypy.config.update({
-        'log_to_screen': False,
-        'environment': 'production',
-        })
-
-import helper
-
-class StaticFilterTest(helper.CPWebCase):
-    
-    def testStaticFilter(self):
-        self.getPage("/static/index.html")
-        self.assertStatus('200 OK')
-        self.assertHeader('Content-Type', 'text/html')
-        self.assertBody('Hello, world\r\n')
-        
-        # Using a static_filter.root value in a subdir...
-        self.getPage("/docroot/index.html")
-        self.assertStatus('200 OK')
-        self.assertHeader('Content-Type', 'text/html')
-        self.assertBody('Hello, world\r\n')
-        
-        # Check a filename with spaces in it
-        self.getPage("/static/has%20space.html")
-        self.assertStatus('200 OK')
-        self.assertHeader('Content-Type', 'text/html')
-        self.assertBody('Hello, world\r\n')
-        
-        self.getPage("/style.css")
-        self.assertStatus('200 OK')
-        self.assertHeader('Content-Type', 'text/css')
-        # Note: The body should be exactly 'Dummy stylesheet\n', but
-        #   unfortunately some tools such as WinZip sometimes turn \n
-        #   into \r\n on Windows when extracting the CherryPy tarball so
-        #   we just check the content
-        self.assertMatchesBody('^Dummy stylesheet')
-        
-        # Test that NotFound will then try dynamic handlers (see [878]).
-        self.getPage("/static/dynamic")
-        self.assertBody("This is a DYNAMIC page")
-        
-        # Check a directory via fall-through to dynamic handler.
-        self.getPage("/static/")
-        self.assertStatus('200 OK')
-        self.assertHeader('Content-Type', 'text/html')
-        self.assertBody('You want the Baron? You can have the Baron!')
-        
-        # Check a directory via "static_filter.index".
-        self.getPage("/docroot/")
-        self.assertStatus('200 OK')
-        self.assertHeader('Content-Type', 'text/html')
-        self.assertBody('Hello, world\r\n')
-        # The same page should be returned even if redirected.
-        self.getPage("/docroot")
-        self.assertStatus('200 OK')
-        self.assertHeader('Content-Type', 'text/html')
-        self.assertBody('Hello, world\r\n')
-        
-        # Check that we get an error if no .file or .dir
-        self.getPage("/error/thing.html")
-        self.assertErrorPage(500)
-        self.assertInBody("TypeError: staticdir() takes at least 2 "
-                          "arguments (0 given)")
-        
-        # Test up-level security
-        self.getPage("/static/../../test/style.css")
-        self.assertStatus((400, 403))
-        
-        # Test modified-since on a reasonably-large file
-        self.getPage("/static/dirback.jpg")
-        self.assertStatus("200 OK")
-        lastmod = ""
-        for k, v in self.headers:
-            if k == 'Last-Modified':
-                lastmod = v
-        ims = ("If-Modified-Since", lastmod)
-        self.getPage("/static/dirback.jpg", headers=[ims])
-        self.assertStatus("304 Not Modified")
-##        
-##        # Test lots of requests for the same file (no If-Mod).
-##        ts = []
-##        for x in xrange(500):
-##            t = threading.Thread(target=self.getPage,
-##                                 args=("/static/dirback.jpg",))
-##            ts.append(t)
-##            t.start()
-##        for t in ts:
-##            t.join()
-##
-
-if __name__ == "__main__":
-    setup_server()
-    helper.testmain()

test/test_tools.py

+"""Test the various means of instantiating and invoking tools."""
+
+import gzip, StringIO
+import types
+import test
+test.prefer_parent_path()
+
+import cherrypy
+from cherrypy import tools
+
+
+europoundUnicode = u'\x80\xa3'
+
+def setup_server():
+    
+    def check_access():
+        if not getattr(cherrypy.request, "login", None):
+            raise cherrypy.HTTPError(401)
+    tools.check_access = tools.Tool('before_request_body', check_access)
+    
+    def numerify():
+        def number_it(body):
+            for chunk in body:
+                for k, v in cherrypy.request.numerify_map:
+                    chunk = chunk.replace(k, v)
+                yield chunk
+        cherrypy.response.body = number_it(cherrypy.response.body)
+    
+    class NumTool(tools.Tool):
+        def setup(self):
+            def makemap():
+                m = self.merged_args().get("map", {})
+                cherrypy.request.numerify_map = m.items()
+            cherrypy.request.hooks.attach('on_start_resource', makemap)
+            cherrypy.request.hooks.attach(self.point, self.callable)
+    tools.numerify = NumTool('before_finalize', numerify)
+    
+    # It's not mandatory to inherit from tools.Tool.
+    class NadsatTool:
+        
+        def __init__(self):
+            self.counter = 0
+            self.ended = {}
+            self.name = "nadsat"
+        
+        def nadsat(self):
+            def nadsat_it_up(body):
+                for chunk in body:
+                    chunk = chunk.replace("good", "horrorshow")
+                    chunk = chunk.replace("piece", "lomtick")
+                    yield chunk
+            cherrypy.response.body = nadsat_it_up(cherrypy.response.body)
+        
+        def cleanup(self):
+            # This runs after the request has been completely written out.
+            cherrypy.response.body = "razdrez"
+            self.ended[cherrypy.request.counter] = True
+        
+        def setup(self):
+            cherrypy.request.counter = self.counter = self.counter + 1
+            self.ended[cherrypy.request.counter] = False
+            cherrypy.request.hooks.callbacks['before_finalize'].insert(0, self.nadsat)
+            cherrypy.request.hooks.attach('on_end_request', self.cleanup)
+    tools.nadsat = NadsatTool()
+    
+    class Root:
+        def index(self):
+            return "Howdy earth!"
+        index.exposed = True
+        
+        def euro(self):
+            yield u"Hello,"
+            yield u"world"
+            yield europoundUnicode
+        euro.exposed = True
+    
+    root = Root()
+    
+    
+    class TestType(type):
+        """Metaclass which automatically exposes all functions in each subclass,
+        and adds an instance of the subclass as an attribute of root.
+        """
+        def __init__(cls, name, bases, dct):
+            type.__init__(name, bases, dct)
+            for value in dct.itervalues():
+                if isinstance(value, types.FunctionType):
+                    value.exposed = True
+            setattr(root, name.lower(), cls())
+    class Test(object):
+        __metaclass__ = TestType
+    
+    
+    # METHOD ONE:
+    # Use _cp_config
+    class Demo(Test):
+        
+        _cp_config = {"tools.nadsat.on": True}
+        
+        def index(self):
+            return "A good piece of cherry pie"
+        
+        def ended(self, id):
+            return repr(tools.nadsat.ended[int(id)])
+        
+        def err(self):
+            raise ValueError()
+        
+        def errinstream(self):
+            raise ValueError()
+            yield "confidential"
+        
+        # METHOD TWO: decorator using tool.wrap
+        def restricted(self):
+            return "Welcome!"
+        restricted = tools.check_access.wrap()(restricted)
+        
+        def err_in_onstart(self):
+            return "success!"
+    
+    
+    cherrypy.config.update({'log_to_screen': False,
+                            'environment': 'production',
+                            'show_tracebacks': True,
+                            })
+    
+    conf = {
+        # METHOD THREE:
+        # Do it all in config
+        '/demo': {
+            'tools.numerify.on': True,
+            'tools.numerify.map': {"pie": "3.14159"},
+        },
+        '/demo/restricted': {
+            'show_tracebacks': False,
+        },
+        '/demo/errinstream': {
+            'stream_response': True,
+        },
+        '/demo/err_in_onstart': {
+            # Because this isn't a dict, on_start_resource will error.
+            'tools.numerify.map': "pie->3.14159"
+        },
+        # Combined tools
+        '/euro': {
+            'tools.gzip.on': True,
+            'tools.encode.on': True,
+        },
+    }
+    cherrypy.tree.mount(root, conf=conf)
+
+
+#                             Client-side code                             #
+
+import helper
+
+
+class ToolTests(helper.CPWebCase):
+    
+    def testDemo(self):
+        self.getPage("/demo/")
+        # If body is "razdrez", then on_end_request is being called too early.
+        self.assertBody("A horrorshow lomtick of cherry 3.14159")
+        # If this fails, then on_end_request isn't being called at all.
+        self.getPage("/demo/ended/1")
+        self.assertBody("True")
+        
+        valerr = '\n    raise ValueError()\nValueError'
+        self.getPage("/demo/err")
+        # If body is "razdrez", then on_end_request is being called too early.
+        self.assertErrorPage(500, pattern=valerr)
+        # If this fails, then on_end_request isn't being called at all.
+        self.getPage("/demo/ended/3")
+        self.assertBody("True")
+        
+        # If body is "razdrez", then on_end_request is being called too early.
+        self.getPage("/demo/errinstream")
+        # Because this error is raised after the response body has
+        # started, the status should not change to an error status.
+        self.assertStatus("200 OK")
+        self.assertBody("Unrecoverable error in the server.")
+        # If this fails, then on_end_request isn't being called at all.
+        self.getPage("/demo/ended/5")
+        self.assertBody("True")
+        
+        # Test the decorator technique.
+        self.getPage("/demo/restricted")
+        self.assertErrorPage(401)
+    
+    def testGuaranteedHooks(self):
+        # The on_start_resource and on_end_request hooks are all
+        # guaranteed to run, even if there are failures in other on_start
+        # or on_end methods. This is NOT true of the other hooks.
+        # Here, we have set up a failure in NumerifyTool.on_start_resource,
+        # but because that failure is logged and passed over, the error
+        # page we obtain in the user agent should be from before_finalize.
+        self.getPage("/demo/err_in_onstart")
+        self.assertErrorPage(500)
+        self.assertInBody("AttributeError: 'Request' object has no "
+                          "attribute 'numerify_map'")
+    
+    def testCombinedTools(self):
+        expectedResult = (u"Hello,world" + europoundUnicode).encode('utf-8')
+        zbuf = StringIO.StringIO()
+        zfile = gzip.GzipFile(mode='wb', fileobj=zbuf, compresslevel=9)
+        zfile.write(expectedResult)
+        zfile.close()
+        
+        self.getPage("/euro", headers=[("Accept-Encoding", "gzip")])
+        self.assertInBody(zbuf.getvalue()[:3])
+
+
+if __name__ == '__main__':
+    setup_server()
+    helper.testmain()
+

test/test_tutorials.py

         app = cherrypy.tree.apps[""]
         
         app.root.load_tut_module = load_tut_module
-        app.root.sessfilteron = sessfilteron
+        app.root.sessions = sessions
         app.root.traceback_setting = traceback_setting
     load_tut_module.exposed = True
     
-    def sessfilteron():
-        cherrypy.config.update({"session_filter.on": True})
-    sessfilteron.exposed = True
+    def sessions():
+        cherrypy.config.update({"tools.sessions.on": True})
+    sessions.exposed = True
     
     def traceback_setting():
         return repr(cherrypy.config.get('show_tracebacks'))
                         '(<a href="./">back</a>)')
     def test07Sessions(self):
         self.getPage("/load_tut_module/tut07_sessions")
-        self.getPage("/sessfilteron")
+        self.getPage("/sessions")
         
         self.getPage('/')
         self.assertBody("\n            During your current session, you've viewed this"

test/test_virtualhost.py

+
+import test
+test.prefer_parent_path()
+
+import cherrypy
+
+def setup_server():
+    class Root:
+        def index(self):
+            return "Hello, world"
+        index.exposed = True
+        
+        def dom4(self):
+            return "Under construction"
+        dom4.exposed = True
+        
+        def method(self, value):
+            return "You sent %s" % repr(value)
+        method.exposed = True
+    
+    class VHost:
+        def __init__(self, sitename):
+            self.sitename = sitename
+        
+        def index(self):
+            return "Welcome to %s" % self.sitename
+        index.exposed = True
+        
+        def vmethod(self, value):
+            return "You sent %s" % repr(value)
+        vmethod.exposed = True
+    
+    
+    root = Root()
+    root.mydom2 = VHost("Domain 2")
+    root.mydom3 = VHost("Domain 3")
+    cherrypy.tree.mount(root)
+    
+    cherrypy.config.update({
+            'log_to_screen': False,
+            'environment': 'production',
+            'tools.virtual_host.on': True,
+            'tools.virtual_host.www.mydom2.com': '/mydom2',
+            'tools.virtual_host.www.mydom3.com': '/mydom3',
+            'tools.virtual_host.www.mydom4.com': '/dom4',
+    })
+
+import helper
+
+class VirtualHostTest(helper.CPWebCase):
+    
+    def testVirtualHost(self):
+        self.getPage("/", [('Host', 'www.mydom1.com')])
+        self.assertBody('Hello, world')
+        self.getPage("/mydom2/", [('Host', 'www.mydom1.com')])
+        self.assertBody('Welcome to Domain 2')
+        
+        self.getPage("/", [('Host', 'www.mydom2.com')])
+        self.assertBody('Welcome to Domain 2')
+        self.getPage("/", [('Host', 'www.mydom3.com')])
+        self.assertBody('Welcome to Domain 3')
+        self.getPage("/", [('Host', 'www.mydom4.com')])
+        self.assertBody('Under construction')
+        
+        # Test GET, POST, and positional params
+        self.getPage("/method?value=root")
+        self.assertBody("You sent 'root'")
+        self.getPage("/vmethod?value=dom2+GET", [('Host', 'www.mydom2.com')])
+        self.assertBody("You sent 'dom2 GET'")
+        self.getPage("/vmethod", [('Host', 'www.mydom3.com')], method="POST",
+                     body="value=dom3+POST")
+        self.assertBody("You sent 'dom3 POST'")
+        self.getPage("/vmethod/pos", [('Host', 'www.mydom3.com')])
+        self.assertBody("You sent 'pos'")
+
+
+if __name__ == "__main__":
+    setup_server()
+    helper.testmain()

test/test_virtualhost_filter.py

-
-import test
-test.prefer_parent_path()
-
-import cherrypy
-
-def setup_server():
-    class Root:
-        def index(self):
-            return "Hello, world"
-        index.exposed = True
-        
-        def dom4(self):
-            return "Under construction"
-        dom4.exposed = True
-        
-        def method(self, value):
-            return "You sent %s" % repr(value)
-        method.exposed = True
-    
-    class VHost:
-        def __init__(self, sitename):
-            self.sitename = sitename
-        
-        def index(self):
-            return "Welcome to %s" % self.sitename
-        index.exposed = True
-        
-        def vmethod(self, value):
-            return "You sent %s" % repr(value)
-        vmethod.exposed = True
-    
-    
-    root = Root()
-    root.mydom2 = VHost("Domain 2")
-    root.mydom3 = VHost("Domain 3")
-    cherrypy.tree.mount(root)
-    
-    cherrypy.config.update({
-            'log_to_screen': False,
-            'environment': 'production',
-            'tools.virtual_host.on': True,
-            'tools.virtual_host.www.mydom2.com': '/mydom2',
-            'tools.virtual_host.www.mydom3.com': '/mydom3',
-            'tools.virtual_host.www.mydom4.com': '/dom4',
-    })
-
-import helper
-
-class VirtualHostFilterTest(helper.CPWebCase):
-    
-    def testVirtualHostFilter(self):
-        self.getPage("/", [('Host', 'www.mydom1.com')])
-        self.assertBody('Hello, world')
-        self.getPage("/mydom2/", [('Host', 'www.mydom1.com')])
-        self.assertBody('Welcome to Domain 2')
-        
-        self.getPage("/", [('Host', 'www.mydom2.com')])
-        self.assertBody('Welcome to Domain 2')
-        self.getPage("/", [('Host', 'www.mydom3.com')])
-        self.assertBody('Welcome to Domain 3')
-        self.getPage("/", [('Host', 'www.mydom4.com')])
-        self.assertBody('Under construction')
-        
-        # Test GET, POST, and positional params
-        self.getPage("/method?value=root")
-        self.assertBody("You sent 'root'")
-        self.getPage("/vmethod?value=dom2+GET", [('Host', 'www.mydom2.com')])
-        self.assertBody("You sent 'dom2 GET'")
-        self.getPage("/vmethod", [('Host', 'www.mydom3.com')], method="POST",
-                     body="value=dom3+POST")
-        self.assertBody("You sent 'dom3 POST'")
-        self.getPage("/vmethod/pos", [('Host', 'www.mydom3.com')])
-        self.assertBody("You sent 'pos'")
-
-
-if __name__ == "__main__":
-    setup_server()
-    helper.testmain()

test/test_wsgiapp.py

+import test
+test.prefer_parent_path()
+
+
+def setup_server():
+    import os
+    curdir = os.path.join(os.getcwd(), os.path.dirname(__file__))
+    
+    import cherrypy
+    
+    def test_app(environ, start_response):
+        status = '200 OK'
+        response_headers = [('Content-type', 'text/plain')]
+        start_response(status, response_headers)
+        yield 'Hello, world!\n'
+        yield 'This is a wsgi app running within CherryPy!\n\n'
+        keys = environ.keys()
+        keys.sort()
+        for k in keys:
+            yield '%s: %s\n' % (k,environ[k])
+    
+    class Root:
+        def index(self):
+            return "I'm a regular CherryPy page handler!"
+        index.exposed = True
+    
+    
+    class HostedWSGI(object):
+        _cp_config = {'tools.wsgiapp.on': True,
+                      'tools.wsgiapp.app': test_app,
+                      }
+    
+    cherrypy.config.update({'log_to_screen': False,
+                            'environment': 'production',
+                            'show_tracebacks': True,
+                            })
+    cherrypy.tree.mount(Root())
+    
+    conf0 = {'/static': {'tools.staticdir.on': True,
+                         'tools.staticdir.root': curdir,
+                         'tools.staticdir.dir': 'static',
+                         }}
+    cherrypy.tree.mount(HostedWSGI(), '/hosted/app0', conf0)
+
+
+import helper
+
+
+class WSGIAppTest(helper.CPWebCase):
+    
+    wsgi_output = '''Hello, world!
+This is a wsgi app running within CherryPy!'''
+
+    def test_01_standard_app(self):
+        self.getPage("/")
+        self.assertBody("I'm a regular CherryPy page handler!")
+    
+    def test_02_tools(self):
+        self.getPage("/hosted/app0")
+        self.assertHeader("Content-Type", "text/plain")
+        self.assertInBody(self.wsgi_output)
+    
+    def test_04_static_subdir(self):
+        self.getPage("/hosted/app0/static/index.html")
+        self.assertStatus('200 OK')
+        self.assertHeader('Content-Type', 'text/html')
+        self.assertBody('Hello, world\r\n')
+
+if __name__ == '__main__':
+    setup_server()
+    helper.testmain()
+

test/test_wsgiapp_filter.py

-import test
-test.prefer_parent_path()
-
-
-def setup_server():
-    import os
-    curdir = os.path.join(os.getcwd(), os.path.dirname(__file__))
-    
-    import cherrypy
-    
-    def test_app(environ, start_response):
-        status = '200 OK'
-        response_headers = [('Content-type', 'text/plain')]
-        start_response(status, response_headers)
-        yield 'Hello, world!\n'
-        yield 'This is a wsgi app running within CherryPy!\n\n'
-        keys = environ.keys()
-        keys.sort()
-        for k in keys:
-            yield '%s: %s\n' % (k,environ[k])
-    
-    class Root:
-        def index(self):
-            return "I'm a regular CherryPy page handler!"
-        index.exposed = True
-    
-    
-    class HostedWSGI(object):
-        _cp_config = {'tools.wsgiapp.on': True,
-                      'tools.wsgiapp.app': test_app,
-                      }
-    
-    cherrypy.config.update({'log_to_screen': False,
-                            'environment': 'production',
-                            'show_tracebacks': True,
-                            })
-    cherrypy.tree.mount(Root())
-    
-    conf0 = {'/static': {'tools.staticdir.on': True,
-                         'tools.staticdir.root': curdir,
-                         'tools.staticdir.dir': 'static',
-                         }}
-    cherrypy.tree.mount(HostedWSGI(), '/hosted/app0', conf0)
-
-
-import helper
-
-
-class WSGIAppFilterTest(helper.CPWebCase):
-    
-    wsgi_output = '''Hello, world!
-This is a wsgi app running within CherryPy!'''
-
-    def test_01_standard_app(self):
-        self.getPage("/")
-        self.assertBody("I'm a regular CherryPy page handler!")
-    
-    def test_02_cp_filters(self):
-        self.getPage("/hosted/app0")
-        self.assertHeader("Content-Type", "text/plain")
-        self.assertInBody(self.wsgi_output)
-    
-    def test_04_static_subdir(self):
-        self.getPage("/hosted/app0/static/index.html")
-        self.assertStatus('200 OK')
-        self.assertHeader('Content-Type', 'text/html')
-        self.assertBody('Hello, world\r\n')
-
-if __name__ == '__main__':
-    setup_server()
-    helper.testmain()
-

test/test_xmlrpc.py

+import test
+test.prefer_parent_path()
+import xmlrpclib
+
+
+def setup_server():
+    import cherrypy
+    from cherrypy import tools
+    
+    class Root:
+        def index(self):
+            return "I'm a standard index!"
+        index.exposed = True
+
+
+    class XmlRpc(tools.XMLRPCController):
+        
+        def return_single_item_list(self):
+            return [42]
+        return_single_item_list.exposed = True
+        
+        def return_string(self):
+            return "here is a string"
+        return_string.exposed = True
+        
+        def return_tuple(self):
+            return ('here', 'is', 1, 'tuple')
+        return_tuple.exposed = True
+        
+        def return_dict(self):
+            return dict(a=1, b=2, c=3)
+        return_dict.exposed = True
+        
+        def return_composite(self):
+            return dict(a=1,z=26), 'hi', ['welcome', 'friend']
+        return_composite.exposed = True
+
+        def return_int(self):
+            return 42
+        return_int.exposed = True
+
+        def return_float(self):
+            return 3.14
+        return_float.exposed = True
+
+        def return_datetime(self):
+            return xmlrpclib.DateTime((2003, 10, 7, 8, 1, 0, 1, 280, -1))
+        return_datetime.exposed = True
+
+        def return_boolean(self):
+            return True
+        return_boolean.exposed = True
+
+        def test_argument_passing(self, num):
+            return num * 2
+        test_argument_passing.exposed = True
+
+    root = Root()
+    root.xmlrpc = XmlRpc()
+    cherrypy.tree.mount(root)
+    cherrypy.config.update({
+        'log_to_screen': False,
+        'environment': 'production',
+        'show_tracebacks': True,
+        })
+
+
+import helper
+
+class XmlRpcTest(helper.CPWebCase):
+    def testXmlRpc(self):
+        
+        # load the appropriate xmlrpc proxy
+        url = 'http://localhost:%s/xmlrpc/' % (self.PORT)