diff options
Diffstat (limited to 'tests/test_urldispatch.py')
| -rw-r--r-- | tests/test_urldispatch.py | 448 |
1 files changed, 281 insertions, 167 deletions
diff --git a/tests/test_urldispatch.py b/tests/test_urldispatch.py index 06f4ad793..e90fbfa0b 100644 --- a/tests/test_urldispatch.py +++ b/tests/test_urldispatch.py @@ -1,13 +1,12 @@ import unittest from pyramid import testing -from pyramid.compat import ( - text_, - PY2, - ) +from pyramid.compat import text_, PY2 + class TestRoute(unittest.TestCase): def _getTargetClass(self): from pyramid.urldispatch import Route + return Route def _makeOne(self, *arg): @@ -16,10 +15,12 @@ class TestRoute(unittest.TestCase): def test_provides_IRoute(self): from pyramid.interfaces import IRoute from zope.interface.verify import verifyObject + verifyObject(IRoute, self._makeOne('name', 'pattern')) def test_ctor(self): import types + route = self._makeOne('name', ':path', 'factory') self.assertEqual(route.pattern, ':path') self.assertEqual(route.path, ':path') @@ -30,6 +31,7 @@ class TestRoute(unittest.TestCase): def test_ctor_defaults(self): import types + route = self._makeOne('name', ':path') self.assertEqual(route.pattern, ':path') self.assertEqual(route.path, ':path') @@ -40,11 +42,12 @@ class TestRoute(unittest.TestCase): def test_match(self): route = self._makeOne('name', ':path') - self.assertEqual(route.match('/whatever'), {'path':'whatever'}) + self.assertEqual(route.match('/whatever'), {'path': 'whatever'}) def test_generate(self): route = self._makeOne('name', ':path') - self.assertEqual(route.generate({'path':'abc'}), '/abc') + self.assertEqual(route.generate({'path': 'abc'}), '/abc') + class RoutesMapperTests(unittest.TestCase): def setUp(self): @@ -52,11 +55,11 @@ class RoutesMapperTests(unittest.TestCase): def tearDown(self): testing.tearDown() - + def _getRequest(self, **kw): from pyramid.threadlocal import get_current_registry - environ = {'SERVER_NAME':'localhost', - 'wsgi.url_scheme':'http'} + + environ = {'SERVER_NAME': 'localhost', 'wsgi.url_scheme': 'http'} environ.update(kw) request = DummyRequest(environ) reg = get_current_registry() @@ -65,6 +68,7 @@ class RoutesMapperTests(unittest.TestCase): def _getTargetClass(self): from pyramid.urldispatch import RoutesMapper + return RoutesMapper def _makeOne(self): @@ -74,6 +78,7 @@ class RoutesMapperTests(unittest.TestCase): def test_provides_IRoutesMapper(self): from pyramid.interfaces import IRoutesMapper from zope.interface.verify import verifyObject + verifyObject(IRoutesMapper, self._makeOne()) def test_no_route_matches(self): @@ -89,36 +94,43 @@ class RoutesMapperTests(unittest.TestCase): mapper.connect('foo', 'archives/:action/:article2') self.assertEqual(len(mapper.routelist), 1) self.assertEqual(len(mapper.routes), 1) - self.assertEqual(mapper.routes['foo'].pattern, - 'archives/:action/:article2') - self.assertEqual(mapper.routelist[0].pattern, - 'archives/:action/:article2') + self.assertEqual( + mapper.routes['foo'].pattern, 'archives/:action/:article2' + ) + self.assertEqual( + mapper.routelist[0].pattern, 'archives/:action/:article2' + ) def test_connect_static(self): mapper = self._makeOne() mapper.connect('foo', 'archives/:action/:article', static=True) self.assertEqual(len(mapper.routelist), 0) self.assertEqual(len(mapper.routes), 1) - self.assertEqual(mapper.routes['foo'].pattern, - 'archives/:action/:article') + self.assertEqual( + mapper.routes['foo'].pattern, 'archives/:action/:article' + ) def test_connect_static_overridden(self): mapper = self._makeOne() mapper.connect('foo', 'archives/:action/:article', static=True) self.assertEqual(len(mapper.routelist), 0) self.assertEqual(len(mapper.routes), 1) - self.assertEqual(mapper.routes['foo'].pattern, - 'archives/:action/:article') + self.assertEqual( + mapper.routes['foo'].pattern, 'archives/:action/:article' + ) mapper.connect('foo', 'archives/:action/:article2') self.assertEqual(len(mapper.routelist), 1) self.assertEqual(len(mapper.routes), 1) - self.assertEqual(mapper.routes['foo'].pattern, - 'archives/:action/:article2') - self.assertEqual(mapper.routelist[0].pattern, - 'archives/:action/:article2') + self.assertEqual( + mapper.routes['foo'].pattern, 'archives/:action/:article2' + ) + self.assertEqual( + mapper.routelist[0].pattern, 'archives/:action/:article2' + ) def test___call__pathinfo_cant_be_decoded(self): from pyramid.exceptions import URLDecodeError + mapper = self._makeOne() if PY2: path_info = b'\xff\xfe\xe6\x00' @@ -138,8 +150,9 @@ class RoutesMapperTests(unittest.TestCase): def test___call__route_matches_with_predicates(self): mapper = self._makeOne() - mapper.connect('foo', 'archives/:action/:article', - predicates=[lambda *arg: True]) + mapper.connect( + 'foo', 'archives/:action/:article', predicates=[lambda *arg: True] + ) request = self._getRequest(PATH_INFO='/archives/action1/article1') result = mapper(request) self.assertEqual(result['route'], mapper.routes['foo']) @@ -148,8 +161,11 @@ class RoutesMapperTests(unittest.TestCase): def test___call__route_fails_to_match_with_predicates(self): mapper = self._makeOne() - mapper.connect('foo', 'archives/:action/article1', - predicates=[lambda *arg: True, lambda *arg: False]) + mapper.connect( + 'foo', + 'archives/:action/article1', + predicates=[lambda *arg: True, lambda *arg: False], + ) mapper.connect('bar', 'archives/:action/:article') request = self._getRequest(PATH_INFO='/archives/action1/article1') result = mapper(request) @@ -159,10 +175,12 @@ class RoutesMapperTests(unittest.TestCase): def test___call__custom_predicate_gets_info(self): mapper = self._makeOne() + def pred(info, request): - self.assertEqual(info['match'], {'action':'action1'}) + self.assertEqual(info['match'], {'action': 'action1'}) self.assertEqual(info['route'], mapper.routes['foo']) return True + mapper.connect('foo', 'archives/:action/article1', predicates=[pred]) request = self._getRequest(PATH_INFO='/archives/action1/article1') mapper(request) @@ -172,8 +190,9 @@ class RoutesMapperTests(unittest.TestCase): # http://labs.creativecommons.org/2010/01/13/cc-engine-and-web-non-frameworks/ mapper = self._makeOne() mapper.connect('rdf', 'licenses/:license_code/:license_version/rdf') - mapper.connect('juri', - 'licenses/:license_code/:license_version/:jurisdiction') + mapper.connect( + 'juri', 'licenses/:license_code/:license_version/:jurisdiction' + ) request = self._getRequest(PATH_INFO='/licenses/1/v2/rdf') result = mapper(request) @@ -236,6 +255,7 @@ class RoutesMapperTests(unittest.TestCase): def test_get_routes(self): from pyramid.urldispatch import Route + mapper = self._makeOne() self.assertEqual(mapper.get_routes(), []) mapper.connect('whatever', 'archives/:action/:article') @@ -256,131 +276,167 @@ class RoutesMapperTests(unittest.TestCase): def test_generate(self): mapper = self._makeOne() + def generator(kw): return 123 + route = DummyRoute(generator) - mapper.routes['abc'] = route + mapper.routes['abc'] = route self.assertEqual(mapper.generate('abc', {}), 123) + class TestCompileRoute(unittest.TestCase): def _callFUT(self, pattern): from pyramid.urldispatch import _compile_route + return _compile_route(pattern) def test_no_star(self): matcher, generator = self._callFUT('/foo/:baz/biz/:buz/bar') - self.assertEqual(matcher('/foo/baz/biz/buz/bar'), - {'baz':'baz', 'buz':'buz'}) + self.assertEqual( + matcher('/foo/baz/biz/buz/bar'), {'baz': 'baz', 'buz': 'buz'} + ) self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) - self.assertEqual(generator({'baz':1, 'buz':2}), '/foo/1/biz/2/bar') + self.assertEqual(generator({'baz': 1, 'buz': 2}), '/foo/1/biz/2/bar') def test_with_star(self): matcher, generator = self._callFUT('/foo/:baz/biz/:buz/bar*traverse') - self.assertEqual(matcher('/foo/baz/biz/buz/bar'), - {'baz':'baz', 'buz':'buz', 'traverse':()}) - self.assertEqual(matcher('/foo/baz/biz/buz/bar/everything/else/here'), - {'baz':'baz', 'buz':'buz', - 'traverse':('everything', 'else', 'here')}) + self.assertEqual( + matcher('/foo/baz/biz/buz/bar'), + {'baz': 'baz', 'buz': 'buz', 'traverse': ()}, + ) + self.assertEqual( + matcher('/foo/baz/biz/buz/bar/everything/else/here'), + { + 'baz': 'baz', + 'buz': 'buz', + 'traverse': ('everything', 'else', 'here'), + }, + ) self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) - self.assertEqual(generator( - {'baz':1, 'buz':2, 'traverse':'/a/b'}), '/foo/1/biz/2/bar/a/b') - + self.assertEqual( + generator({'baz': 1, 'buz': 2, 'traverse': '/a/b'}), + '/foo/1/biz/2/bar/a/b', + ) + def test_with_bracket_star(self): matcher, generator = self._callFUT( - '/foo/{baz}/biz/{buz}/bar{remainder:.*}') - self.assertEqual(matcher('/foo/baz/biz/buz/bar'), - {'baz':'baz', 'buz':'buz', 'remainder':''}) - self.assertEqual(matcher('/foo/baz/biz/buz/bar/everything/else/here'), - {'baz':'baz', 'buz':'buz', - 'remainder':'/everything/else/here'}) + '/foo/{baz}/biz/{buz}/bar{remainder:.*}' + ) + self.assertEqual( + matcher('/foo/baz/biz/buz/bar'), + {'baz': 'baz', 'buz': 'buz', 'remainder': ''}, + ) + self.assertEqual( + matcher('/foo/baz/biz/buz/bar/everything/else/here'), + {'baz': 'baz', 'buz': 'buz', 'remainder': '/everything/else/here'}, + ) self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) - self.assertEqual(generator( - {'baz':1, 'buz':2, 'remainder':'/a/b'}), '/foo/1/biz/2/bar/a/b') + self.assertEqual( + generator({'baz': 1, 'buz': 2, 'remainder': '/a/b'}), + '/foo/1/biz/2/bar/a/b', + ) def test_no_beginning_slash(self): matcher, generator = self._callFUT('foo/:baz/biz/:buz/bar') - self.assertEqual(matcher('/foo/baz/biz/buz/bar'), - {'baz':'baz', 'buz':'buz'}) + self.assertEqual( + matcher('/foo/baz/biz/buz/bar'), {'baz': 'baz', 'buz': 'buz'} + ) self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) - self.assertEqual(generator({'baz':1, 'buz':2}), '/foo/1/biz/2/bar') + self.assertEqual(generator({'baz': 1, 'buz': 2}), '/foo/1/biz/2/bar') def test_custom_regex(self): matcher, generator = self._callFUT('foo/{baz}/biz/{buz:[^/\.]+}.{bar}') - self.assertEqual(matcher('/foo/baz/biz/buz.bar'), - {'baz':'baz', 'buz':'buz', 'bar':'bar'}) + self.assertEqual( + matcher('/foo/baz/biz/buz.bar'), + {'baz': 'baz', 'buz': 'buz', 'bar': 'bar'}, + ) self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) - self.assertEqual(generator({'baz':1, 'buz':2, 'bar': 'html'}), - '/foo/1/biz/2.html') - + self.assertEqual( + generator({'baz': 1, 'buz': 2, 'bar': 'html'}), '/foo/1/biz/2.html' + ) + def test_custom_regex_with_colons(self): - matcher, generator = self._callFUT('foo/{baz}/biz/{buz:(?:[^/\.]+)}.{bar}') - self.assertEqual(matcher('/foo/baz/biz/buz.bar'), - {'baz':'baz', 'buz':'buz', 'bar':'bar'}) + matcher, generator = self._callFUT( + 'foo/{baz}/biz/{buz:(?:[^/\.]+)}.{bar}' + ) + self.assertEqual( + matcher('/foo/baz/biz/buz.bar'), + {'baz': 'baz', 'buz': 'buz', 'bar': 'bar'}, + ) self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) - self.assertEqual(generator({'baz':1, 'buz':2, 'bar': 'html'}), - '/foo/1/biz/2.html') + self.assertEqual( + generator({'baz': 1, 'buz': 2, 'bar': 'html'}), '/foo/1/biz/2.html' + ) def test_mixed_newstyle_oldstyle_pattern_defaults_to_newstyle(self): # pattern: '\\/foo\\/(?P<baz>abc)\\/biz\\/(?P<buz>[^/]+)\\/bar$' # note presence of :abc in pattern (oldstyle match) matcher, generator = self._callFUT('foo/{baz:abc}/biz/{buz}/bar') - self.assertEqual(matcher('/foo/abc/biz/buz/bar'), - {'baz':'abc', 'buz':'buz'}) - self.assertEqual(generator({'baz':1, 'buz':2}), '/foo/1/biz/2/bar') + self.assertEqual( + matcher('/foo/abc/biz/buz/bar'), {'baz': 'abc', 'buz': 'buz'} + ) + self.assertEqual(generator({'baz': 1, 'buz': 2}), '/foo/1/biz/2/bar') def test_custom_regex_with_embedded_squigglies(self): matcher, generator = self._callFUT('/{buz:\d{4}}') - self.assertEqual(matcher('/2001'), {'buz':'2001'}) + self.assertEqual(matcher('/2001'), {'buz': '2001'}) self.assertEqual(matcher('/200'), None) - self.assertEqual(generator({'buz':2001}), '/2001') + self.assertEqual(generator({'buz': 2001}), '/2001') def test_custom_regex_with_embedded_squigglies2(self): matcher, generator = self._callFUT('/{buz:\d{3,4}}') - self.assertEqual(matcher('/2001'), {'buz':'2001'}) - self.assertEqual(matcher('/200'), {'buz':'200'}) + self.assertEqual(matcher('/2001'), {'buz': '2001'}) + self.assertEqual(matcher('/200'), {'buz': '200'}) self.assertEqual(matcher('/20'), None) - self.assertEqual(generator({'buz':2001}), '/2001') + self.assertEqual(generator({'buz': 2001}), '/2001') def test_custom_regex_with_embedded_squigglies3(self): matcher, generator = self._callFUT( - '/{buz:(\d{2}|\d{4})-[a-zA-Z]{3,4}-\d{2}}') - self.assertEqual(matcher('/2001-Nov-15'), {'buz':'2001-Nov-15'}) - self.assertEqual(matcher('/99-June-10'), {'buz':'99-June-10'}) + '/{buz:(\d{2}|\d{4})-[a-zA-Z]{3,4}-\d{2}}' + ) + self.assertEqual(matcher('/2001-Nov-15'), {'buz': '2001-Nov-15'}) + self.assertEqual(matcher('/99-June-10'), {'buz': '99-June-10'}) self.assertEqual(matcher('/2-Nov-15'), None) self.assertEqual(matcher('/200-Nov-15'), None) self.assertEqual(matcher('/2001-No-15'), None) - self.assertEqual(generator({'buz':'2001-Nov-15'}), '/2001-Nov-15') - self.assertEqual(generator({'buz':'99-June-10'}), '/99-June-10') + self.assertEqual(generator({'buz': '2001-Nov-15'}), '/2001-Nov-15') + self.assertEqual(generator({'buz': '99-June-10'}), '/99-June-10') def test_pattern_with_high_order_literal(self): pattern = text_(b'/La Pe\xc3\xb1a/{x}', 'utf-8') matcher, generator = self._callFUT(pattern) - self.assertEqual(matcher(text_(b'/La Pe\xc3\xb1a/x', 'utf-8')), - {'x':'x'}) - self.assertEqual(generator({'x':'1'}), '/La%20Pe%C3%B1a/1') + self.assertEqual( + matcher(text_(b'/La Pe\xc3\xb1a/x', 'utf-8')), {'x': 'x'} + ) + self.assertEqual(generator({'x': '1'}), '/La%20Pe%C3%B1a/1') def test_pattern_generate_with_high_order_dynamic(self): pattern = '/{x}' _, generator = self._callFUT(pattern) self.assertEqual( - generator({'x':text_(b'La Pe\xc3\xb1a', 'utf-8')}), - '/La%20Pe%C3%B1a') + generator({'x': text_(b'La Pe\xc3\xb1a', 'utf-8')}), + '/La%20Pe%C3%B1a', + ) def test_docs_sample_generate(self): # sample from urldispatch.rst pattern = text_(b'/La Pe\xc3\xb1a/{city}', 'utf-8') _, generator = self._callFUT(pattern) self.assertEqual( - generator({'city':text_(b'Qu\xc3\xa9bec', 'utf-8')}), - '/La%20Pe%C3%B1a/Qu%C3%A9bec') + generator({'city': text_(b'Qu\xc3\xa9bec', 'utf-8')}), + '/La%20Pe%C3%B1a/Qu%C3%A9bec', + ) def test_generate_with_mixedtype_values(self): pattern = '/{city}/{state}' _, generator = self._callFUT(pattern) result = generator( - {'city': text_(b'Qu\xc3\xa9bec', 'utf-8'), - 'state': b'La Pe\xc3\xb1a'} - ) + { + 'city': text_(b'Qu\xc3\xa9bec', 'utf-8'), + 'state': b'La Pe\xc3\xb1a', + } + ) self.assertEqual(result, '/Qu%C3%A9bec/La%20Pe%C3%B1a') # should be a native string self.assertEqual(type(result), str) @@ -394,7 +450,7 @@ class TestCompileRoute(unittest.TestCase): _, generator = self._callFUT(pattern) result = generator( {'remainder': text_(b'/Qu\xc3\xa9bec/La Pe\xc3\xb1a', 'utf-8')} - ) + ) self.assertEqual(result, '/abc/Qu%C3%A9bec/La%20Pe%C3%B1a') # should be a native string self.assertEqual(type(result), str) @@ -402,22 +458,23 @@ class TestCompileRoute(unittest.TestCase): def test_generate_with_string_remainder_and_nonstring_replacement(self): pattern = text_(b'/abc/*remainder', 'utf-8') _, generator = self._callFUT(pattern) - result = generator( - {'remainder': None} - ) + result = generator({'remainder': None}) self.assertEqual(result, '/abc/None') # should be a native string self.assertEqual(type(result), str) + class TestCompileRouteFunctional(unittest.TestCase): def matches(self, pattern, path, expected): from pyramid.urldispatch import _compile_route + matcher = _compile_route(pattern)[0] result = matcher(path) self.assertEqual(result, expected) def generates(self, pattern, dict, result): from pyramid.urldispatch import _compile_route + self.assertEqual(_compile_route(pattern)[1](dict), result) def test_matcher_functional_notdynamic(self): @@ -432,108 +489,165 @@ class TestCompileRouteFunctional(unittest.TestCase): self.matches('/{x}', '', None) self.matches('/{x}', '/', None) self.matches('/abc/{def}', '/abc/', None) - self.matches('/{x}', '/a', {'x':'a'}) - self.matches('zzz/{x}', '/zzz/abc', {'x':'abc'}) - self.matches('zzz/{x}*traverse', '/zzz/abc', {'x':'abc', 'traverse':()}) - self.matches('zzz/{x}*traverse', '/zzz/abc/def/g', - {'x':'abc', 'traverse':('def', 'g')}) - self.matches('*traverse', '/zzz/abc', {'traverse':('zzz', 'abc')}) - self.matches('*traverse', '/zzz/ abc', {'traverse':('zzz', ' abc')}) + self.matches('/{x}', '/a', {'x': 'a'}) + self.matches('zzz/{x}', '/zzz/abc', {'x': 'abc'}) + self.matches( + 'zzz/{x}*traverse', '/zzz/abc', {'x': 'abc', 'traverse': ()} + ) + self.matches( + 'zzz/{x}*traverse', + '/zzz/abc/def/g', + {'x': 'abc', 'traverse': ('def', 'g')}, + ) + self.matches('*traverse', '/zzz/abc', {'traverse': ('zzz', 'abc')}) + self.matches('*traverse', '/zzz/ abc', {'traverse': ('zzz', ' abc')}) #'/La%20Pe%C3%B1a' - self.matches('{x}', text_(b'/La Pe\xc3\xb1a', 'utf-8'), - {'x':text_(b'La Pe\xc3\xb1a', 'utf-8')}) + self.matches( + '{x}', + text_(b'/La Pe\xc3\xb1a', 'utf-8'), + {'x': text_(b'La Pe\xc3\xb1a', 'utf-8')}, + ) # '/La%20Pe%C3%B1a/x' - self.matches('*traverse', text_(b'/La Pe\xc3\xb1a/x'), - {'traverse':(text_(b'La Pe\xc3\xb1a'), 'x')}) - self.matches('/foo/{id}.html', '/foo/bar.html', {'id':'bar'}) - self.matches('/{num:[0-9]+}/*traverse', '/555/abc/def', - {'num':'555', 'traverse':('abc', 'def')}) - self.matches('/{num:[0-9]*}/*traverse', '/555/abc/def', - {'num':'555', 'traverse':('abc', 'def')}) - self.matches('zzz/{_}', '/zzz/abc', {'_':'abc'}) - self.matches('zzz/{_abc}', '/zzz/abc', {'_abc':'abc'}) - self.matches('zzz/{abc_def}', '/zzz/abc', {'abc_def':'abc'}) + self.matches( + '*traverse', + text_(b'/La Pe\xc3\xb1a/x'), + {'traverse': (text_(b'La Pe\xc3\xb1a'), 'x')}, + ) + self.matches('/foo/{id}.html', '/foo/bar.html', {'id': 'bar'}) + self.matches( + '/{num:[0-9]+}/*traverse', + '/555/abc/def', + {'num': '555', 'traverse': ('abc', 'def')}, + ) + self.matches( + '/{num:[0-9]*}/*traverse', + '/555/abc/def', + {'num': '555', 'traverse': ('abc', 'def')}, + ) + self.matches('zzz/{_}', '/zzz/abc', {'_': 'abc'}) + self.matches('zzz/{_abc}', '/zzz/abc', {'_abc': 'abc'}) + self.matches('zzz/{abc_def}', '/zzz/abc', {'abc_def': 'abc'}) def test_matcher_functional_oldstyle(self): self.matches('/:x', '', None) self.matches('/:x', '/', None) self.matches('/abc/:def', '/abc/', None) - self.matches('/:x', '/a', {'x':'a'}) - self.matches('zzz/:x', '/zzz/abc', {'x':'abc'}) - self.matches('zzz/:x*traverse', '/zzz/abc', {'x':'abc', 'traverse':()}) - self.matches('zzz/:x*traverse', '/zzz/abc/def/g', - {'x':'abc', 'traverse':('def', 'g')}) - self.matches('*traverse', '/zzz/abc', {'traverse':('zzz', 'abc')}) - self.matches('*traverse', '/zzz/ abc', {'traverse':('zzz', ' abc')}) + self.matches('/:x', '/a', {'x': 'a'}) + self.matches('zzz/:x', '/zzz/abc', {'x': 'abc'}) + self.matches( + 'zzz/:x*traverse', '/zzz/abc', {'x': 'abc', 'traverse': ()} + ) + self.matches( + 'zzz/:x*traverse', + '/zzz/abc/def/g', + {'x': 'abc', 'traverse': ('def', 'g')}, + ) + self.matches('*traverse', '/zzz/abc', {'traverse': ('zzz', 'abc')}) + self.matches('*traverse', '/zzz/ abc', {'traverse': ('zzz', ' abc')}) #'/La%20Pe%C3%B1a' # pattern, path, expected - self.matches(':x', text_(b'/La Pe\xc3\xb1a', 'utf-8'), - {'x':text_(b'La Pe\xc3\xb1a', 'utf-8')}) + self.matches( + ':x', + text_(b'/La Pe\xc3\xb1a', 'utf-8'), + {'x': text_(b'La Pe\xc3\xb1a', 'utf-8')}, + ) # '/La%20Pe%C3%B1a/x' - self.matches('*traverse', text_(b'/La Pe\xc3\xb1a/x', 'utf-8'), - {'traverse':(text_(b'La Pe\xc3\xb1a', 'utf-8'), 'x')}) - self.matches('/foo/:id.html', '/foo/bar.html', {'id':'bar'}) - self.matches('/foo/:id_html', '/foo/bar_html', {'id_html':'bar_html'}) - self.matches('zzz/:_', '/zzz/abc', {'_':'abc'}) - self.matches('zzz/:_abc', '/zzz/abc', {'_abc':'abc'}) - self.matches('zzz/:abc_def', '/zzz/abc', {'abc_def':'abc'}) + self.matches( + '*traverse', + text_(b'/La Pe\xc3\xb1a/x', 'utf-8'), + {'traverse': (text_(b'La Pe\xc3\xb1a', 'utf-8'), 'x')}, + ) + self.matches('/foo/:id.html', '/foo/bar.html', {'id': 'bar'}) + self.matches('/foo/:id_html', '/foo/bar_html', {'id_html': 'bar_html'}) + self.matches('zzz/:_', '/zzz/abc', {'_': 'abc'}) + self.matches('zzz/:_abc', '/zzz/abc', {'_abc': 'abc'}) + self.matches('zzz/:abc_def', '/zzz/abc', {'abc_def': 'abc'}) def test_generator_functional_notdynamic(self): self.generates('', {}, '/') self.generates('/', {}, '/') def test_generator_functional_newstyle(self): - self.generates('/{x}', {'x':''}, '/') - self.generates('/{x}', {'x':'a'}, '/a') - self.generates('/{x}', {'x':'a/b/c'}, '/a/b/c') - self.generates('/{x}', {'x':':@&+$,'}, '/:@&+$,') - self.generates('zzz/{x}', {'x':'abc'}, '/zzz/abc') - self.generates('zzz/{x}*traverse', {'x':'abc', 'traverse':''}, - '/zzz/abc') - self.generates('zzz/{x}*traverse', {'x':'abc', 'traverse':'/def/g'}, - '/zzz/abc/def/g') - self.generates('zzz/{x}*traverse', {'x':':@&+$,', 'traverse':'/:@&+$,'}, - '/zzz/:@&+$,/:@&+$,') - self.generates('/{x}', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8')}, - '//La%20Pe%C3%B1a') - self.generates('/{x}*y', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8'), - 'y':'/rest/of/path'}, - '//La%20Pe%C3%B1a/rest/of/path') - self.generates('*traverse', {'traverse':('a', text_(b'La Pe\xf1a'))}, - '/a/La%20Pe%C3%B1a') - self.generates('/foo/{id}.html', {'id':'bar'}, '/foo/bar.html') - self.generates('/foo/{_}', {'_':'20'}, '/foo/20') - self.generates('/foo/{_abc}', {'_abc':'20'}, '/foo/20') - self.generates('/foo/{abc_def}', {'abc_def':'20'}, '/foo/20') - + self.generates('/{x}', {'x': ''}, '/') + self.generates('/{x}', {'x': 'a'}, '/a') + self.generates('/{x}', {'x': 'a/b/c'}, '/a/b/c') + self.generates('/{x}', {'x': ':@&+$,'}, '/:@&+$,') + self.generates('zzz/{x}', {'x': 'abc'}, '/zzz/abc') + self.generates( + 'zzz/{x}*traverse', {'x': 'abc', 'traverse': ''}, '/zzz/abc' + ) + self.generates( + 'zzz/{x}*traverse', + {'x': 'abc', 'traverse': '/def/g'}, + '/zzz/abc/def/g', + ) + self.generates( + 'zzz/{x}*traverse', + {'x': ':@&+$,', 'traverse': '/:@&+$,'}, + '/zzz/:@&+$,/:@&+$,', + ) + self.generates( + '/{x}', + {'x': text_(b'/La Pe\xc3\xb1a', 'utf-8')}, + '//La%20Pe%C3%B1a', + ) + self.generates( + '/{x}*y', + {'x': text_(b'/La Pe\xc3\xb1a', 'utf-8'), 'y': '/rest/of/path'}, + '//La%20Pe%C3%B1a/rest/of/path', + ) + self.generates( + '*traverse', + {'traverse': ('a', text_(b'La Pe\xf1a'))}, + '/a/La%20Pe%C3%B1a', + ) + self.generates('/foo/{id}.html', {'id': 'bar'}, '/foo/bar.html') + self.generates('/foo/{_}', {'_': '20'}, '/foo/20') + self.generates('/foo/{_abc}', {'_abc': '20'}, '/foo/20') + self.generates('/foo/{abc_def}', {'abc_def': '20'}, '/foo/20') + def test_generator_functional_oldstyle(self): - self.generates('/:x', {'x':''}, '/') - self.generates('/:x', {'x':'a'}, '/a') - self.generates('zzz/:x', {'x':'abc'}, '/zzz/abc') - self.generates('zzz/:x*traverse', {'x':'abc', 'traverse':''}, - '/zzz/abc') - self.generates('zzz/:x*traverse', {'x':'abc', 'traverse':'/def/g'}, - '/zzz/abc/def/g') - self.generates('/:x', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8')}, - '//La%20Pe%C3%B1a') - self.generates('/:x*y', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8'), - 'y':'/rest/of/path'}, - '//La%20Pe%C3%B1a/rest/of/path') - self.generates('*traverse', {'traverse':('a', text_(b'La Pe\xf1a'))}, - '/a/La%20Pe%C3%B1a') - self.generates('/foo/:id.html', {'id':'bar'}, '/foo/bar.html') - self.generates('/foo/:_', {'_':'20'}, '/foo/20') - self.generates('/foo/:_abc', {'_abc':'20'}, '/foo/20') - self.generates('/foo/:abc_def', {'abc_def':'20'}, '/foo/20') + self.generates('/:x', {'x': ''}, '/') + self.generates('/:x', {'x': 'a'}, '/a') + self.generates('zzz/:x', {'x': 'abc'}, '/zzz/abc') + self.generates( + 'zzz/:x*traverse', {'x': 'abc', 'traverse': ''}, '/zzz/abc' + ) + self.generates( + 'zzz/:x*traverse', + {'x': 'abc', 'traverse': '/def/g'}, + '/zzz/abc/def/g', + ) + self.generates( + '/:x', + {'x': text_(b'/La Pe\xc3\xb1a', 'utf-8')}, + '//La%20Pe%C3%B1a', + ) + self.generates( + '/:x*y', + {'x': text_(b'/La Pe\xc3\xb1a', 'utf-8'), 'y': '/rest/of/path'}, + '//La%20Pe%C3%B1a/rest/of/path', + ) + self.generates( + '*traverse', + {'traverse': ('a', text_(b'La Pe\xf1a'))}, + '/a/La%20Pe%C3%B1a', + ) + self.generates('/foo/:id.html', {'id': 'bar'}, '/foo/bar.html') + self.generates('/foo/:_', {'_': '20'}, '/foo/20') + self.generates('/foo/:_abc', {'_abc': '20'}, '/foo/20') + self.generates('/foo/:abc_def', {'abc_def': '20'}, '/foo/20') + class DummyContext(object): """ """ - + + class DummyRequest(object): def __init__(self, environ): self.environ = environ - + + class DummyRoute(object): def __init__(self, generator): self.generate = generator - |
