From 17358dde36850af57571e6d8930a35d8494b53d1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 25 Jun 2009 02:55:38 +0000 Subject: - Make ``route_url`` URL-quote segment replacements during generation. Remainder segments are not quoted. --- CHANGES.txt | 6 ++++++ repoze/bfg/tests/test_urldispatch.py | 41 ++++++++++++++++++++++++++++++++++++ repoze/bfg/urldispatch.py | 7 ++++++ 3 files changed, 54 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 0de550b58..45ba8752c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -7,6 +7,12 @@ Documentation - Add information to the URL Dispatch narrative documentation about path pattern matching syntax. +Bug Fixes +--------- + +- Make ``route_url`` URL-quote segment replacements during generation. + Remainder segments are not quoted. + 1.0a3 (2009-06-24) ================== diff --git a/repoze/bfg/tests/test_urldispatch.py b/repoze/bfg/tests/test_urldispatch.py index cdb99b7f4..014401008 100644 --- a/repoze/bfg/tests/test_urldispatch.py +++ b/repoze/bfg/tests/test_urldispatch.py @@ -147,6 +147,47 @@ class TestCompileRoute(unittest.TestCase): self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) self.assertEqual(generator({'baz':1, 'buz':2}), '/foo/1/biz/2/bar') +class TestCompileRouteMatchFunctional(unittest.TestCase): + def matches(self, pattern, path, result): + from repoze.bfg.urldispatch import _compile_route + self.assertEqual(_compile_route(pattern)[0](path), result) + + def generates(self, pattern, dict, result): + from repoze.bfg.urldispatch import _compile_route + self.assertEqual(_compile_route(pattern)[1](dict), result) + + def test_matcher_functional(self): + self.matches('/', '', None) + self.matches('', '', None) + self.matches('/', '/foo', None) + self.matches('/foo/', '/foo', None) + self.matches('/:x', '', None) + self.matches('', '/', {}) + self.matches('/', '/', {}) + self.matches('/:x', '/', {'x':''}) + 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'}) + + def test_generator_functional(self): + self.generates('', {}, '/') + self.generates('/', {}, '/') + 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':unicode('/La Pe\xc3\xb1a', 'utf-8')}, + '/%2FLa%20Pe%C3%B1a') + self.generates('/:x*y', {'x':unicode('/La Pe\xc3\xb1a', 'utf-8'), + 'y':'/rest/of/path'}, + '/%2FLa%20Pe%C3%B1a/rest/of/path') + + class DummyRootFactory(object): def __init__(self, result): diff --git a/repoze/bfg/urldispatch.py b/repoze/bfg/urldispatch.py index 497d3980e..885f0eb98 100644 --- a/repoze/bfg/urldispatch.py +++ b/repoze/bfg/urldispatch.py @@ -1,5 +1,7 @@ import re +from repoze.bfg.traversal import _url_quote + _marker = object() class Route(object): @@ -96,6 +98,11 @@ def _compile_route(route): for k, v in dict.items(): if isinstance(v, unicode): v = v.encode('utf-8') + if (k!=star): + try: + v = _url_quote(v) + except TypeError: + pass newdict[k] = v return gen % newdict -- cgit v1.2.3