summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-06-25 02:55:38 +0000
committerChris McDonough <chrism@agendaless.com>2009-06-25 02:55:38 +0000
commit17358dde36850af57571e6d8930a35d8494b53d1 (patch)
tree9410015d05848fa56030dbbe6e8a2dc3f82a695d
parent03b756271de674932845e4b07fab050e60d8df34 (diff)
downloadpyramid-17358dde36850af57571e6d8930a35d8494b53d1.tar.gz
pyramid-17358dde36850af57571e6d8930a35d8494b53d1.tar.bz2
pyramid-17358dde36850af57571e6d8930a35d8494b53d1.zip
- Make ``route_url`` URL-quote segment replacements during generation.
Remainder segments are not quoted.
-rw-r--r--CHANGES.txt6
-rw-r--r--repoze/bfg/tests/test_urldispatch.py41
-rw-r--r--repoze/bfg/urldispatch.py7
3 files changed, 54 insertions, 0 deletions
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