Merge default into py3k

--HG--
branch : py3k
master
Dustin C. Hatch 2012-11-30 22:11:23 -06:00
commit f8e89d46c6
3 changed files with 137 additions and 49 deletions

View File

@ -18,8 +18,7 @@
from milla.app import * from milla.app import *
from milla.auth.decorators import * from milla.auth.decorators import *
from webob.exc import * from webob.exc import *
from webob.request import * import webob
from webob.response import *
import urllib import urllib
try: try:
import urllib.parse import urllib.parse
@ -44,42 +43,67 @@ def allow(*methods):
return wrapper return wrapper
class Response(Response): class Response(webob.Response):
''':py:class:`WebOb Response <webob.response.Response>` with minor tweaks ''':py:class:`WebOb Response <webob.response.Response>` with minor tweaks
''' '''
class Request(Request): class Request(webob.Request):
''':py:class:`WebOb Request <webob.request.BaseRequest>` with minor tweaks ''':py:class:`WebOb Request <webob.request.BaseRequest>` with minor tweaks
''' '''
ResponseClass = Response ResponseClass = Response
@classmethod @classmethod
def blank(cls, *args, **kwargs): def blank(cls, path, *args, **kwargs):
req = super(Request, cls).blank(*args, **kwargs) '''Create a simple request for the specified path
See :py:meth:`webob.Request.blank <webob.request.BaseRequest.blank>`
for information on other arguments and keywords
'''
req = super(Request, cls).blank(path, *args, **kwargs)
req.config = {} req.config = {}
return req return req
def relative_url(self, other_url, to_application=True, path_only=True, def create_href(self, path, **keywords):
**vars): #@ReservedAssignment '''Combine the application's path with a path to form an HREF
'''Create a new URL relative to the request URL
:param other_url: relative path to join with the request URL :param path: relative path to join with the request URL
:param to_application: If true, generated URL will be relative
to the application's root path, otherwise relative to the
server root
:param path_only: If true, scheme and host will be omitted
Any other keyword arguments will be encoded and appended to the URL Any other keyword arguments will be encoded and appended to the URL
as querystring arguments. as querystring arguments.
The HREF returned will will be the absolute path on the same host
and protocol as the request. To get the full URL including scheme
and host information, use :py:meth:`create_href_full` instead.
''' '''
url = super(Request, self).relative_url(other_url, to_application) url = self._merge_url(self.script_name, path)
if path_only:
url = urllib.parse.urlsplit(url).path if keywords:
if vars: url += '?' + urllib.urlencode(keywords)
url += '?' + urllib.urlencode(vars)
return url
def create_href_full(self, path, **keywords):
'''Combine the application's full URL with a path to form a new URL
:param path: relative path to join with the request URL
Any other keyword arguments will be encoded and appended to the
URL as querystring arguments/
The HREF returned will be the full URL, including scheme and host
information. To get the path only, use :py:meth:`create_href`
instead.
'''
url = self._merge_url(self.application_url, path)
if keywords:
url += '?' + urllib.urlencode(keywords)
return url return url
def static_resource(self, path): def static_resource(self, path):
@ -114,6 +138,9 @@ class Request(Request):
except KeyError: except KeyError:
return path return path
return self._merge_url(root, path)
def _merge_url(self, root, path):
if path.startswith('/'): if path.startswith('/'):
path = path[1:] path = path[1:]
if not root.endswith('/'): if not root.endswith('/'):

View File

@ -221,7 +221,7 @@ class Generator(object):
url = Generator(request).generate url = Generator(request).generate
.. deprecated:: 0.2 .. deprecated:: 0.2
Use :py:meth:`milla.Request.relative_url` instead. Use :py:meth:`milla.Request.create_href` instead.
''' '''
def __init__(self, request, path_only=True): def __init__(self, request, path_only=True):
@ -229,7 +229,7 @@ class Generator(object):
self.path_only = path_only self.path_only = path_only
warnings.warn( warnings.warn(
'Use of Generator is deprecated; ' 'Use of Generator is deprecated; '
'use milla.Request.relative_url instead', 'use milla.Request.create_href instead',
DeprecationWarning, DeprecationWarning,
stacklevel=2 stacklevel=2
) )
@ -239,10 +239,8 @@ class Generator(object):
''' '''
path = '/'.join(str(s) for s in segments) path = '/'.join(str(s) for s in segments)
while path.startswith('/'):
path = path[1:]
return self.request.relative_url(path, if self.path_only:
to_application=True, return self.request.create_href(path, **vars)
path_only=self.path_only, else:
**vars) return self.request.create_href_full(path, **vars)

View File

@ -44,7 +44,7 @@ class ResponseMaker(object):
for data in app_iter: for data in app_iter:
self.body += data self.body += data
def testing_environ(): def environ_for_testing():
environ = {} environ = {}
wsgiref.util.setup_testing_defaults(environ) wsgiref.util.setup_testing_defaults(environ)
return environ return environ
@ -61,7 +61,7 @@ def test_notfound():
''' '''
app = milla.app.Application(StubResolverUnresolved()) app = milla.app.Application(StubResolverUnresolved())
environ = testing_environ() environ = environ_for_testing()
response = ResponseMaker() response = ResponseMaker()
app_iter = app(environ, response.start_response) app_iter = app(environ, response.start_response)
response.finish_response(app_iter) response.finish_response(app_iter)
@ -72,7 +72,7 @@ def test_favicon():
''' '''
app = milla.app.Application(StubResolverUnresolved()) app = milla.app.Application(StubResolverUnresolved())
environ = testing_environ() environ = environ_for_testing()
environ.update({'PATH_INFO': '/favicon.ico'}) environ.update({'PATH_INFO': '/favicon.ico'})
response = ResponseMaker() response = ResponseMaker()
app_iter = app(environ, response.start_response) app_iter = app(environ, response.start_response)
@ -85,7 +85,7 @@ def test_allow_header_disallowed():
''' '''
app = milla.app.Application(StubResolver()) app = milla.app.Application(StubResolver())
environ = testing_environ() environ = environ_for_testing()
environ.update({'REQUEST_METHOD': 'POST'}) environ.update({'REQUEST_METHOD': 'POST'})
response = ResponseMaker() response = ResponseMaker()
app_iter = app(environ, response.start_response) app_iter = app(environ, response.start_response)
@ -99,7 +99,7 @@ def test_allow_header_allowed():
resolver = StubResolver() resolver = StubResolver()
resolver.controller.allowed_methods = ('POST',) resolver.controller.allowed_methods = ('POST',)
app = milla.app.Application(resolver) app = milla.app.Application(resolver)
environ = testing_environ() environ = environ_for_testing()
environ.update({'REQUEST_METHOD': 'POST'}) environ.update({'REQUEST_METHOD': 'POST'})
response = ResponseMaker() response = ResponseMaker()
app_iter = app(environ, response.start_response) app_iter = app(environ, response.start_response)
@ -113,7 +113,7 @@ def test_allow_header_options():
resolver = StubResolver() resolver = StubResolver()
resolver.controller.allowed_methods = ('GET',) resolver.controller.allowed_methods = ('GET',)
app = milla.app.Application(resolver) app = milla.app.Application(resolver)
environ = testing_environ() environ = environ_for_testing()
environ.update({'REQUEST_METHOD': 'OPTIONS'}) environ.update({'REQUEST_METHOD': 'OPTIONS'})
response = ResponseMaker() response = ResponseMaker()
app_iter = app(environ, response.start_response) app_iter = app(environ, response.start_response)
@ -130,7 +130,7 @@ def test_emulated_method():
resolver = StubResolver() resolver = StubResolver()
resolver.controller.allowed_methods = ('PUT',) resolver.controller.allowed_methods = ('PUT',)
app = milla.app.Application(resolver) app = milla.app.Application(resolver)
environ = testing_environ() environ = environ_for_testing()
environ.update({ environ.update({
'REQUEST_METHOD': 'POST', 'REQUEST_METHOD': 'POST',
'CONTENT_TYPE': 'application/x-www-form-urlencoded', 'CONTENT_TYPE': 'application/x-www-form-urlencoded',
@ -156,7 +156,7 @@ def test_function_before():
resolver = StubResolver() resolver = StubResolver()
resolver.controller.__before__ = before resolver.controller.__before__ = before
app = milla.app.Application(resolver) app = milla.app.Application(resolver)
environ = testing_environ() environ = environ_for_testing()
response = ResponseMaker() response = ResponseMaker()
app(environ, response.start_response) app(environ, response.start_response)
@ -172,7 +172,7 @@ def test_instance_before():
return 'success' return 'success'
app = milla.app.Application(StubResolver(Controller())) app = milla.app.Application(StubResolver(Controller()))
environ = testing_environ() environ = environ_for_testing()
response = ResponseMaker() response = ResponseMaker()
app(environ, response.start_response) app(environ, response.start_response)
@ -188,7 +188,7 @@ def test_instancemethod_before():
return 'success' return 'success'
app = milla.app.Application(StubResolver(Controller().foo)) app = milla.app.Application(StubResolver(Controller().foo))
environ = testing_environ() environ = environ_for_testing()
response = ResponseMaker() response = ResponseMaker()
app(environ, response.start_response) app(environ, response.start_response)
@ -206,7 +206,7 @@ def test_partial_function_before():
resolver = StubResolver() resolver = StubResolver()
resolver.controller = functools.partial(controller, text='success') resolver.controller = functools.partial(controller, text='success')
app = milla.app.Application(resolver) app = milla.app.Application(resolver)
environ = testing_environ() environ = environ_for_testing()
response = ResponseMaker() response = ResponseMaker()
app(environ, response.start_response) app(environ, response.start_response)
@ -224,7 +224,7 @@ def test_partial_instance_before():
resolver = StubResolver() resolver = StubResolver()
resolver.controller = functools.partial(Controller(), text='success') resolver.controller = functools.partial(Controller(), text='success')
app = milla.app.Application(resolver) app = milla.app.Application(resolver)
environ = testing_environ() environ = environ_for_testing()
response = ResponseMaker() response = ResponseMaker()
app(environ, response.start_response) app(environ, response.start_response)
@ -245,7 +245,7 @@ def test_partial_instancemethod_before():
resolver = StubResolver() resolver = StubResolver()
resolver.controller = functools.partial(Controller().foo, text='success') resolver.controller = functools.partial(Controller().foo, text='success')
app = milla.app.Application(resolver) app = milla.app.Application(resolver)
environ = testing_environ() environ = environ_for_testing()
response = ResponseMaker() response = ResponseMaker()
app(environ, response.start_response) app(environ, response.start_response)
@ -260,7 +260,7 @@ def test_function_after():
resolver = StubResolver() resolver = StubResolver()
resolver.controller.__after__ = after resolver.controller.__after__ = after
app = milla.app.Application(resolver) app = milla.app.Application(resolver)
environ = testing_environ() environ = environ_for_testing()
response = ResponseMaker() response = ResponseMaker()
app(environ, response.start_response) app(environ, response.start_response)
@ -276,7 +276,7 @@ def test_instance_after():
return 'success' return 'success'
app = milla.app.Application(StubResolver(Controller())) app = milla.app.Application(StubResolver(Controller()))
environ = testing_environ() environ = environ_for_testing()
response = ResponseMaker() response = ResponseMaker()
app(environ, response.start_response) app(environ, response.start_response)
@ -292,7 +292,7 @@ def test_instancemethod_after():
return 'success' return 'success'
app = milla.app.Application(StubResolver(Controller().foo)) app = milla.app.Application(StubResolver(Controller().foo))
environ = testing_environ() environ = environ_for_testing()
response = ResponseMaker() response = ResponseMaker()
app(environ, response.start_response) app(environ, response.start_response)
@ -310,7 +310,7 @@ def test_partial_function_after():
resolver = StubResolver() resolver = StubResolver()
resolver.controller = functools.partial(controller, text='success') resolver.controller = functools.partial(controller, text='success')
app = milla.app.Application(resolver) app = milla.app.Application(resolver)
environ = testing_environ() environ = environ_for_testing()
response = ResponseMaker() response = ResponseMaker()
app(environ, response.start_response) app(environ, response.start_response)
@ -328,7 +328,7 @@ def test_partial_instance_after():
resolver = StubResolver() resolver = StubResolver()
resolver.controller = functools.partial(Controller(), text='success') resolver.controller = functools.partial(Controller(), text='success')
app = milla.app.Application(resolver) app = milla.app.Application(resolver)
environ = testing_environ() environ = environ_for_testing()
response = ResponseMaker() response = ResponseMaker()
app(environ, response.start_response) app(environ, response.start_response)
@ -349,7 +349,7 @@ def test_partial_instancemethod_after():
resolver = StubResolver() resolver = StubResolver()
resolver.controller = functools.partial(Controller().foo, text='success') resolver.controller = functools.partial(Controller().foo, text='success')
app = milla.app.Application(resolver) app = milla.app.Application(resolver)
environ = testing_environ() environ = environ_for_testing()
response = ResponseMaker() response = ResponseMaker()
app(environ, response.start_response) app(environ, response.start_response)
@ -361,7 +361,7 @@ def test_httperror_response():
raise webob.exc.HTTPClientError('NotFound') raise webob.exc.HTTPClientError('NotFound')
app = milla.app.Application(StubResolver(controller)) app = milla.app.Application(StubResolver(controller))
environ = testing_environ() environ = environ_for_testing()
response = ResponseMaker() response = ResponseMaker()
app_iter = app(environ, response.start_response) app_iter = app(environ, response.start_response)
response.finish_response(app_iter) response.finish_response(app_iter)
@ -386,7 +386,7 @@ def test_single_start_response():
return 'test' return 'test'
app = milla.app.Application(StubResolver(controller)) app = milla.app.Application(StubResolver(controller))
environ = testing_environ() environ = environ_for_testing()
response = ResponseMaker() response = ResponseMaker()
start_response = TestStartResponse(response.start_response) start_response = TestStartResponse(response.start_response)
app_iter = app(environ, start_response) app_iter = app(environ, start_response)
@ -394,3 +394,66 @@ def test_single_start_response():
assert start_response.call_count == 1, start_response.call_count assert start_response.call_count == 1, start_response.call_count
assert response.headers.startswith('HTTP/1.1 200 OK'), response.headers assert response.headers.startswith('HTTP/1.1 200 OK'), response.headers
assert response.body == b'test', response.body assert response.body == b'test', response.body
def test_allow_decorator():
'''Ensure allow decorator sets allowed_methods on controllers'''
@milla.allow('GET', 'HEAD', 'POST')
def controller(request):
return 'success'
assert controller.allowed_methods == ('GET', 'HEAD', 'POST')
def test_create_href_simple():
'''Request.create_href creates a valid URL path from the application root'''
environ = environ_for_testing()
request = milla.Request(environ)
url = request.create_href('/bar')
assert url == '/bar', url
def test_create_href_nonroot():
'''Request.create_href handles applications mounted somewhere besides /'''
environ = environ_for_testing()
environ.update({
'SCRIPT_NAME': '/test'
})
request = milla.Request(environ)
url = request.create_href('/bar')
assert url == '/test/bar', url
def test_create_href_full():
'''Request.create_href_full creates appropriate full URL'''
environ = environ_for_testing()
request = milla.Request(environ)
url = request.create_href_full('/bar')
assert url == 'http://127.0.0.1/bar', url
def test_create_href_full_nonroot():
'''Request.create_href_full creates correct full URL for nonroot applications'''
environ = environ_for_testing()
environ.update({
'SCRIPT_NAME': '/test'
})
request = milla.Request(environ)
url = request.create_href_full('/bar')
assert url == 'http://127.0.0.1/test/bar', url
def test_create_href_keywords():
'''Request.create_href properly appends querystring arguments'''
environ = environ_for_testing()
request = milla.Request(environ)
url = request.create_href('/bar', foo='baz')
assert url == '/bar?foo=baz'
def test_create_href_full_keywords():
'''Request.create_href_full properly appends querystring arguments'''
environ = environ_for_testing()
request = milla.Request(environ)
url = request.create_href_full('/bar', foo='baz')
assert url == 'http://127.0.0.1/bar?foo=baz'