summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Alexander <steve@z3u.com>2002-06-25 12:38:12 +0000
committerSteve Alexander <steve@z3u.com>2002-06-25 12:38:12 +0000
commitdc9c587bfee2359d89fcf29022170f2d361ec6db (patch)
treeb33db924ea6053754ebe0f294bd1a08bf06d0008
parent2677b463c305af08e2e37c7d521612edc4b25691 (diff)
downloadzope-traversing-dc9c587bfee2359d89fcf29022170f2d361ec6db.tar.gz
Added convenience functions to Zope.App.Traversing to get a canonical
location from a tuple of strings or a string. A canonical location is a slash-delimited unicode string, or a tuple of unicode strings. Location strings must not end in a slash (except the root), nor contain more than one consecutive slashes, nor be of zero length. Location tuples must not end with an empty string (except the root), nor contain more than one consecutive empty string, nor be of zero length. The root location is given as u'/' or (u'',)
-rw-r--r--__init__.py48
-rw-r--r--tests/testConvenienceFunctions.py57
2 files changed, 104 insertions, 1 deletions
diff --git a/__init__.py b/__init__.py
index 546d6c3..eb01c62 100644
--- a/__init__.py
+++ b/__init__.py
@@ -21,6 +21,7 @@ from ITraverser import ITraverser as _ITraverser
from Traverser import WrapperChain as _WrapperChain
from Zope.Proxy.ContextWrapper import getWrapperContext as _getWrapperContext
from Zope.Proxy.ContextWrapper import isWrapper as _isWrapper
+from types import StringTypes
_marker = object()
# XXX: this probably shouldn't have "request" in its signature, nor
@@ -111,3 +112,50 @@ def getPhysicalRoot(obj):
return _getAdapter(obj, _ITraverser).getPhysicalRoot()
+def locationAsTuple(location):
+ """Given a location as a unicode or ascii string or as a tuple of
+ unicode or ascii strings, returns the location as a tuple of
+ unicode strings.
+
+ Raises a ValueError if a poorly formed location is given.
+ """
+ if not location:
+ raise ValueError, "location must be non-empty."
+ if isinstance(location, tuple):
+ t = tuple(map(unicode, location))
+ elif isinstance(location, StringTypes):
+ if location == u'/': # matches '/' or u'/'
+ return (u'',)
+ t = tuple(location.split(u'/'))
+ else:
+ raise ValueError, \
+ "location %s must be a string or a tuple of strings." % (location,)
+
+ if t[-1] == u'': # matches '' or u''
+ raise ValueError, \
+ "location tuple %s must not end with empty string." % (t,)
+ # don't usually need this, so just an assertion rather than a value error
+ assert '' not in t[1:]
+ return t
+
+def locationAsUnicode(location):
+ """Given a location as a unicode or ascii string or as a tuple of
+ unicode or ascii strings, returns the location as a slash-separated
+ unicode string.
+
+ Raises ValueError if a poorly formed location is given.
+ """
+ if not location:
+ raise ValueError, "location must be non-empty."
+ if isinstance(location, tuple):
+ u = u'/'.join(location)
+ elif isinstance(location, StringTypes):
+ u = unicode(location)
+ else:
+ raise ValueError, \
+ "location %s must be a string or a tuple of strings." % (location,)
+ if u != '/' and u[-1] == u'/':
+ raise ValueError, "location %s must not end with a slash." % u
+ # don't usually need this, so just an assertion rather than a value error
+ assert u.find(u'//') == -1
+ return u
diff --git a/tests/testConvenienceFunctions.py b/tests/testConvenienceFunctions.py
index 4bf2021..477396c 100644
--- a/tests/testConvenienceFunctions.py
+++ b/tests/testConvenienceFunctions.py
@@ -13,7 +13,7 @@
##############################################################################
"""
-$Id: testConvenienceFunctions.py,v 1.2 2002/06/18 22:14:16 stevea Exp $
+$Id: testConvenienceFunctions.py,v 1.3 2002/06/25 12:38:12 stevea Exp $
"""
from unittest import TestCase, TestSuite, main, makeSuite
from Zope.App.OFS.Services.ServiceManager.tests.PlacefulSetup \
@@ -185,6 +185,61 @@ class Test(PlacefulSetup, TestCase):
self.unwrapped_item
)
+ def testLocationAsTuple(self):
+ # TODO: put these assertions in a less random order
+ from Zope.App.Traversing import locationAsTuple as lat
+ loc = (u'xx',u'yy',u'zz')
+ self.assertEqual(lat((u'xx',u'yy',u'zz')), loc)
+ self.assertEqual(lat((u'', u'xx',u'yy',u'zz')), (u'',)+loc)
+ self.assertEqual(lat(('xx','yy','zz')), loc)
+ self.assertRaises(ValueError, lat, ())
+ self.assertEqual(lat(('xx',)), (u'xx',))
+ self.assertRaises(ValueError, lat, 23)
+ self.assertRaises(UnicodeError, lat, ('', u'123', '£23'))
+ self.assertRaises(UnicodeError, lat, '£23')
+ self.assertEqual(lat(u'xx/yy/zz'), loc)
+ self.assertEqual(lat(u'/xx/yy/zz'), (u'',)+loc)
+ self.assertEqual(lat('xx/yy/zz'), loc)
+ self.assertRaises(ValueError, lat, '')
+ self.assertEqual(lat('/'), (u'',))
+ self.assertEqual(lat('xx'), (u'xx',))
+ self.assertRaises(ValueError, lat, '//')
+ self.assertRaises(AssertionError, lat, '/foo//bar')
+ # having a trailing slash on a location is undefined.
+ # we might want to give it a particular meaning for zope3 later
+ # for now, it is an invalid location identifier
+ self.assertRaises(ValueError, lat, '/foo/bar/')
+ self.assertRaises(ValueError, lat, 'foo/bar/')
+ self.assertRaises(ValueError, lat, ('','foo','bar',''))
+ self.assertRaises(ValueError, lat, ('foo','bar',''))
+
+ def testLocationAsUnicode(self):
+ from Zope.App.Traversing import locationAsUnicode as lau
+ loc = u'xx/yy/zz'
+ self.assertEqual(lau((u'xx',u'yy',u'zz')), loc)
+ self.assertEqual(lau((u'', u'xx',u'yy',u'zz')), '/'+loc)
+ self.assertEqual(lau(('xx','yy','zz')), loc)
+ self.assertRaises(ValueError, lau, ())
+ self.assertEqual(lau(('xx',)), u'xx')
+ self.assertRaises(ValueError, lau, 23)
+ self.assertRaises(UnicodeError, lau, ('', u'123', '£23'))
+ self.assertRaises(UnicodeError, lau, '£23')
+ self.assertEqual(lau(u'xx/yy/zz'), loc)
+ self.assertEqual(lau(u'/xx/yy/zz'), u'/'+loc)
+ self.assertEqual(lau('xx/yy/zz'), loc)
+ self.assertRaises(ValueError, lau, '')
+ self.assertEqual(lau('/'), u'/')
+ self.assertEqual(lau('xx'), u'xx')
+ self.assertRaises(ValueError, lau, '//')
+ self.assertRaises(AssertionError, lau, '/foo//bar')
+ # having a trailing slash on a location is undefined.
+ # we might want to give it a particular meaning for zope3 later
+ # for now, it is an invalid location identifier
+ self.assertRaises(ValueError, lau, '/foo/bar/')
+ self.assertRaises(ValueError, lau, 'foo/bar/')
+ self.assertRaises(ValueError, lau, ('','foo','bar',''))
+ self.assertRaises(ValueError, lau, ('foo','bar',''))
+
def test_suite():
return TestSuite((
makeSuite(Test),