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.auth.decorators import *
from webob.exc import *
from webob.request import *
from webob.response import *
import webob
import urllib
try:
import urllib.parse
@ -44,42 +43,67 @@ def allow(*methods):
return wrapper
class Response(Response):
class Response(webob.Response):
''':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
'''
ResponseClass = Response
@classmethod
def blank(cls, *args, **kwargs):
req = super(Request, cls).blank(*args, **kwargs)
def blank(cls, path, *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 = {}
return req
def relative_url(self, other_url, to_application=True, path_only=True,
**vars): #@ReservedAssignment
'''Create a new URL relative to the request URL
def create_href(self, path, **keywords):
'''Combine the application's path with a path to form an HREF
:param other_url: 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
: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 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)
if path_only:
url = urllib.parse.urlsplit(url).path
if vars:
url += '?' + urllib.urlencode(vars)
url = self._merge_url(self.script_name, path)
if keywords:
url += '?' + urllib.urlencode(keywords)
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
def static_resource(self, path):
@ -114,6 +138,9 @@ class Request(Request):
except KeyError:
return path
return self._merge_url(root, path)
def _merge_url(self, root, path):
if path.startswith('/'):
path = path[1:]
if not root.endswith('/'):

View File

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

View File

@ -44,7 +44,7 @@ class ResponseMaker(object):
for data in app_iter:
self.body += data
def testing_environ():
def environ_for_testing():
environ = {}
wsgiref.util.setup_testing_defaults(environ)
return environ
@ -61,7 +61,7 @@ def test_notfound():
'''
app = milla.app.Application(StubResolverUnresolved())
environ = testing_environ()
environ = environ_for_testing()
response = ResponseMaker()
app_iter = app(environ, response.start_response)
response.finish_response(app_iter)
@ -72,7 +72,7 @@ def test_favicon():
'''
app = milla.app.Application(StubResolverUnresolved())
environ = testing_environ()
environ = environ_for_testing()
environ.update({'PATH_INFO': '/favicon.ico'})
response = ResponseMaker()
app_iter = app(environ, response.start_response)
@ -85,7 +85,7 @@ def test_allow_header_disallowed():
'''
app = milla.app.Application(StubResolver())
environ = testing_environ()
environ = environ_for_testing()
environ.update({'REQUEST_METHOD': 'POST'})
response = ResponseMaker()
app_iter = app(environ, response.start_response)
@ -99,7 +99,7 @@ def test_allow_header_allowed():
resolver = StubResolver()
resolver.controller.allowed_methods = ('POST',)
app = milla.app.Application(resolver)
environ = testing_environ()
environ = environ_for_testing()
environ.update({'REQUEST_METHOD': 'POST'})
response = ResponseMaker()
app_iter = app(environ, response.start_response)
@ -113,7 +113,7 @@ def test_allow_header_options():
resolver = StubResolver()
resolver.controller.allowed_methods = ('GET',)
app = milla.app.Application(resolver)
environ = testing_environ()
environ = environ_for_testing()
environ.update({'REQUEST_METHOD': 'OPTIONS'})
response = ResponseMaker()
app_iter = app(environ, response.start_response)
@ -130,7 +130,7 @@ def test_emulated_method():
resolver = StubResolver()
resolver.controller.allowed_methods = ('PUT',)
app = milla.app.Application(resolver)
environ = testing_environ()
environ = environ_for_testing()
environ.update({
'REQUEST_METHOD': 'POST',
'CONTENT_TYPE': 'application/x-www-form-urlencoded',
@ -156,7 +156,7 @@ def test_function_before():
resolver = StubResolver()
resolver.controller.__before__ = before
app = milla.app.Application(resolver)
environ = testing_environ()
environ = environ_for_testing()
response = ResponseMaker()
app(environ, response.start_response)
@ -172,7 +172,7 @@ def test_instance_before():
return 'success'
app = milla.app.Application(StubResolver(Controller()))
environ = testing_environ()
environ = environ_for_testing()
response = ResponseMaker()
app(environ, response.start_response)
@ -188,7 +188,7 @@ def test_instancemethod_before():
return 'success'
app = milla.app.Application(StubResolver(Controller().foo))
environ = testing_environ()
environ = environ_for_testing()
response = ResponseMaker()
app(environ, response.start_response)
@ -206,7 +206,7 @@ def test_partial_function_before():
resolver = StubResolver()
resolver.controller = functools.partial(controller, text='success')
app = milla.app.Application(resolver)
environ = testing_environ()
environ = environ_for_testing()
response = ResponseMaker()
app(environ, response.start_response)
@ -224,7 +224,7 @@ def test_partial_instance_before():
resolver = StubResolver()
resolver.controller = functools.partial(Controller(), text='success')
app = milla.app.Application(resolver)
environ = testing_environ()
environ = environ_for_testing()
response = ResponseMaker()
app(environ, response.start_response)
@ -245,7 +245,7 @@ def test_partial_instancemethod_before():
resolver = StubResolver()
resolver.controller = functools.partial(Controller().foo, text='success')
app = milla.app.Application(resolver)
environ = testing_environ()
environ = environ_for_testing()
response = ResponseMaker()
app(environ, response.start_response)
@ -260,7 +260,7 @@ def test_function_after():
resolver = StubResolver()
resolver.controller.__after__ = after
app = milla.app.Application(resolver)
environ = testing_environ()
environ = environ_for_testing()
response = ResponseMaker()
app(environ, response.start_response)
@ -276,7 +276,7 @@ def test_instance_after():
return 'success'
app = milla.app.Application(StubResolver(Controller()))
environ = testing_environ()
environ = environ_for_testing()
response = ResponseMaker()
app(environ, response.start_response)
@ -292,7 +292,7 @@ def test_instancemethod_after():
return 'success'
app = milla.app.Application(StubResolver(Controller().foo))
environ = testing_environ()
environ = environ_for_testing()
response = ResponseMaker()
app(environ, response.start_response)
@ -310,7 +310,7 @@ def test_partial_function_after():
resolver = StubResolver()
resolver.controller = functools.partial(controller, text='success')
app = milla.app.Application(resolver)
environ = testing_environ()
environ = environ_for_testing()
response = ResponseMaker()
app(environ, response.start_response)
@ -328,7 +328,7 @@ def test_partial_instance_after():
resolver = StubResolver()
resolver.controller = functools.partial(Controller(), text='success')
app = milla.app.Application(resolver)
environ = testing_environ()
environ = environ_for_testing()
response = ResponseMaker()
app(environ, response.start_response)
@ -349,7 +349,7 @@ def test_partial_instancemethod_after():
resolver = StubResolver()
resolver.controller = functools.partial(Controller().foo, text='success')
app = milla.app.Application(resolver)
environ = testing_environ()
environ = environ_for_testing()
response = ResponseMaker()
app(environ, response.start_response)
@ -361,7 +361,7 @@ def test_httperror_response():
raise webob.exc.HTTPClientError('NotFound')
app = milla.app.Application(StubResolver(controller))
environ = testing_environ()
environ = environ_for_testing()
response = ResponseMaker()
app_iter = app(environ, response.start_response)
response.finish_response(app_iter)
@ -386,7 +386,7 @@ def test_single_start_response():
return 'test'
app = milla.app.Application(StubResolver(controller))
environ = testing_environ()
environ = environ_for_testing()
response = ResponseMaker()
start_response = TestStartResponse(response.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 response.headers.startswith('HTTP/1.1 200 OK'), response.headers
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'