blob: a68de4ca9f76e85e160e70f15bb52c037486e0cc [file] [log] [blame]
# -*- coding: utf-8 -*-
import random
import webapp2
from webapp2 import BaseRoute, RedirectHandler, Request, Route, Router
import test_base
class TestRoute(test_base.BaseTestCase):
def test_no_variable(self):
route = Route(r'/hello', None)
route, args, kwargs = route.match(Request.blank('/hello'))
self.assertEqual(kwargs, {})
url = route.build(Request.blank('/'), (), {})
self.assertEqual(url, '/hello')
route = Route(r'/hello/world/', None)
route, args, kwargs = route.match(Request.blank('/hello/world/'))
self.assertEqual(kwargs, {})
url = route.build(Request.blank('/'), (), {})
self.assertEqual(url, '/hello/world/')
def test_repetition_operator(self):
route = Route(r'/<:\d>', None)
self.assertEqual(route.match(Request.blank('/1')), (route, ('1',), {}))
self.assertEqual(route.match(Request.blank('/2')), (route, ('2',), {}))
route = Route(r'/<:\d{2,3}>', None)
self.assertEqual(route.match(Request.blank('/11')), (route, ('11',), {}))
self.assertEqual(route.match(Request.blank('/111')), (route, ('111',), {}))
self.assertEqual(route.match(Request.blank('/1111')), None)
def test_unnamed_variable(self):
route = Route(r'/<:\d{4}>', None)
self.assertEqual(route.match(Request.blank('/2010')), (route, ('2010',), {}))
self.assertEqual(route.match(Request.blank('/aaaa')), None)
route = Route(r'/<:\d{2}>.<:\d{2}>', None)
self.assertEqual(route.match(Request.blank('/98.99')), (route, ('98', '99'), {}))
self.assertEqual(route.match(Request.blank('/aa.aa')), None)
route = Route(r'/<:\d{2}>.<:\d{2}>/<foo>', None)
self.assertEqual(route.match(Request.blank('/98.99/test')), (route, ('98', '99'), {'foo': 'test'}))
self.assertEqual(route.match(Request.blank('/aa.aa/test')), None)
def test_simple_variable(self):
route = Route(r'/<foo>', None)
self.assertEqual(route.match(Request.blank('/bar')), (route, (), {'foo': 'bar'}))
url = route.build(Request.blank('/'), (), dict(foo='baz'))
self.assertEqual(url, '/baz')
def test_expr_variable(self):
route = Route(r'/<year:\d{4}>', None)
self.assertEqual(route.match(Request.blank('/bar')), None)
self.assertEqual(route.match(Request.blank('/2010')), (route, (), {'year': '2010'}))
self.assertEqual(route.match(Request.blank('/1900')), (route, (), {'year': '1900'}))
url = route.build(Request.blank('/'), (), dict(year='2010'))
self.assertEqual(url, '/2010')
def test_expr_variable2(self):
route = Route(r'/<year:\d{4}>/foo/', None)
url = route.build(Request.blank('/'), (), dict(year='2010'))
self.assertEqual(url, '/2010/foo/')
def test_build_missing_argument(self):
route = Route(r'/<:\d{4}>', None)
self.assertRaises(KeyError, route.build, Request.blank('/'), (), {})
route = Route(r'/<:\d{4}>/<:\d{2}>', None)
self.assertRaises(KeyError, route.build, Request.blank('/'), (2010,), {})
def test_build_invalid_argument(self):
route = Route(r'/<:\d{4}>', None)
self.assertRaises(ValueError, route.build, Request.blank('/'), ('20100',), {})
def test_build_invalid_argument2(self):
route = Route(r'/<:\d{4}>', None)
self.assertRaises(ValueError, route.build, Request.blank('/'), ('201a',), {})
def test_build_missing_keyword(self):
route = Route(r'/<year:\d{4}>', None)
self.assertRaises(KeyError, route.build, Request.blank('/'), (), {})
def test_build_missing_keyword2(self):
route = Route(r'/<year:\d{4}>/<month:\d{2}>', None)
self.assertRaises(KeyError, route.build, Request.blank('/'), (), dict(year='2010'))
def test_build_invalid_keyword(self):
route = Route(r'/<year:\d{4}>', None)
self.assertRaises(ValueError, route.build, Request.blank('/'), (), dict(year='20100'))
def test_build_invalid_keyword2(self):
route = Route(r'/<year:\d{4}>', None)
self.assertRaises(ValueError, route.build, Request.blank('/'), (), dict(year='201a'))
def test_build_with_unnamed_variable(self):
route = Route(r'/<:\d{4}>/<month:\d{2}>', None)
url = route.build(Request.blank('/'), (2010,), dict(month=10))
self.assertEqual(url, '/2010/10')
url = route.build(Request.blank('/'), ('1999',), dict(month='07'))
self.assertEqual(url, '/1999/07')
def test_build_default_keyword(self):
route = Route(r'/<year:\d{4}>/<month:\d{2}>', None,
defaults={'month': 10})
url = route.build(Request.blank('/'), (), dict(year='2010'))
self.assertEqual(url, '/2010/10')
route = Route(r'/<year:\d{4}>/<month:\d{2}>', None,
defaults={'year': 1900})
url = route.build(Request.blank('/'), (), dict(month='07'))
self.assertEqual(url, '/1900/07')
def test_build_extra_keyword(self):
route = Route(r'/<year:\d{4}>', None)
url = route.build(Request.blank('/'), (), dict(year='2010', foo='bar'))
self.assertEqual(url, '/2010?foo=bar')
# Arguments are sorted.
url = route.build(Request.blank('/'), (), dict(year='2010', foo='bar', baz='ding'))
self.assertEqual(url, '/2010?baz=ding&foo=bar')
def test_build_extra_positional_keyword(self):
route = Route(r'/<year:\d{4}>/<:\d{2}>', None)
url = route.build(Request.blank('/'), ('08', 'i-should-be-ignored', 'me-too'), dict(year='2010', foo='bar'))
self.assertEqual(url, '/2010/08?foo=bar')
url = route.build(Request.blank('/'), ('08', 'i-should-be-ignored', 'me-too'), dict(year='2010', foo='bar', baz='ding'))
self.assertEqual(url, '/2010/08?baz=ding&foo=bar')
def test_build_int_keyword(self):
route = Route(r'/<year:\d{4}>', None)
url = route.build(Request.blank('/'), (), dict(year=2010))
self.assertEqual(url, '/2010')
def test_build_int_variable(self):
route = Route(r'/<:\d{4}>', None)
url = route.build(Request.blank('/'), (2010,), {})
self.assertEqual(url, '/2010')
def test_router_build_error(self):
router = Router(None)
router.add(Route('/<year:\d{4}>', None, name='year-page'))
url = router.build(Request.blank('/'), 'year-page', (), dict(year='2010'))
self.assertEqual(url, '/2010')
self.assertRaises(KeyError, router.build, Request.blank('/'), 'i-dont-exist', (), dict(year='2010'))
def test_reverse_template(self):
route = Route('/foo', None)
# Access route.regex just to set the lazy properties.
regex = route.regex
self.assertEqual(route.reverse_template, '/foo')
route = Route('/foo/<bar>', None)
# Access route.regex just to set the lazy properties.
regex = route.regex
self.assertEqual(route.reverse_template, '/foo/%(bar)s')
route = Route('/foo/<bar>/<baz:\d>', None)
# Access route.regex just to set the lazy properties.
regex = route.regex
self.assertEqual(route.reverse_template, '/foo/%(bar)s/%(baz)s')
def test_invalid_template(self):
# To break it:
# <>foo:><bar<:baz>
route = Route('/<foo/<:bar', None)
# Access route.regex just to set the lazy properties.
regex = route.regex
self.assertEqual(route.reverse_template, '/<foo/<:bar')
def test_build_full_without_request(self):
router = Router(None)
router.add(Route(r'/hello', None, name='hello'))
self.assertRaises(AttributeError, router.build, None, 'hello', (), dict(_full=True))
self.assertRaises(AttributeError, router.build, None, 'hello', (), dict(_scheme='https'))
def test_positions(self):
template = '/<:\d+>' * 98
args = tuple(str(i) for i in range(98))
url_res = '/' + '/'.join(args)
route = Route(template, None)
self.assertEqual(route.match(Request.blank(url_res)), (route, args, {}))
url = route.build(Request.blank('/'), args, {})
self.assertEqual(url_res, url)
args = [str(i) for i in range(1000)]
random.shuffle(args)
args = tuple(args[:98])
url_res = '/' + '/'.join(args)
self.assertEqual(route.match(Request.blank(url_res)), (route, args, {}))
url = route.build(Request.blank('/'), args, {})
self.assertEqual(url_res, url)
def test_build_only_without_name(self):
self.assertRaises(ValueError, Route, r'/<foo>', None, build_only=True)
def test_route_repr(self):
self.assertEqual(Route(r'/<foo>', None).__repr__(),
"<Route('/<foo>', None, name=None, defaults={}, build_only=False)>")
self.assertEqual(Route(r'/<foo>', None, name='bar', defaults={'baz': 'ding'}, build_only=True).__repr__(),
"<Route('/<foo>', None, name='bar', defaults={'baz': 'ding'}, build_only=True)>")
self.assertEqual(str(Route(r'/<foo>', None)),
"<Route('/<foo>', None, name=None, defaults={}, build_only=False)>")
self.assertEqual(str(Route(r'/<foo>', None, name='bar', defaults={'baz': 'ding'}, build_only=True)),
"<Route('/<foo>', None, name='bar', defaults={'baz': 'ding'}, build_only=True)>")
def test_router_repr(self):
router = Router(None)
router.add(Route(r'/hello', None, name='hello', build_only=True))
router.add(Route(r'/world', None))
self.assertEqual(router.__repr__(), "<Router([<Route('/world', None, name=None, defaults={}, build_only=False)>, <Route('/hello', None, name='hello', defaults={}, build_only=True)>])>")
def test_base_route(self):
route = BaseRoute('foo', 'bar')
self.assertRaises(NotImplementedError, route.match, None)
def test_set_matcher(self):
req = Request.blank('/')
def custom_matcher(router, request):
self.assertEqual(request, req)
router = Router(None)
router.set_matcher(custom_matcher)
router.match(req)
def test_set_builder(self):
req = Request.blank('/')
def custom_builder(router, request, name, args, kwargs):
self.assertEqual(request, req)
return 'http://www.google.com'
router = Router(None)
router.set_builder(custom_builder)
res = router.build(req, '', (), {})
self.assertEqual(res, 'http://www.google.com')
def test_set_adapter(self):
def custom_adapter(router, handler):
class MyAdapter(webapp2.BaseHandlerAdapter):
def __call__(self, request, response):
response.write('hello my adapter')
return MyAdapter(handler)
def myhandler(request, *args, **kwargs):
return webapp2.Response('hello')
app = webapp2.WSGIApplication([('/', myhandler)])
app.router.set_adapter(custom_adapter)
rsp = app.get_response('/')
self.assertEqual(rsp.status_int, 200)
self.assertEqual(rsp.body, 'hello my adapter')
def test_methods(self):
route = Route(r'/', methods=['GET', 'POST'])
router = Router([route])
req = Request.blank('/')
req.method = 'GET'
self.assertTrue(router.match(req) is not None)
req.method = 'POST'
self.assertTrue(router.match(req) is not None)
req.method = 'PUT'
self.assertRaises(webapp2.exc.HTTPMethodNotAllowed, router.match, req)
def test_schemes(self):
route = Route(r'/', schemes=['http'])
req = Request.blank('http://mydomain.com/')
self.assertTrue(route.match(req) is not None)
req = Request.blank('https://mydomain.com/')
self.assertTrue(route.match(req) is None)
route = Route(r'/', schemes=['https'])
req = Request.blank('https://mydomain.com/')
self.assertTrue(route.match(req) is not None)
req = Request.blank('http://mydomain.com/')
self.assertTrue(route.match(req) is None)
class TestSimpleRoute(test_base.BaseTestCase):
def test_no_variable(self):
router = webapp2.Router([(r'/', 'my_handler')])
matched_route, args, kwargs = router.match(webapp2.Request.blank('/'))
self.assertEqual(args, ())
self.assertEqual(kwargs, {})
def test_simple_variables(self):
router = webapp2.Router([(r'/(\d{4})/(\d{2})', 'my_handler')])
matched_route, args, kwargs = router.match(webapp2.Request.blank('/2007/10'))
self.assertEqual(args, ('2007', '10'))
self.assertEqual(kwargs, {})
def test_build(self):
route = webapp2.SimpleRoute('/', None)
self.assertRaises(NotImplementedError, route.build, None, None, None)
def test_route_repr(self):
self.assertEqual(webapp2.SimpleRoute(r'/<foo>', None).__repr__(), "<SimpleRoute('/<foo>', None)>")
self.assertEqual(str(webapp2.SimpleRoute(r'/<foo>', None)), "<SimpleRoute('/<foo>', None)>")
if __name__ == '__main__':
test_base.main()