thirdparty/google_appengine/lib/webob/tests/test_response.txt
changeset 109 620f9b141567
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/thirdparty/google_appengine/lib/webob/tests/test_response.txt	Tue Aug 26 21:49:54 2008 +0000
@@ -0,0 +1,254 @@
+This demonstrates how the Response object works, and tests it at the
+same time.
+
+    >>> from dtopt import ELLIPSIS
+    >>> from webob import Response, UTC
+    >>> from datetime import datetime
+    >>> res = Response('Test', status='200 OK')
+
+This is a minimal response object.  We can do things like get and set
+the body:
+
+    >>> res.body
+    'Test'
+    >>> res.body = 'Another test'
+    >>> res.body
+    'Another test'
+    >>> res.body = 'Another'
+    >>> res.write(' test')
+    >>> res.app_iter
+    ['Another test']
+    >>> res.content_length
+    12
+    >>> res.headers['content-length']
+    '12'
+    
+Content-Length is only applied when setting the body to a string; you
+have to set it manually otherwise.  There are also getters and setters
+for the various pieces:
+
+    >>> res.app_iter = ['test']
+    >>> print res.content_length
+    None
+    >>> res.content_length = 4
+    >>> res.status
+    '200 OK'
+    >>> res.status_int
+    200
+    >>> res.headers
+    HeaderDict([('content-type', 'text/html; charset=utf8'), ('Content-Length', '4')])
+    >>> res.headerlist
+    [('content-type', 'text/html; charset=utf8'), ('Content-Length', '4')]
+
+Content-type and charset are handled separately as properties, though
+they are both in the ``res.headers['content-type']`` header:
+
+    >>> res.content_type
+    'text/html'
+    >>> res.content_type = 'text/html'
+    >>> res.content_type
+    'text/html'
+    >>> res.charset
+    'utf8'
+    >>> res.charset = 'iso-8859-1'
+    >>> res.charset
+    'iso-8859-1'
+    >>> res.content_type
+    'text/html'
+    >>> res.headers['content-type']
+    'text/html; charset=iso-8859-1'
+
+Cookie handling is done through methods:
+
+    >>> res.set_cookie('test', 'value')
+    >>> res.headers['set-cookie']
+    'test=value; Path=/'
+    >>> res.set_cookie('test2', 'value2', max_age=10000)
+    >>> res.headers['set-cookie'] # We only see the last header
+    'test2=value2; Max-Age=10000; Path=/'
+    >>> res.headers.getall('set-cookie')
+    ['test=value; Path=/', 'test2=value2; Max-Age=10000; Path=/']
+    >>> res.unset_cookie('test')
+    >>> res.headers.getall('set-cookie')
+    ['test2=value2; Max-Age=10000; Path=/']
+
+Most headers are available in a parsed getter/setter form through
+properties:
+
+    >>> res.age = 10
+    >>> res.age, res.headers['age']
+    (10, '10')
+    >>> res.allow = ['GET', 'PUT']
+    >>> res.allow, res.headers['allow']
+    (['GET', 'PUT'], 'GET, PUT')
+    >>> res.cache_control
+    <CacheControl ''>
+    >>> print res.cache_control.max_age
+    None
+    >>> res.cache_control.properties['max-age'] = None
+    >>> print res.cache_control.max_age
+    -1
+    >>> res.cache_control.max_age = 10
+    >>> res.cache_control
+    <CacheControl 'max-age=10'>
+    >>> res.headers['cache-control']
+    'max-age=10'
+    >>> res.cache_control.max_stale = 10
+    Traceback (most recent call last):
+        ...
+    AttributeError: The property max-stale only applies to request Cache-Control
+    >>> res.cache_control = {}
+    >>> res.cache_control
+    <CacheControl ''>
+    >>> res.content_encoding = 'gzip'
+    >>> (res.content_encoding, res.headers['content-encoding'])
+    ('gzip', 'gzip')
+    >>> res.content_language = 'en'
+    >>> (res.content_language, res.headers['content-language'])
+    (['en'], 'en')
+    >>> res.content_location = 'http://localhost:8080'
+    >>> res.headers['content-location']
+    'http://localhost:8080'
+    >>> res.content_range = (0, 100, 1000)
+    >>> (res.content_range, res.headers['content-range'])
+    (<ContentRange bytes 0-101/1000>, 'bytes 0-101/1000')
+    >>> res.date = datetime(2005, 1, 1, 12, 0, tzinfo=UTC)
+    >>> (res.date, res.headers['date'])
+    (datetime.datetime(2005, 1, 1, 12, 0, tzinfo=UTC), 'Sat, 01 Jan 2005 12:00:00 GMT')
+    >>> print res.etag
+    None
+    >>> res.etag = 'foo'
+    >>> (res.etag, res.headers['etag'])
+    ('foo', 'foo')
+    >>> res.expires = res.date
+    >>> res.retry_after = 120 # two minutes
+    >>> res.retry_after
+    datetime.datetime(...)
+    >>> res.server = 'Python/foo'
+    >>> res.headers['server']
+    'Python/foo'
+    >>> res.vary = ['Cookie']
+    >>> (res.vary, res.headers['vary'])
+    (['Cookie'], 'Cookie')
+
+The location header will try to absolutify itself if you have a
+request object attached.
+
+    >>> res.location = '/test.html'
+    >>> from webob import Request
+    >>> res.request = Request.blank('/')
+    >>> res.location
+    'http://localhost/test.html'
+    >>> res.request = None
+    >>> res.location
+    '/test.html'
+    >>> res.request = Request.blank('/')
+    >>> res.location = '/test2.html'
+    >>> res.request = None
+    >>> res.location
+    'http://localhost/test2.html'
+
+There's some conditional response handling too (you have to turn on
+conditioanl_response)::
+
+    >>> res = Response(conditional_response=True)
+    >>> req = Request.blank('/')
+    >>> res.etag = 'tag'
+    >>> req.if_none_match = 'tag'
+    >>> req.get_response(res)
+    <Response ... 304 Not Modified>
+    >>> res.etag = 'other-tag'
+    >>> req.get_response(res)
+    <Response ... 200 OK>
+    >>> del req.if_none_match
+    >>> req.if_modified_since = datetime(2005, 1, 1, 12, 1, tzinfo=UTC)
+    >>> res.last_modified = datetime(2005, 1, 1, 12, 1, tzinfo=UTC)
+    >>> req.get_response(res)
+    <Response ... 304 Not Modified>
+    >>> res.last_modified = datetime(2006, 1, 1, 12, 1, tzinfo=UTC)
+    >>> req.get_response(res)
+    <Response ... 200 OK>
+    >>> res.last_modified = None
+    >>> req.get_response(res)
+    <Response ... 200 OK>
+
+Also range response::
+
+    >>> res = Response(conditional_response=True)
+    >>> req = Request.blank('/')
+    >>> res.body = '0123456789'
+    >>> req.range = (1, 5)
+    >>> result = req.get_response(res)
+    >>> result.body
+    '1234'
+    >>> result.content_range
+    <ContentRange bytes 1-6/10>
+    >>> tuple(result.content_range)
+    (1, 5, 10)
+    >>> # Now an invalid range:
+    >>> req.range = (0, 20)
+    >>> str(req.range)
+    'bytes=0-21'
+    >>> result = req.get_response(res)
+    >>> result.body
+    '0123456789'
+    >>> print result.content_range
+    None
+
+That was easier; we'll try it with a iterator for the body::
+
+    >>> res = Response(conditional_response=True)
+    >>> res.app_iter = ['01234', '567', '89']
+    >>> req = Request.blank('/')
+    >>> req.range = (1, 5)
+    >>> result = req.get_response(res)
+    >>> # Because we don't know the length of the app_iter, this
+    >>> # doesn't work:
+    >>> result.body
+    '0123456789'
+    >>> print result.content_range
+    None
+    >>> req.range = (5, None)
+    >>> result = req.get_response(res)
+    >>> result.body
+    '56789'
+    >>> result.content_range
+    <ContentRange bytes 5-*/10>
+    >>> # If we set Content-Length then we can use it with an app_iter
+    >>> res.content_length = 10
+    >>> req.range = (1, 5)
+    >>> result = req.get_response(res)
+    >>> result.body
+    '1234'
+    >>> result.content_range
+    <ContentRange bytes 1-6/10>
+    >>> # And trying If-modified-since
+    >>> res.etag = 'foobar'
+    >>> req.if_range = 'foobar'
+    >>> req.if_range
+    <IfRange etag=foobar, date=*>
+    >>> result = req.get_response(res)
+    >>> result.content_range
+    <ContentRange bytes 1-6/10>
+    >>> req.if_range = 'blah'
+    >>> result = req.get_response(res)
+    >>> result.content_range
+    >>> req.if_range = datetime(2005, 1, 1, 12, 0, tzinfo=UTC)
+    >>> res.last_modified = datetime(2005, 1, 1, 12, 0, tzinfo=UTC)
+    >>> result = req.get_response(res)
+    >>> result.content_range
+    <ContentRange bytes 1-6/10>
+    >>> res.last_modified = datetime(2006, 1, 1, 12, 0, tzinfo=UTC)
+    >>> result = req.get_response(res)
+    >>> result.content_range
+
+Some tests of exceptions::
+
+    >>> from webob import exc
+    >>> res = exc.HTTPNotFound('Not found!')
+    >>> res.exception.content_type = 'text/plain'
+    >>> res.content_type
+    'text/plain'
+    >>> res = exc.HTTPNotModified()
+    >>> res.headers
+    HeaderDict([])