--- a/tests/test_urltree.py Mon Feb 16 20:56:05 2009 +0200
+++ b/tests/test_urltree.py Mon Feb 16 21:27:39 2009 +0200
@@ -157,6 +157,7 @@
def test_build_default (self) :
self.assertEqual(self.label_default_0.build_default({}), (True, "0"))
self.assertEqual(self.label_default_1.build_default({}), (True, "1"))
+ self.assertEqual(self.label_default_0.build_default(dict(test=0)), (True, "0"))
def test_build_nonedefault (self) :
self.assertEqual(self.label_default_1.build_default(dict(test=None)), (True, "1"))
@@ -165,7 +166,6 @@
self.assertEqual(self.label.build_default(dict(test=0)), (False, "0"))
self.assertEqual(self.label.build_default(dict(test=1)), (False, "1"))
self.assertEqual(self.label_default_0.build_default(dict(test=1)), (False, "1"))
- self.assertEqual(self.label_default_0.build_default(dict(test=0)), (False, "0"))
def test_str (self) :
self.assertEqual(str(self.label), "{test:int}")
@@ -293,7 +293,8 @@
# right qargs values
for key, value in qargs.iteritems() :
self.assertEquals(url.query_args[key], value)
-
+
+ # __init__
def test_label_path_empty (self) :
self._test_label_path("", urltree.EmptyLabel())
@@ -373,7 +374,8 @@
out_args = url.execute(req, values)
return out_args
-
+
+ # execute
def test_execute_empty (self) :
self.assertEquals(set(self._test_execute("/")), set())
@@ -424,4 +426,63 @@
def test_execute_qarg_override_ok (self) :
self.assertEqual(self._test_execute("/{foo=x1}", dict(foo=("x1", True)), dict(foo="x2")), dict(foo="x2"))
+
+ # build
+ class dummyrequest_page :
+ def __init__ (self, page_prefix) :
+ self.page_prefix = page_prefix
+
+ def _test_build (self, mask, url, **args) :
+ self.assertEquals(self.config(mask, None).build(self.dummyrequest_page("/index.cgi"), **args), "/index.cgi" + url)
+
+ def _test_build_fails (self, err, mask, **args) :
+ self.assertRaises(err, self.config(mask, None).build, self.dummyrequest_page("/index.cgi"), **args)
+ def test_build_empty (self) :
+ self._test_build("/", "/")
+
+ def test_build_static (self) :
+ self._test_build("/foo", "/foo")
+
+ def test_build_simple (self) :
+ self._test_build("/foo/{bar}", "/foo/x", bar="x")
+
+ def test_build_multi (self) :
+ self._test_build("/foo/{bar}/{quux}", "/foo/x/y", bar="x", quux="y")
+
+ def test_build_missing (self) :
+ self._test_build_fails(urltree.URLError, "/foo/{bar}/{quux}", bar="x")
+
+ def test_build_unknown (self) :
+ self._test_build_fails(urltree.URLError, "/foo/{bar}/{quux}", bar="x", quux="y", frob="???")
+
+ def test_build_long (self) :
+ self._test_build("/foo/{bar=a}/{quux=b}", "/foo/x/y", bar="x", quux="y")
+
+ def test_build_short (self) :
+ self._test_build("/foo/{bar=a}/{quux=b}", "/foo/x", bar="x", quux="b")
+
+ def test_build_with_none (self) :
+ self._test_build("/foo/{bar=a}/{quux=b}", "/foo/x", bar="x", quux=None)
+
+ def test_build_default (self) :
+ self._test_build("/foo/{bar=a}/{quux=b}", "/foo/x", bar="x")
+
+ def test_build_qargs (self) :
+ self._test_build("/foo/{bar}/?quux", "/foo/x?quux=a", bar="x", quux="a")
+
+ def test_build_qargs_default (self) :
+ self._test_build("/foo/{bar}/?quux", "/foo/x?quux=a", bar="x", quux="a")
+
+ # XXX: this just becomes ...?quux=['a', 'b'] like from str(list)
+# def test_build_qargs_multi_invalid (self) :
+# self.assertRaises(urltree.URLError, self.config("/foo/{bar}/?quux", None).build, self.dummyrequest_page("/index.cgi"), bar="x", quux=["a", "b"])
+
+ def test_build_qargs_multi_list (self) :
+ self._test_build("/foo/{bar}/?quux:list", "/foo/x?quux=a&quux=b", bar="x", quux=["a", "b"])
+
+ def test_build_qargs_none (self) :
+ self._test_build("/foo/{bar}/?quux", "/foo/x", bar="x", quux=None)
+
+
+
--- a/urltree.py Mon Feb 16 20:56:05 2009 +0200
+++ b/urltree.py Mon Feb 16 21:27:39 2009 +0200
@@ -238,6 +238,9 @@
else :
# lookup the value obj to use
value = values[self.key]
+
+ # default?
+ is_default = bool(value == self.default)
# convert value back to str
value = self.type.build(value)
@@ -363,7 +366,7 @@
def build (self, obj) :
return str(obj)
-
+
class URLIntegerType (URLType) :
"""
A URLType for simple integers
@@ -674,7 +677,7 @@
# trim default items off the end
for is_default, segment in segments[::-1] :
- if is_default :
+ if segment is None or is_default :
segments.pop(-1)
else :
@@ -683,12 +686,12 @@
assert segments
# join
- url = '/'.join(segment for is_default, segment in segments if segment is not None)
+ url = '/'.join(segment for is_default, segment in segments)
# build query args as { key -> [value] }
- query_args = dict((key, type.build_multi(values[key])) for key, (type, default) in self.query_args.iteritems() if key in values and values[key] is not None)
+ query_args = [(key, type.build_multi(values[key])) for key, (type, default) in self.query_args.iteritems() if key in values and values[key] is not None]
- return "%s%s" % (url, '?%s' % ('&'.join('%s=%s' % (key, value) for key, values in query_args.iteritems() for value in values)) if query_args else '')
+ return "%s%s" % (url, '?%s' % ('&'.join('%s=%s' % (key, value) for key, values in query_args for value in values)) if query_args else '')
def __str__ (self) :
return '/'.join(str(label) for label in self.label_path)